    001    // Copyright 2007, 2008, 2010 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // 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
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services;
    016
    017    import java.util.Collections;
    018    import java.util.List;
    019    import java.util.Map;
    020
    021    import org.apache.tapestry5.Translator;
    022    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    023    import org.apache.tapestry5.ioc.util.AvailableValues;
    024    import org.apache.tapestry5.ioc.util.StrategyRegistry;
    025    import org.apache.tapestry5.ioc.util.UnknownValueException;
    026    import org.apache.tapestry5.services.InvalidationListener;
    027    import org.apache.tapestry5.services.TranslatorSource;
    028
    029    @SuppressWarnings("unchecked")
    030    public class TranslatorSourceImpl implements TranslatorSource, InvalidationListener
    031    {
    032        private final Map<String, Translator> nameToTranslator = CollectionFactory.newCaseInsensitiveMap();
    033
    034        private final StrategyRegistry<Translator> registry;
    035
    036        private static final Map<String, Translator> EMPTY = Collections.emptyMap();
    037
    038        public TranslatorSourceImpl(Map<Class, Translator> configuration)
    039        {
    040            this(configuration, EMPTY);
    041        }
    042
    043        public TranslatorSourceImpl(Map<Class, Translator> configuration, Map<String, Translator> alternates)
    044        {
    045            for (Map.Entry<Class, Translator> me : configuration.entrySet())
    046            {
    047                Class type = me.getKey();
    048                Translator translator = me.getValue();
    049
    050                if (!type.equals(translator.getType()))
    051                    throw new RuntimeException(
    052                            String
    053                                    .format(
    054                                            "Contributed translator for type %s reports its type as %s. Please change the contribution so that the key matches that translator type.",
    055                                            type.getName(), translator.getType().getName()));
    056
    057                String name = translator.getName();
    058
    059                if (nameToTranslator.containsKey(name))
    060                    throw new RuntimeException(
    061                            String
    062                                    .format(
    063                                            "Two different Translators contributed to the TranslatorSource service use the same translator name: '%s'.  Translator names must be unique.",
    064                                            name));
    065
    066                nameToTranslator.put(name, translator);
    067            }
    068
    069            for (String name : alternates.keySet())
    070            {
    071                if (nameToTranslator.containsKey(name))
    072                    throw new RuntimeException(
    073                            String
    074                                    .format(
    075                                            "Translator '%s' contributed to the TranslatorAlternatesSource service has the same name as a standard Translator contributed to the TranslatorSource service.",
    076                                            name));
    077
    078                nameToTranslator.put(name, alternates.get(name));
    079            }
    080
    081            registry = StrategyRegistry.newInstance(Translator.class, configuration, true);
    082        }
    083
    084        public Translator get(String name)
    085        {
    086            Translator result = nameToTranslator.get(name);
    087
    088            if (result == null)
    089                throw new UnknownValueException(String.format("Unknown translator type '%s'.", name), new AvailableValues(
    090                        "Configured translators", nameToTranslator));
    091
    092            return result;
    093        }
    094
    095        public Translator getByType(Class valueType)
    096        {
    097            Translator result = registry.get(valueType);
    098
    099            if (result == null)
    100            {
    101                List<String> names = CollectionFactory.newList();
    102
    103                for (Class type : registry.getTypes())
    104                {
    105                    names.add(type.getName());
    106                }
    107
    108                throw new IllegalArgumentException(ServicesMessages.noTranslatorForType(valueType, names));
    109            }
    110
    111            return result;
    112        }
    113
    114        public Translator findByType(Class valueType)
    115        {
    116            return registry.get(valueType);
    117        }
    118
    119        public void objectWasInvalidated()
    120        {
    121            registry.clearCache();
    122        }
    123    }