1 16 package org.apache.cocoon.forms.formmodel; 17 18 import java.util.HashSet ; 19 import java.util.Locale ; 20 import java.util.Set ; 21 import java.util.StringTokenizer ; 22 23 import org.apache.cocoon.forms.FormContext; 24 import org.apache.cocoon.forms.event.FormHandler; 25 import org.apache.cocoon.forms.event.ProcessingPhase; 26 import org.apache.cocoon.forms.event.ProcessingPhaseEvent; 27 import org.apache.cocoon.forms.event.ProcessingPhaseListener; 28 import org.apache.cocoon.forms.event.WidgetEvent; 29 import org.apache.cocoon.forms.event.WidgetEventMulticaster; 30 import org.apache.cocoon.forms.validation.ValidationError; 31 import org.apache.cocoon.forms.validation.ValidationErrorAware; 32 import org.apache.commons.collections.list.CursorableLinkedList; 33 import org.apache.commons.lang.BooleanUtils; 34 35 43 public class Form extends AbstractContainerWidget 44 implements ValidationErrorAware { 45 46 private static final String FORM_EL = "form"; 47 48 private final FormDefinition definition; 49 50 56 private Boolean endProcessing; 57 private Locale locale = Locale.getDefault(); 58 private FormHandler formHandler; 59 private Widget submitWidget; 60 private ProcessingPhase phase = ProcessingPhase.LOAD_MODEL; 61 private boolean isValid = false; 62 private ProcessingPhaseListener listener; 63 64 private boolean bufferEvents = false; 67 private CursorableLinkedList events; 68 69 private Set updatedWidgets; 71 private Set childUpdatedWidgets; 73 74 75 public Form(FormDefinition definition) { 76 super(definition); 77 this.definition = definition; 78 } 79 80 86 public void initialize() { 87 try { 88 this.bufferEvents = true; 90 super.initialize(); 91 fireEvents(); 94 } finally { 95 this.bufferEvents = false; 97 } 98 } 99 100 public WidgetDefinition getDefinition() { 101 return this.definition; 102 } 103 104 110 public void addWidgetEvent(WidgetEvent event) { 111 112 if (this.bufferEvents) { 113 if (this.events == null) { 114 this.events = new CursorableLinkedList(); 115 } 116 117 this.events.add(event); 119 } else { 120 event.getSourceWidget().broadcastEvent(event); 122 } 123 } 124 125 131 public boolean addWidgetUpdate(Widget widget) { 132 if (this.updatedWidgets != null) { 133 if (this.updatedWidgets.add(widget.getRequestParameterName())) { 134 Widget parent = widget.getParent(); 136 addParents: while (parent != this && parent != null) { 137 if (this.childUpdatedWidgets.add(parent.getRequestParameterName())) { 138 parent = parent.getParent(); 139 } else { 140 break addParents; 142 } 143 } 144 return true; 145 } 146 } 147 return false; 148 } 149 150 public Set getUpdatedWidgetIds() { 151 return this.updatedWidgets; 152 } 153 154 public Set getChildUpdatedWidgetIds() { 155 return this.childUpdatedWidgets; 156 } 157 158 162 private void fireEvents() { 163 if (this.events != null) { 164 CursorableLinkedList.Cursor cursor = this.events.cursor(); 165 while(cursor.hasNext()) { 166 WidgetEvent event = (WidgetEvent)cursor.next(); 167 event.getSourceWidget().broadcastEvent(event); 168 if (formHandler != null) 169 formHandler.handleEvent(event); 170 } 171 cursor.close(); 172 173 this.events.clear(); 174 } 175 } 176 177 182 public Locale getLocale() { 183 return this.locale; 184 } 185 186 192 public Widget getSubmitWidget() { 193 return this.submitWidget; 194 } 195 196 201 public void setSubmitWidget(Widget widget) { 202 if (this.submitWidget != null && this.submitWidget != widget) { 203 throw new IllegalStateException ("Submit widget already set to " + this.submitWidget + 204 ". Cannot set also " + widget); 205 } 206 207 if (widget.getCombinedState() != WidgetState.ACTIVE) { 209 throw new IllegalStateException ("Widget " + widget + " that submitted the form is not active."); 210 } 211 212 if (!(widget instanceof Action)) { 217 endProcessing(true); 218 } 219 this.submitWidget = widget; 220 } 221 222 public boolean hasFormHandler() { 223 return (this.formHandler != null); 224 } 225 226 public void setFormHandler(FormHandler formHandler) { 227 this.formHandler = formHandler; 228 } 229 230 251 public void addProcessingPhaseListener(ProcessingPhaseListener listener) { 252 this.listener = WidgetEventMulticaster.add(this.listener, listener); 253 } 254 255 public void removeProcessingPhaseListener(ProcessingPhaseListener listener) { 256 this.listener = WidgetEventMulticaster.remove(this.listener, listener); 257 } 258 259 278 public synchronized boolean process(FormContext formContext) { 279 if (formContext.getRequest().getParameter("cocoon-ajax") != null) { 281 this.updatedWidgets = new HashSet (); 282 this.childUpdatedWidgets = new HashSet (); 283 } 284 285 fireEvents(); 287 288 this.submitWidget = null; 290 this.locale = formContext.getLocale(); 291 this.endProcessing = null; 292 this.isValid = false; 293 294 if (this.listener != null) { 296 this.listener.phaseEnded(new ProcessingPhaseEvent(this, this.phase)); 297 } 298 299 this.phase = ProcessingPhase.READ_FROM_REQUEST; 300 this.submitWidget = null; 302 String submitId = formContext.getRequest().getParameter("forms_submit_id"); 303 if (submitId != null && submitId.length() > 0) { 304 if(this.getId() != null && !"".equals(this.getId())) { 307 submitId = submitId.substring(submitId.indexOf('.')+1); 308 } 309 StringTokenizer stok = new StringTokenizer (submitId, "."); 310 Widget submit = this; 311 while (stok.hasMoreTokens()) { 312 submit = submit.lookupWidget(stok.nextToken()); 313 if (submit == null) { 314 throw new IllegalArgumentException ("Invalid submit id (no such widget): " + submitId); 315 } 316 } 317 318 setSubmitWidget(submit); 319 } 320 321 try { 322 this.bufferEvents = true; 324 325 doReadFromRequest(formContext); 326 327 fireEvents(); 330 } finally { 331 this.bufferEvents = false; 333 } 334 335 if (this.listener != null) { 337 this.listener.phaseEnded(new ProcessingPhaseEvent(this, this.phase)); 338 } 339 if (this.endProcessing != null) { 340 return this.endProcessing.booleanValue(); 341 } 342 343 return validate(); 344 } 345 346 351 public void endProcessing(boolean redisplayForm) { 352 this.endProcessing = BooleanUtils.toBooleanObject( !redisplayForm ); 356 } 357 358 363 public boolean isValid() { 364 return this.isValid; 365 } 366 367 public void readFromRequest(FormContext formContext) { 368 throw new UnsupportedOperationException ("Please use Form.process()"); 369 } 370 371 private void doReadFromRequest(FormContext formContext) { 372 super.readFromRequest(formContext); 374 } 375 376 382 public ValidationError getValidationError() { 383 return this.validationError; 384 } 385 386 389 public void setValidationError(ValidationError error) { 390 this.validationError = error; 391 } 392 393 396 public boolean validate() { 397 this.phase = ProcessingPhase.VALIDATE; 399 this.isValid = super.validate(); 400 401 if (this.endProcessing != null) { 403 this.wasValid = this.endProcessing.booleanValue(); 404 return this.wasValid; 405 } 406 407 if (this.listener != null) { 409 this.listener.phaseEnded(new ProcessingPhaseEvent(this, this.phase)); 410 } 411 if (this.endProcessing != null) { 412 this.isValid = false; 415 this.wasValid = this.endProcessing.booleanValue(); 416 return this.wasValid; 417 } 418 this.wasValid = this.isValid && this.validationError == null; 419 return this.wasValid; 420 } 421 422 public String getXMLElementName() { 423 return FORM_EL; 424 } 425 } 426 | Popular Tags |