1 package pl.caltha.forms.internal;
2
3 import java.util.HashMap;
4
5 import org.objectledge.parameters.Parameters;
6
7 import pl.caltha.forms.ConstructionException;
8 import pl.caltha.forms.Form;
9 import pl.caltha.forms.FormsService;
10 import pl.caltha.forms.internal.model.Bind;
11 import pl.caltha.forms.internal.model.DefaultInstance;
12 import pl.caltha.forms.internal.model.InstanceImpl;
13 import pl.caltha.forms.internal.model.SubmitInfo;
14 import pl.caltha.forms.internal.ui.UI;
15 import pl.caltha.forms.internal.ui.UIConstants;
16 import pl.caltha.services.xml.XMLService;
17
18 /***
19 * Represents Form definition.
20 *
21 * @author <a href="mailto:zwierzem@ngo.pl">Damian Gajda</a>
22 * @version $Id: FormImpl.java,v 1.3 2005/02/08 20:33:27 rafal Exp $
23 */
24 public class FormImpl implements Form
25 {
26 /*** FormsService. */
27 private FormsService formToolService;
28
29 /*** XMLService is used to get validators. */
30 private XMLService xmlService;
31
32 /*** I18nService is used to localise strings. */
33
34
35 /*** Keeps ID for this form definition.. */
36 private String id;
37
38 /*** Keeps URI for form definition.. */
39 private String definitionURI;
40
41 /*** Keeps model/bind elements. */
42 private HashMap bindElements = new HashMap();
43
44 /*** Keeps Form's SubmitInfo. */
45 protected SubmitInfo submitInfo;
46
47 /*** Keeps URI for UI definition.. */
48 protected String uiURI;
49 /*** Keeps UI object. */
50 private UI ui;
51
52 /*** Keeps Instance schema URI. */
53 protected String instanceSchemaURI;
54 /*** Keeps Instance URI. */
55 protected String defaultInstanceURI;
56 /*** Keeps an object representing default Instance. */
57 private DefaultInstance defaultInstance;
58
59
60
61 /*** Creates new Form */
62 public FormImpl(FormsService formToolService, XMLService xmlService,
63 String definitionURI, String id)
64 {
65 this.definitionURI = definitionURI;
66 this.id = id;
67 this.formToolService = formToolService;
68 this.xmlService = xmlService;
69 }
70
71
72
73
74 /*** Processes a user request merging it's data with an Instance object.
75 * <p>Processing consists of following steps:</p>
76 * <ol>
77 * <li><b>Value extraction (from the request) and application on an Instance.</b>
78 * <p>This step is first because form-tool is a server-side tool.
79 * All values must be applied before Instance is validated, or
80 * any actions, including setting values dynamically are executed
81 * (If for instance setValue action would be executed before
82 * applying values, the result of this action could be lost).
83 * </p>
84 * <p>This action triggers bind property cache clean up
85 * ({@link pl.caltha.forms.internal.model.InstanceImpl#preprocessInit()})
86 * </p>
87 * <p>This action also triggers submit requested flag clean up
88 * ({@link pl.caltha.forms.internal.model.InstanceImpl#preprocessInit()})
89 * </p>
90 * <p>This action also triggers error collector clean up
91 * ({@link pl.caltha.forms.internal.model.InstanceImpl#preprocessInit()})
92 * </p>
93 * </li>
94 * <li><b>Event extraction (from request) and dispatching.</b>
95 * <p>Event dispatching triggers actions connected to controls.
96 * These actions may also trigger another events and so on.</p>
97 * <p>TODO: Implement event - action loop protection.</p>
98 *
99 * <p>Right now only two kinds of events are extracted:</p>
100 * <ol>
101 * <li><code>activate</code> - control activation,
102 * in this case button control activation.</li>
103 * <li><code>submit</code> - submit button control activation.</li>
104 * </ol>
105 * </li>
106 * <li><b>Instance validation</b>
107 * <p>In client-side XForms implementation this step should be
108 * triggered by a changed value. In server-side processing value
109 * comparison would have to be implemented to check if any of them
110 * was changed. It is not very wise to do value comparison because
111 * there will be cases in which it will be faster to do validation
112 * than to compare all values in the Instance. That's why validation
113 * is always executed.
114 * </p>
115 * </li>
116 * </ol>
117 */
118 public void process(pl.caltha.forms.Instance inst, Parameters parameters)
119 throws Exception
120 {
121 InstanceImpl instance = (InstanceImpl)inst;
122
123
124
125
126
127
128
129
130
131 instance.preprocessInit();
132
133
134
135
136
137
138
139 String instanceId = parameters.get(UIConstants.INSTANCE_ID_NAME,null);
140 if(instanceId != null && instanceId.equals(instance.getId()))
141 {
142 ui.setValues(instance, parameters);
143 ui.dispatchEvents(instance, parameters);
144 }
145
146
147
148 instance.validate( xmlService.getDOM4JValidator() );
149
150
151
152
153
154 boolean hasRequired = ui.hasRequired(instance);
155 instance.setHasRequired(hasRequired);
156 }
157
158 /*** Returns ID for this form's definition file. This is a form definition URI
159 * ({@link Form#getDefinitionURI}) changed to be compatible with XHTML IDs. */
160 public String getId()
161 {
162 return id;
163 }
164
165 public String getDefinitionURI()
166 {
167 return definitionURI;
168 }
169
170 public String getUIDefinitionURI()
171 {
172 return uiURI;
173 }
174
175 public String getDefaultInstanceURI()
176 {
177 return defaultInstanceURI;
178 }
179
180 public String getInstanceSchemaURI()
181 {
182 return instanceSchemaURI;
183 }
184
185
186
187
188 /*** Returns a default instance object. */
189 public DefaultInstance getDefaultInstance()
190 {
191 return defaultInstance;
192 }
193
194 /*** Creates a new instance object. */
195 InstanceImpl createInstance(String instanceId)
196 {
197 return defaultInstance.createInstance(instanceId);
198 }
199
200 /*** Creates a new instance object from a saved instance data. */
201 InstanceImpl createInstance(String instanceId, byte[] savedState)
202 throws Exception
203 {
204 return defaultInstance.createInstance(instanceId, savedState);
205 }
206
207
208 public Bind getBind(String id)
209 throws ConstructionException
210 {
211 if(bindElements.containsKey(id))
212 {
213 return (Bind)(bindElements.get(id));
214 }
215 throw new ConstructionException("Cannot find bind element with id='"+id+"'");
216 }
217
218 public SubmitInfo getSubmitInfo()
219 {
220 return submitInfo;
221 }
222
223 public UI getUI()
224 {
225 return ui;
226 }
227
228 public FormsService getFormToolService()
229 {
230 return formToolService;
231 }
232
233
234
235
236
237
238
239
240 void setDefaultInstance(DefaultInstance defaultInstance)
241 {
242 this.defaultInstance = defaultInstance;
243 }
244
245 void addBindElement(Bind bind)
246 throws ConstructionException
247 {
248
249 String id = bind.getId();
250 if(id == null || id.equals(""))
251 {
252 throw new ConstructionException("Cannot add Bind element with no id");
253 }
254
255 if(!bindElements.containsKey(id))
256 {
257 bindElements.put(id, bind);
258 }
259
260 else
261 {
262 throw new ConstructionException("Duplicate bind element id='"+id+"'");
263 }
264 }
265
266 void init(UI ui)
267 throws ConstructionException
268 {
269 this.ui = ui;
270 }
271 }
272