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 }