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
015package org.apache.tapestry5.internal.services;
016
017import java.util.Locale;
018
019import org.apache.tapestry5.ComponentResources;
020import org.apache.tapestry5.Field;
021import org.apache.tapestry5.FieldTranslator;
022import org.apache.tapestry5.Translator;
023import org.apache.tapestry5.beaneditor.Translate;
024import org.apache.tapestry5.commons.AnnotationProvider;
025import org.apache.tapestry5.commons.MessageFormatter;
026import org.apache.tapestry5.commons.Messages;
027import org.apache.tapestry5.ioc.internal.util.InternalUtils;
028import org.apache.tapestry5.services.FieldTranslatorSource;
029import org.apache.tapestry5.services.FormSupport;
030import org.apache.tapestry5.services.TranslatorSource;
031
032@SuppressWarnings("all")
033public 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}