You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by do...@cocoon.apache.org on 2004/07/10 04:00:04 UTC

[Cocoon Wiki] Updated: WoodyBinding

   Date: 2004-07-09T19:00:04
   Editor: JoergHeinicke <jo...@gmx.de>
   Wiki: Cocoon Wiki
   Page: WoodyBinding
   URL: http://wiki.apache.org/cocoon/WoodyBinding

   no comment

Change Log:

------------------------------------------------------------------------------
@@ -3,31 +3,31 @@
 Likely you will want to use Woody to "edit stuff", such as the properties of a bean or data from an XML document (we'll simply use the term object to refer to either of these). This supposes that before you show the form, you copy the data from the object to the form, and after the form has been validated, you copy the data in the form back to the object. To avoid having to write actual code for this, a binding framework is available.
 The basic definition of a binding is as follows (if you don't know Java, just ignore this):
 
-{{{
-public interface Binding {
-    public void loadFormFromModel(Widget frmModel, Object objModel);
-    public void saveFormToModel(Widget frmModel, Object objModel);
-}
+{{{
+public interface Binding {
+    public void loadFormFromModel(Widget frmModel, Object objModel);
+    public void saveFormToModel(Widget frmModel, Object objModel);
+}
 }}}
 
 A binding can work with any object and can perform the binding in any possible way. Currently one implementation is available, based on [http://jakarta.apache.org/commons/jxpath/index.html JXPath]. JXPath allows to address data in both beans and XML documents using [http://www.w3.org/TR/xpath XPath expressions], so this binding implementation can be used both with beans and XML documents. The rest of this document will focus on this implementation.
 
 The binding is configured using an XML file. This XML file contains elements in the {{{wb}}} namesspace (Woody Binding):
 
-{{{
-xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
+{{{
+xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
 }}}
 
 = What does a binding file look like? =
 
 To give you an idea of what a binding file looks like, below a very simple example is shown.
 
-{{{
-<wb:context xmlns:wb="http://apache.org/cocoon/woody/binding/1.0" path="/" >
-    <wb:value id="firstname" path="firstName"/>
-    <wb:value id="lastname" path="lastName"/>
-    <wb:value id="email" path="email"/>
-</wb:context>
+{{{
+<wb:context xmlns:wb="http://apache.org/cocoon/woody/binding/1.0" path="/" >
+    <wb:value id="firstname" path="firstName"/>
+    <wb:value id="lastname" path="lastName"/>
+    <wb:value id="email" path="email"/>
+</wb:context>
 }}}
 
 The {{{id}}} attribute identifies the WoodyWidgetReference.
@@ -87,22 +87,22 @@
 
 Secondly, you use {{{wb:context}}} if you need to address multiple items having a common base path. On the one hand, this saves you on typing and helps readability, and on the other hand, this improves the performance of the binding. To illustrate this with an example, instead of doing this:
 
-{{{
-...
-<wb:value id="firstname" path="info/person/firstName"/>
-<wb:value id="lastname" path="info/person/lastName"/>
-...
+{{{
+...
+<wb:value id="firstname" path="info/person/firstName"/>
+<wb:value id="lastname" path="info/person/lastName"/>
+...
 }}}
 
 it is better to do this:
 
-{{{
-...
-<wb:context path="info/person">
-  <wb:value id="firstname" path="firstName"/>
-  <wb:value id="lastname" path="lastName"/>
-</wb:context>
-...
+{{{
+...
+<wb:context path="info/person">
+  <wb:value id="firstname" path="firstName"/>
+  <wb:value id="lastname" path="lastName"/>
+</wb:context>
+...
 }}}
 
 == wb:value ==
@@ -122,14 +122,14 @@
 
 The {{{wd:convertor}}} element has the same purpose as the {{{wd:convertor}}} element in the form definition: it converts between objects (numbers, dates) and strings. This is mostly used when binding to XML documents. Suppose you have defined a certain widget in a form definition to have a "date" datatype, and you want to bind to an XML document which contains the date in the XML Schema date representation, then you could define a convertor as follows:
 
-{{{
-<wb:value id="birthday" path="person/birthday">
-  <wd:convertor datatype="date" type="formatting">
-    <wd:patterns>
-      <wd:pattern>yyyy-MM-dd</wd:pattern>
-    </wd:patterns>
-  </wd:convertor>
-</wb:value>
+{{{
+<wb:value id="birthday" path="person/birthday">
+  <wd:convertor datatype="date" type="formatting">
+    <wd:patterns>
+      <wd:pattern>yyyy-MM-dd</wd:pattern>
+    </wd:patterns>
+  </wd:convertor>
+</wb:value>
 }}}
 
 The datatype attribute on the {{{wd:convertor}}} element, which you don't have to specify in the form definition, identifies the datatype to which the convertor belongs.
@@ -180,11 +180,11 @@
 
 For XML documents:
 If you have an XML structure like this:
-{{{
-<things>
-   <thing ... />
-   <thing ... />
-</things>
+{{{
+<things>
+   <thing ... />
+   <thing ... />
+</things>
 }}}
 
 then the parent-path attribute contains the path to the containing element ("things") and the row-path attribute contains the path to the repeating element ("thing").
@@ -296,19 +296,19 @@
 Specifies the binding using two !JavaScript snippets, respectively for loading and saving the form.
 
 Example:
-{{{
-<wb:javascript id="foo" path="@foo">
-  <wb:load-form>
-    var appValue = jxpathPointer.getValue();
-    var formValue = doLoadConversion(appValue);
-    widget.setValue(formValue);
-  </wb:load-form>
-  <wb:save-form>
-    var formValue = widget.getValue();
-    var appValue = doSaveConversion(formValue);
-    jxpathPointer.setValue(appValue);
-  </wb:save-form>
-</wb:javascript>
+{{{
+<wb:javascript id="foo" path="@foo">
+  <wb:load-form>
+    var appValue = jxpathPointer.getValue();
+    var formValue = doLoadConversion(appValue);
+    widget.setValue(formValue);
+  </wb:load-form>
+  <wb:save-form>
+    var formValue = widget.getValue();
+    var appValue = doSaveConversion(formValue);
+    jxpathPointer.setValue(appValue);
+  </wb:save-form>
+</wb:javascript>
 }}}
 
 This example is rather trivial and could be replaced by a simple {{{<wb:value>}}}, but it shows the available variables in the script:
@@ -319,13 +319,13 @@
 
 It's much more interesting to fill a selection list via {{{wb:javascript}}} as there is no built-in element for it at the moment. Imagine your binding bean contains a collection field:
 
-{{{
-<wb:javascript id="selectionListWidget" path="objectCollection" direction="load">
-  <wb:load-form>
-    var collection = jxpathPointer.getNode();
-    widget.setSelectionList(collection, "id", "name")
-  </wb:load-form>
-</wb:javascript>
+{{{
+<wb:javascript id="selectionListWidget" path="objectCollection" direction="load">
+  <wb:load-form>
+    var collection = jxpathPointer.getNode();
+    widget.setSelectionList(collection, "id", "name")
+  </wb:load-form>
+</wb:javascript>
 }}}
 
 '''NOTE''': 
@@ -352,15 +352,15 @@
 There are two essential modes of operation reflected in two examples:
 
 Example 1 - No configuration required:
-{{{
-  <fb:custom id="custom" path="custom-value" 
-      class="org.apache.cocoon.forms.samples.bindings.CustomValueWrapBinding"/>
+{{{
+  <fb:custom id="custom" path="custom-value" 
+      class="org.apache.cocoon.forms.samples.bindings.CustomValueWrapBinding"/>
 }}}
 
 This describes the classname of your user defined binding class.
 
 Above imposes the following requirements:
- 1. there is a {{{class}}}=== CustomValueWrapBinding available in the specified package  ===
+ 1. there is a {{{class}}} !CustomValueWrapBinding available in the specified package
  1. it has a default (i.e. no arguments) constructor
  1. it is a subclass of org.apache.cocoon.forms.binding.!AbstractCustomBinding
 
@@ -375,16 +375,16 @@
 
 
 Example 2 - with nested configuration: 
-{{{
-  <fb:custom id="config" path="config-value" 
-      builderclass="org.apache.cocoon.forms.samples.bindings.CustomValueWrapBinding"
-      factorymethod="createBinding" >
-      <fb:config prefixchar="[" suffixchar="]" />      
-  </fb:custom>
+{{{
+  <fb:custom id="config" path="config-value" 
+      builderclass="org.apache.cocoon.forms.samples.bindings.!CustomValueWrapBinding"
+      factorymethod="createBinding" >
+      <fb:config prefixchar="[" suffixchar="]" />      
+  </fb:custom>
 }}}
 
 The additional requirements to your user defined classes are now:
- 1. there is a {{{builderclass}}}=== CustomValueWrapBinding class having a static  ==={{{factorymethod}}} 
+ 1. there is a {{{builderclass}}} !CustomValueWrapBinding class having a static {{{factorymethod}}} 
  1. that can (optionally) take an org.w3c.dom.Element holding it's configuration 
  1. and return an instance of your own user-defined binding which must be a non abstract subclass of org.apache.cocoon.forms.binding.!AbstractCustomBinding