    001    // Copyright 2006, 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.corelib.internal;
    016
    017    import java.util.List;
    018
    019    import org.apache.tapestry5.ComponentAction;
    020    import org.apache.tapestry5.ComponentResources;
    021    import org.apache.tapestry5.Field;
    022    import org.apache.tapestry5.ioc.Locatable;
    023    import org.apache.tapestry5.ioc.Location;
    024    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    025    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    026    import org.apache.tapestry5.ioc.util.IdAllocator;
    027    import org.apache.tapestry5.services.ClientBehaviorSupport;
    028
    029    /**
    030     * Provides support to components enclosed by a form when the form is rendering (allowing the components to registry
    031     * form submit callback commands), and also during form submission time.
    032     * <p/>
    033     * TODO: Most methods should only be invokable depending on whether the form is rendering or processing a submission.
    034     */
    035    public class FormSupportImpl implements InternalFormSupport, Locatable
    036    {
    037        private final ComponentResources resources;
    038
    039        private final ClientBehaviorSupport clientBehaviorSupport;
    040
    041        private final boolean clientValidationEnabled;
    042
    043        private final IdAllocator idAllocator;
    044
    045        private final String clientId;
    046
    047        private final ComponentActionSink actionSink;
    048
    049        private final String formValidationId;
    050
    051        private List<Runnable> commands;
    052
    053        private String encodingType;
    054
    055        /**
    056         * Constructor used when processing a form submission.
    057         */
    058        public FormSupportImpl(ComponentResources resources, String formValidationId)
    059        {
    060            this(resources, null, null, null, false, null, formValidationId);
    061        }
    062
    063        /**
    064         * Full constructor (specifically constructor for render time).
    065         */
    066        public FormSupportImpl(ComponentResources resources, String clientId, ComponentActionSink actionSink,
    067                ClientBehaviorSupport clientBehaviorSupport, boolean clientValidationEnabled, IdAllocator idAllocator,
    068                String formValidationId)
    069        {
    070            this.resources = resources;
    071            this.clientId = clientId;
    072            this.actionSink = actionSink;
    073            this.clientBehaviorSupport = clientBehaviorSupport;
    074            this.clientValidationEnabled = clientValidationEnabled;
    075            this.idAllocator = idAllocator;
    076            this.formValidationId = formValidationId;
    077        }
    078
    079        public Location getLocation()
    080        {
    081            return resources.getLocation();
    082        }
    083
    084        public String getFormComponentId()
    085        {
    086            return resources.getCompleteId();
    087        }
    088
    089        public String allocateControlName(String id)
    090        {
    091            return idAllocator.allocateId(id);
    092        }
    093
    094        public <T> void store(T component, ComponentAction<T> action)
    095        {
    096            actionSink.store(component, action);
    097        }
    098
    099        public <T> void storeAndExecute(T component, ComponentAction<T> action)
    100        {
    101            actionSink.store(component, action);
    102
    103            action.execute(component);
    104        }
    105
    106        public void defer(Runnable command)
    107        {
    108            assert command != null;
    109
    110            if (commands == null)
    111                commands = CollectionFactory.newList();
    112
    113            commands.add(command);
    114        }
    115
    116        public void executeDeferred()
    117        {
    118            if (commands == null)
    119                return;
    120
    121            for (Runnable r : commands)
    122                r.run();
    123
    124            commands.clear();
    125        }
    126
    127        public String getClientId()
    128        {
    129            return clientId;
    130        }
    131
    132        public String getEncodingType()
    133        {
    134            return encodingType;
    135        }
    136
    137        public void setEncodingType(String encodingType)
    138        {
    139            assert InternalUtils.isNonBlank(encodingType);
    140
    141            if (this.encodingType != null && !this.encodingType.equals(encodingType))
    142                throw new IllegalStateException(InternalMessages.conflictingEncodingType(this.encodingType, encodingType));
    143
    144            this.encodingType = encodingType;
    145        }
    146
    147        public void addValidation(Field field, String validationName, String message, Object constraint)
    148        {
    149            if (clientValidationEnabled)
    150                clientBehaviorSupport.addValidation(field, validationName, message, constraint);
    151        }
    152
    153        public boolean isClientValidationEnabled()
    154        {
    155            return clientValidationEnabled;
    156        }
    157
    158        public String getFormValidationId()
    159        {
    160            return formValidationId;
    161        }
    162    }