    001    // Copyright 2007, 2008, 2009, 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 org.apache.tapestry5.Binding;
    018    import org.apache.tapestry5.BindingConstants;
    019    import org.apache.tapestry5.ComponentResources;
    020    import org.apache.tapestry5.FieldTranslator;
    021    import org.apache.tapestry5.FieldValidator;
    022    import org.apache.tapestry5.MarkupWriter;
    023    import org.apache.tapestry5.ValidationException;
    024    import org.apache.tapestry5.ValueEncoder;
    025    import org.apache.tapestry5.internal.TapestryInternalUtils;
    026    import org.apache.tapestry5.internal.bindings.InvariantBinding;
    027    import org.apache.tapestry5.ioc.Messages;
    028    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    029    import org.apache.tapestry5.ioc.services.PropertyAccess;
    030    import org.apache.tapestry5.runtime.Component;
    031    import org.apache.tapestry5.services.BindingSource;
    032    import org.apache.tapestry5.services.ComponentDefaultProvider;
    033    import org.apache.tapestry5.services.FieldTranslatorSource;
    034    import org.apache.tapestry5.services.FieldValidatorDefaultSource;
    035    import org.apache.tapestry5.services.ValueEncoderSource;
    036
    037    public class ComponentDefaultProviderImpl implements ComponentDefaultProvider
    038    {
    039        private final PropertyAccess propertyAccess;
    040
    041        private final BindingSource bindingSource;
    042
    043        private final ValueEncoderSource valueEncoderSource;
    044
    045        private final FieldTranslatorSource fieldTranslatorSource;
    046
    047        private final FieldValidatorDefaultSource fieldValidatorDefaultSource;
    048
    049        static final FieldValidator NOOP_VALIDATOR = new FieldValidator()
    050        {
    051            public void validate(Object value) throws ValidationException
    052            {
    053                // Do nothing
    054            }
    055
    056            public void render(MarkupWriter writer)
    057            {
    058            }
    059
    060            public boolean isRequired()
    061            {
    062                return false;
    063            }
    064        };
    065
    066        public ComponentDefaultProviderImpl(PropertyAccess propertyAccess, BindingSource bindingSource,
    067                                            ValueEncoderSource valueEncoderSource,
    068                                            FieldTranslatorSource fieldTranslatorSource,
    069                                            FieldValidatorDefaultSource fieldValidatorDefaultSource)
    070        {
    071            this.propertyAccess = propertyAccess;
    072            this.bindingSource = bindingSource;
    073            this.valueEncoderSource = valueEncoderSource;
    074            this.fieldTranslatorSource = fieldTranslatorSource;
    075            this.fieldValidatorDefaultSource = fieldValidatorDefaultSource;
    076        }
    077
    078        public String defaultLabel(ComponentResources resources)
    079        {
    080            assert resources != null;
    081            String componentId = resources.getId();
    082            String key = componentId + "-label";
    083
    084            Messages containerMessages = resources.getContainerResources().getMessages();
    085
    086            if (containerMessages.contains(key)) return containerMessages.get(key);
    087
    088            return TapestryInternalUtils.toUserPresentable(componentId);
    089        }
    090
    091        public Binding defaultBinding(String parameterName, ComponentResources resources)
    092        {
    093            assert InternalUtils.isNonBlank(parameterName);
    094            assert resources != null;
    095            String componentId = resources.getId();
    096
    097            Component container = resources.getContainer();
    098
    099            // Only provide a default binding if the container actually contains the property.
    100            // This sets up an error condition for when the parameter is not bound, and
    101            // the binding can't be deduced.
    102
    103            if (propertyAccess.getAdapter(container).getPropertyAdapter(componentId) == null)
    104                return null;
    105
    106            ComponentResources containerResources = resources.getContainerResources();
    107
    108            return bindingSource.newBinding(
    109                    "default " + parameterName,
    110                    containerResources,
    111                    BindingConstants.PROP,
    112                    componentId);
    113        }
    114
    115        @SuppressWarnings({ "unchecked" })
    116        public ValueEncoder defaultValueEncoder(String parameterName, ComponentResources resources)
    117        {
    118            assert InternalUtils.isNonBlank(parameterName);
    119            assert resources != null;
    120            Class parameterType = resources.getBoundType(parameterName);
    121
    122            if (parameterType == null) return null;
    123
    124            return valueEncoderSource.getValueEncoder(parameterType);
    125        }
    126
    127        public FieldTranslator defaultTranslator(String parameterName, ComponentResources resources)
    128        {
    129            return fieldTranslatorSource.createDefaultTranslator(resources, parameterName);
    130        }
    131
    132        public Binding defaultTranslatorBinding(final String parameterName, final ComponentResources resources)
    133        {
    134            String description = String.format("default translator, parameter %s of %s",
    135                                               parameterName, resources.getCompleteId());
    136
    137            return new InvariantBinding(resources.getLocation(), FieldTranslator.class, description)
    138            {
    139                public Object get()
    140                {
    141                    return defaultTranslator(parameterName, resources);
    142                }
    143            };
    144        }
    145
    146        public FieldValidator defaultValidator(String parameterName, ComponentResources resources)
    147        {
    148            FieldValidator result = fieldValidatorDefaultSource.createDefaultValidator(resources, parameterName);
    149
    150            return result == null ? NOOP_VALIDATOR : result;
    151        }
    152
    153        public Binding defaultValidatorBinding(final String parameterName, final ComponentResources resources)
    154        {
    155            String description = String.format("default validator, parameter %s of %s", parameterName,
    156                                               resources.getCompleteId());
    157
    158            return new InvariantBinding(resources.getLocation(), FieldValidator.class, description)
    159            {
    160                public Object get()
    161                {
    162                    return defaultValidator(parameterName, resources);
    163                }
    164            };
    165        }
    166    }