001/*
002 * Copyright 2011 Atteo.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014package org.atteo.evo.filtering;
015
016import java.util.Collection;
017import java.util.List;
018import java.util.Map.Entry;
019
020import com.google.common.collect.ArrayListMultimap;
021import com.google.common.collect.Lists;
022import com.google.common.collect.Multimap;
023
024/**
025 * Resolves properties by trying a number of underlying {@link PropertyResolver property resolvers}.
026 * <p>
027 * Underlying property resolver can be an instance of {@link PrefixedPropertyResolver}.
028 * In this case it will be executed only if its prefix matches property name.
029 * If at least one prefixed resolver matches given prefix then only prefixed resolvers
030 * matching this prefix will be executed.
031 * </p>
032 */
033public class CompoundPropertyResolver implements PropertyResolver {
034    private List<PropertyResolver> resolvers = Lists.newArrayList();
035    private Multimap<String, PrefixedPropertyResolver> prefixedResolvers = ArrayListMultimap.create();
036
037    public CompoundPropertyResolver(PropertyResolver... resolvers) {
038        for (PropertyResolver resolver : resolvers) {
039            addPropertyResolver(resolver);
040        }
041    }
042
043    public final void addPropertyResolver(PropertyResolver resolver) {
044        if (resolver instanceof PrefixedPropertyResolver) {
045            PrefixedPropertyResolver prefixedResolver = (PrefixedPropertyResolver) resolver;
046            String prefix = prefixedResolver.getPrefix();
047            if (prefix != null) {
048                prefixedResolvers.put(prefixedResolver.getPrefix(), prefixedResolver);
049                return;
050            }
051        }
052        resolvers.add(resolver);
053    }
054
055    @Override
056    public String resolveProperty(String name, PropertyResolver recurse) throws PropertyNotFoundException {
057        for (Entry<String, Collection<PrefixedPropertyResolver>> entry : prefixedResolvers.asMap().entrySet()) {
058            if (name.startsWith(entry.getKey())) {
059                for (PrefixedPropertyResolver resolver : entry.getValue()) {
060                    String value = resolver.resolveProperty(name, recurse);
061                    if (value != null) {
062                        return value;
063                    }
064                }
065                throw new PropertyNotFoundException(name);
066            }
067        }
068
069        for (PropertyResolver resolver : resolvers) {
070            String value = resolver.resolveProperty(name, recurse);
071            if (value != null) {
072                return value;
073            }
074        }
075        return null;
076    }
077}