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