001    // Copyright 2008, 2010, 2011 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.Locale;
018    
019    import org.apache.tapestry5.ComponentResources;
020    import org.apache.tapestry5.Field;
021    import org.apache.tapestry5.FieldTranslator;
022    import org.apache.tapestry5.Translator;
023    import org.apache.tapestry5.beaneditor.Translate;
024    import org.apache.tapestry5.ioc.AnnotationProvider;
025    import org.apache.tapestry5.ioc.MessageFormatter;
026    import org.apache.tapestry5.ioc.Messages;
027    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
028    import org.apache.tapestry5.services.FieldTranslatorSource;
029    import org.apache.tapestry5.services.FormSupport;
030    import org.apache.tapestry5.services.TranslatorSource;
031    
032    @SuppressWarnings("all")
033    public class FieldTranslatorSourceImpl implements FieldTranslatorSource
034    {
035        private final TranslatorSource translatorSource;
036    
037        private final Messages globalMessages;
038    
039        private final FormSupport formSupport;
040    
041        public FieldTranslatorSourceImpl(TranslatorSource translatorSource, Messages globalMessages,
042                FormSupport formSupport)
043        {
044            this.translatorSource = translatorSource;
045            this.globalMessages = globalMessages;
046            this.formSupport = formSupport;
047        }
048    
049        public FieldTranslator createDefaultTranslator(ComponentResources resources, String parameterName)
050        {
051            assert resources != null;
052            assert InternalUtils.isNonBlank(parameterName);
053            Field field = (Field) resources.getComponent();
054            Class propertyType = resources.getBoundType(parameterName);
055    
056            return createDefaultTranslator(field, resources.getId(), resources.getContainerMessages(),
057                    null, propertyType, resources.getAnnotationProvider(parameterName));
058        }
059    
060        public FieldTranslator createDefaultTranslator(Field field, String overrideId, Messages overrideMessages,
061                Locale locale, Class propertyType, AnnotationProvider propertyAnnotations)
062        {
063            assert field != null;
064            assert overrideMessages != null;
065            assert InternalUtils.isNonBlank(overrideId);
066            if (propertyType == null)
067                return null;
068    
069            Translator translator = findTranslator(propertyType, propertyAnnotations);
070    
071            if (translator == null)
072                return null;
073    
074            return createTranslator(field, overrideId, overrideMessages, locale, translator);
075        }
076    
077        Translator findTranslator(Class propertyType, AnnotationProvider propertyAnnotations)
078        {
079            Translate annotation = propertyAnnotations.getAnnotation(Translate.class);
080    
081            if (annotation != null)
082                return translatorSource.get(annotation.value());
083    
084            if (propertyType == null)
085                return null;
086    
087            return translatorSource.findByType(propertyType);
088        }
089    
090        public FieldTranslator createTranslator(Field field, String overrideId, Messages overrideMessages, Locale locale,
091                Translator translator)
092        {
093            MessageFormatter formatter = findFormatter(overrideId, overrideMessages, translator);
094    
095            return new FieldTranslatorImpl(field, translator, formatter, formSupport);
096        }
097    
098        public FieldTranslator createTranslator(ComponentResources resources, String translatorName)
099        {
100            assert resources != null;
101            assert InternalUtils.isNonBlank(translatorName);
102            Field field = (Field) resources.getComponent();
103    
104            Translator translator = translatorSource.get(translatorName);
105    
106            return createTranslator(field, resources.getId(), resources.getContainerMessages(), null, translator);
107        }
108    
109        private MessageFormatter findFormatter(String overrideId, Messages overrideMessages, Translator translator)
110        {
111            // TAP5-228: Try to distinguish message overrides by form id and overrideId (i.e., property name) first.
112    
113            String translatorName = translator.getName();
114    
115            String overrideKey = formSupport.getFormValidationId() + "-" + overrideId + "-" + translatorName + "-message";
116    
117            if (overrideMessages.contains(overrideKey))
118                return overrideMessages.getFormatter(overrideKey);
119    
120            // Ok, look for a simpler name that omits the formId prefix.
121    
122            overrideKey = overrideId + "-" + translatorName + "-message";
123    
124            if (overrideMessages.contains(overrideKey))
125                return overrideMessages.getFormatter(overrideKey);
126    
127            // Otherwise, use the built-in validation message appropriate to this validator.
128            String messageKey = translator.getMessageKey();
129    
130            // If no key has been specified, use translator name to create a key
131            if(messageKey == null)
132            {
133                messageKey = translatorName + "-message";
134            }
135    
136            return globalMessages.getFormatter(messageKey);
137        }
138    }