    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
    015package org.apache.tapestry5.internal.services;
    016
    017import org.apache.tapestry5.Binding;
    018import org.apache.tapestry5.BindingConstants;
    019import org.apache.tapestry5.ComponentResources;
    020import org.apache.tapestry5.FieldTranslator;
    021import org.apache.tapestry5.FieldValidator;
    022import org.apache.tapestry5.MarkupWriter;
    023import org.apache.tapestry5.ValidationException;
    024import org.apache.tapestry5.ValueEncoder;
    025import org.apache.tapestry5.commons.Messages;
    026import org.apache.tapestry5.commons.services.PropertyAccess;
    027import org.apache.tapestry5.internal.TapestryInternalUtils;
    028import org.apache.tapestry5.internal.bindings.InvariantBinding;
    029import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    030import org.apache.tapestry5.runtime.Component;
    031import org.apache.tapestry5.services.BindingSource;
    032import org.apache.tapestry5.services.ComponentDefaultProvider;
    033import org.apache.tapestry5.services.FieldTranslatorSource;
    034import org.apache.tapestry5.services.FieldValidatorDefaultSource;
    035import org.apache.tapestry5.services.ValueEncoderSource;
    036
    037public 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}