1 24 package org.riotfamily.forms; 25 26 import java.io.PrintWriter ; 27 import java.util.ArrayList ; 28 import java.util.Collection ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 import java.util.Set ; 35 36 import javax.servlet.http.HttpServletRequest ; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.riotfamily.common.markup.DocumentWriter; 41 import org.riotfamily.common.markup.Html; 42 import org.riotfamily.common.markup.TagWriter; 43 import org.riotfamily.forms.request.FormRequest; 44 import org.riotfamily.forms.request.HttpFormRequest; 45 import org.riotfamily.forms.resource.FormResource; 46 import org.riotfamily.forms.resource.LoadingCodeGenerator; 47 import org.riotfamily.forms.resource.ResourceElement; 48 import org.riotfamily.forms.resource.StylesheetResource; 49 import org.riotfamily.forms.support.MapOrBeanWrapper; 50 import org.springframework.util.Assert; 51 import org.springframework.validation.Validator; 52 53 54 57 public class Form implements BeanEditor { 58 59 private static final String DEFAULT_ID = "form"; 60 61 private static final String FORM_ATTR = "form"; 62 63 private static final String ELEMENT_CONTAINER_ATTR = "elements"; 64 65 private Log log = LogFactory.getLog(Form.class); 66 67 private String id = DEFAULT_ID; 68 69 70 private Map elementMap = new HashMap (); 71 72 73 private int idCount; 74 75 76 private Set paramNames = new HashSet (); 77 78 79 private EditorBinder editorBinder; 80 81 82 83 private List globalResources = new ArrayList (); 84 85 private FormInitializer initializer; 86 87 private List containers = new ArrayList (); 88 89 private Container elements; 90 91 private FormContext formContext; 92 93 private FormErrors errors; 94 95 private Validator validator; 96 97 private FormListener formListener; 98 99 private boolean rendering; 100 101 private boolean includeStylesheet; 102 103 private String template = TemplateUtils.getTemplatePath(this); 104 105 private Map renderModel = new HashMap (); 106 107 private String hint; 108 109 public Form() { 110 setAttribute(FORM_ATTR, this); 111 elements = createContainer(ELEMENT_CONTAINER_ATTR); 112 } 113 114 public Form(Class type) { 115 this(); 116 setBeanClass(type); 117 } 118 119 122 public Form(Object object) { 123 this(); 124 editorBinder = new EditorBinder(new MapOrBeanWrapper(object.getClass())); 125 editorBinder.setBackingObject(object); 126 } 127 128 public String getId() { 129 return this.id; 130 } 131 132 public void setId(String id) { 133 this.id = id; 134 } 135 136 public void setTemplate(String template) { 137 this.template = template; 138 } 139 140 public Collection getRegisteredElements() { 141 return elementMap.values(); 142 } 143 144 public void setAttribute(String key, Object value) { 145 renderModel.put(key,value); 146 } 147 148 public Object getAttribute(String key) { 149 return renderModel.get(key); 150 } 151 152 public void setBeanClass(Class beanClass) { 153 Assert.notNull(beanClass, "The beanClass must not be null."); 154 editorBinder = new EditorBinder(new MapOrBeanWrapper(beanClass)); 155 } 156 157 public void setValue(Object backingObject) { 158 if (backingObject != null) { 159 editorBinder.setBackingObject(backingObject); 160 } 161 } 162 163 public Object getValue() { 164 return editorBinder.getBackingObject(); 165 } 166 167 public boolean isNew() { 168 return !editorBinder.isEditingExistingBean(); 169 } 170 171 public EditorBinder getEditorBinder() { 172 return editorBinder; 173 } 174 175 public Editor getEditor(String property) { 176 return editorBinder.getEditor(property); 177 } 178 179 public void bind(Editor editor, String property) { 180 editorBinder.bind(editor, property); 181 } 182 183 public void addElement(Element element) { 184 elements.addElement(element); 185 } 186 187 public String getHint() { 188 if (hint == null) { 189 hint = MessageUtils.getHint(this, editorBinder.getBeanClass()); 190 } 191 return hint; 192 } 193 194 197 public void addElement(Editor element, String property) { 198 addElement(element); 199 bind(element, property); 200 } 201 202 public Container createContainer(String name) { 203 Container container = new Container(); 204 containers.add(container); 205 registerElement(container); 206 setAttribute(name, container); 207 return container; 208 } 209 210 public void addResource(FormResource resource) { 211 globalResources.add(resource); 212 } 213 214 protected List getResources() { 215 List resources = new ArrayList (globalResources); 216 Iterator it = getRegisteredElements().iterator(); 217 while (it.hasNext()) { 218 Element element = (Element) it.next(); 219 if (element instanceof ResourceElement) { 220 ResourceElement re = (ResourceElement) element; 221 FormResource res = re.getResource(); 222 if (res != null) { 223 resources.add(res); 224 } 225 } 226 } 227 return resources; 228 } 229 230 236 public void registerElement(Element element) { 237 String id = createId(); 238 element.setId(id); 239 element.setForm(this); 240 if (formContext != null) { 241 element.setFormContext(formContext); 242 } 243 elementMap.put(id, element); 244 } 245 246 public void unregisterElement(Element element) { 247 elementMap.remove(element.getId()); 248 } 249 250 public String createId() { 251 return "e" + idCount++; 252 } 253 254 257 public Element getElementById(String id) { 258 return (Element) elementMap.get(id); 259 } 260 261 266 public String createUniqueParameterName() { 267 return createUniqueParameterName(null); 268 } 269 270 279 public String createUniqueParameterName(String desiredName) { 280 if (desiredName == null) { 281 desiredName = "p" + paramNames.size(); 282 } 283 String name = desiredName; 284 if (name.equalsIgnoreCase("target")) { 285 name = "_target"; 287 } 288 if (paramNames.contains(name)) { 290 name = desiredName + paramNames.size(); 291 } 292 paramNames.add(name); 293 return name; 294 } 295 296 public void render(PrintWriter writer) { 297 rendering = true; 298 299 formContext.setWriter(writer); 300 DocumentWriter doc = new DocumentWriter(writer); 301 302 doc.start(Html.SCRIPT); 303 doc.attribute(Html.SCRIPT_SRC, formContext.getContextPath() 304 + formContext.getResourcePath() + "riot-js/resources.js"); 305 306 doc.attribute(Html.SCRIPT_TYPE, "text/javascript"); 307 doc.attribute(Html.SCRIPT_LANGUAGE, "JavaScript"); 308 doc.end(); 309 310 doc.start(Html.SCRIPT); 311 doc.attribute(Html.SCRIPT_SRC, formContext.getContextPath() 312 + formContext.getResourcePath() + "form/hint.js"); 313 314 doc.attribute(Html.SCRIPT_TYPE, "text/javascript"); 315 doc.attribute(Html.SCRIPT_LANGUAGE, "JavaScript"); 316 doc.end(); 317 318 doc.start(Html.SCRIPT).body(); 319 LoadingCodeGenerator.renderLoadingCode(getResources(), writer); 320 doc.end(); 321 322 formContext.getTemplateRenderer().render( 323 template, renderModel, writer); 324 325 rendering = false; 326 } 327 328 public boolean isRendering() { 329 return rendering; 330 } 331 332 public void elementRendered(Element element) { 333 log.debug("Element rendered: " + element.getId()); 334 if (getFormListener() != null) { 335 getFormListener().elementRendered(element); 336 } 337 if (rendering && element instanceof DHTMLElement) { 338 DHTMLElement dhtml = (DHTMLElement) element; 339 PrintWriter writer = formContext.getWriter(); 340 TagWriter script = new TagWriter(writer); 341 String initScript = dhtml.getInitScript(); 342 if (initScript != null) { 343 script.start(Html.SCRIPT); 344 script.attribute(Html.SCRIPT_LANGUAGE, "JavaScript"); 345 script.attribute(Html.SCRIPT_TYPE, "text/javascript"); 346 script.body().print("//").cData().println(); 347 if (dhtml instanceof ResourceElement) { 348 ResourceElement resEle = (ResourceElement) dhtml; 349 FormResource res = resEle.getResource(); 350 if (res != null) { 351 script.print("Resources.execWhenLoaded(['"); 352 script.print(res.getUrl()); 353 script.print("'], function() {"); 354 script.print(initScript); 355 script.print("})"); 356 } 357 else { 358 script.print(initScript); 359 } 360 } 361 else { 362 script.print(initScript); 363 } 364 script.print("//").end(); 365 } 366 } 367 } 368 369 public void setInitializer(FormInitializer initializer) { 370 this.initializer = initializer; 371 } 372 373 public void setValidator(Validator validator) { 374 this.validator = validator; 375 } 376 377 public void init() { 378 if (initializer != null) { 379 initializer.initForm(this); 380 } 381 editorBinder.initEditors(); 382 if (includeStylesheet) { 383 addResource(new StylesheetResource("form/form.css")); 384 } 385 } 386 387 public void processRequest(HttpServletRequest request) { 388 processRequest(new HttpFormRequest(request)); 389 } 390 391 public void processRequest(FormRequest request) { 392 errors = new FormErrors(this); 393 Iterator it = containers.iterator(); 394 while (it.hasNext()) { 395 Container container = (Container) it.next(); 396 container.processRequest(request); 397 } 398 if (validator != null) { 399 validator.validate(populateBackingObject(), errors); 400 } 401 } 402 403 public void processExclusiveRequest(String elementId, 404 HttpServletRequest request) { 405 406 processExclusiveRequest(elementId, new HttpFormRequest(request)); 407 } 408 409 public void processExclusiveRequest(String elementId, FormRequest request) { 410 errors = new FormErrors(this); 411 Element element = getElementById(elementId); 412 element.processRequest(request); 413 } 414 415 public void setFormListener(FormListener formListener) { 416 this.formListener = formListener; 417 } 418 419 public FormListener getFormListener() { 420 return formListener; 421 } 422 423 public void requestFocus(Element element) { 424 if (formListener != null) { 425 formListener.elementFocused(element); 426 } 427 } 428 429 public Object getBackingObject() { 430 return editorBinder.getBackingObject(); 431 } 432 433 public Object populateBackingObject() { 434 return editorBinder.populateBackingObject(); 435 } 436 437 public FormContext getFormContext() { 438 return this.formContext; 439 } 440 441 public void setFormContext(FormContext formContext) { 442 this.formContext = formContext; 443 this.errors = new FormErrors(this); 444 Iterator it = getRegisteredElements().iterator(); 445 while (it.hasNext()) { 446 Element element = (Element) it.next(); 447 element.setFormContext(formContext); 448 } 449 } 450 451 public FormErrors getErrors() { 452 return errors; 453 } 454 455 public boolean hasErrors() { 456 return errors.hasErrors(); 457 } 458 } | Popular Tags |