001// Copyright 2004, 2005 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.tapestry.pageload;
016
017import java.util.Iterator;
018
019import org.apache.hivemind.ApplicationRuntimeException;
020import org.apache.tapestry.IBinding;
021import org.apache.tapestry.IComponent;
022import org.apache.tapestry.binding.BindingConstants;
023import org.apache.tapestry.binding.BindingSource;
024import org.apache.tapestry.spec.IComponentSpecification;
025import org.apache.tapestry.spec.IParameterSpecification;
026
027/**
028 * For all parameters in the examined component that have default values, but are not bound,
029 * automatically add an ExpressionBinding with the default value.
030 * 
031 * @author mindbridge
032 * @since 3.0
033 */
034public class EstablishDefaultParameterValuesVisitor implements IComponentVisitor
035{
036    /** @since 4.0 */
037    private BindingSource _bindingSource;
038
039    /**
040     * @see org.apache.tapestry.pageload.IComponentVisitor#visitComponent(org.apache.tapestry.IComponent)
041     */
042    public void visitComponent(IComponent component)
043    {
044        IComponentSpecification spec = component.getSpecification();
045
046        Iterator i = spec.getParameterNames().iterator();
047
048        while (i.hasNext())
049        {
050            String name = (String) i.next();
051            IParameterSpecification parameterSpec = spec.getParameter(name);
052
053            // Skip aliases
054
055            if (!name.equals(parameterSpec.getParameterName()))
056                continue;
057
058            String defaultValue = parameterSpec.getDefaultValue();
059            if (defaultValue == null)
060                continue;
061
062            // the parameter has a default value, so it must not be required
063            if (parameterSpec.isRequired())
064                throw new ApplicationRuntimeException(PageloadMessages
065                        .parameterMustHaveNoDefaultValue(component, name), component, parameterSpec
066                        .getLocation(), null);
067
068            // if there is no binding for this parameter, bind it to the default value.
069            // In 3.0, default-value was always an OGNL expression, but now its a binding reference.
070
071            if (component.getBinding(name) == null)
072            {
073                String description = PageloadMessages.defaultParameterName(name);
074
075                IBinding binding = _bindingSource.createBinding(
076                        component,
077                        description,
078                        defaultValue,
079                        BindingConstants.OGNL_PREFIX,
080                        parameterSpec.getLocation());
081
082                component.setBinding(name, binding);
083            }
084        }
085    }
086
087    /** @since 4.0 */
088
089    public void setBindingSource(BindingSource bindingSource)
090    {
091        _bindingSource = bindingSource;
092    }
093}