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 }