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    
015    package org.apache.tapestry.pageload;
016    
017    import java.util.Iterator;
018    
019    import org.apache.hivemind.ApplicationRuntimeException;
020    import org.apache.tapestry.IBinding;
021    import org.apache.tapestry.IComponent;
022    import org.apache.tapestry.binding.BindingConstants;
023    import org.apache.tapestry.binding.BindingSource;
024    import org.apache.tapestry.spec.IComponentSpecification;
025    import 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     */
034    public 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    }