tim 2004/01/26 21:50:09
Modified: src/blocks/woody/java/org/apache/cocoon/woody/binding
InsertBeanJXPathBinding.java
InsertNodeJXPathBinding.java
RepeaterJXPathBinding.java
TempRepeaterJXPathBinding.java
TempRepeaterJXPathBindingBuilder.java
src/blocks/woody/samples/forms form_model_gui_binding.xml
Log:
Make the InsertNodeJXPathBinding actually insert its node
and the InsertBeanJXPathBinding actually insert its bean
instead of registering a factory do the insert later.
Together with associated changes to RepeaterJXPathBinding
and TempRepeaterJXPathBinding, the insert node and bean
implementation now matches the documentation.
Also, the TempRepeaterJXPathBinding was modified to
support virtual rows for DOM bindings. This provides
a virtual JXPath context for the selected row data,
making it easier to bind to rows that do not have a
common row element wrapped around them.
The sample form model GUI binding was updated to use
these new/modified features. This binding now works
correctly, except for adding extraneous whitespace to
the output document.
Revision Changes Path
1.6 +52 -30
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/InsertBeanJXPathBinding.java
Index: InsertBeanJXPathBinding.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/InsertBeanJXPathBinding.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- InsertBeanJXPathBinding.java 11 Jan 2004 20:51:16 -0000 1.5
+++ InsertBeanJXPathBinding.java 27 Jan 2004 05:50:08 -0000 1.6
@@ -97,35 +97,57 @@
* inside this object into the target objectmodel.
*/
public void doSave(Widget frmModel, JXPathContext jxpc) throws
BindingException {
- jxpc.setFactory(new AbstractFactory() {
- public boolean createObject(JXPathContext context, Pointer
pointer,
- Object parent, String name, int
index) {
- try {
- Object[] args = new Object[1];
- Class[] argTypes = new Class[1];
+ try {
+ Object parent = jxpc.getContextBean();
+ Object[] args = new Object[1];
+ Class[] argTypes = new Class[1];
- // instantiate the new object
- argTypes[0] =
Class.forName(InsertBeanJXPathBinding.this.className);
- args[0] = argTypes[0].newInstance();
- // lookup the named method on the parent
+ // instantiate the new object
+ argTypes[0] = Class.forName(this.className);
+ args[0] = argTypes[0].newInstance();
- Method addMethod =
-
parent.getClass().getMethod(InsertBeanJXPathBinding.this.addMethodName,
argTypes);
- // invoke this method with this new beast.
+ // lookup the named method on the parent
+ Method addMethod =
+ parent.getClass().getMethod(this.addMethodName, argTypes);
- addMethod.invoke(parent, args);
+ // invoke this method with this new beast.
+ addMethod.invoke(parent, args);
- if (getLogger().isDebugEnabled())
- getLogger().debug("InsertBean jxpath factory
executed for index " + index);
- return true;
- } catch (Exception e) {
- throw new CascadingRuntimeException("InsertBean jxpath
factory failed.", e);
- }
- }
- });
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("InsertBean performed.");
+ } catch (Exception e) {
+ throw new CascadingRuntimeException("InsertBean failed.", e);
+ }
- if (getLogger().isDebugEnabled())
- getLogger().debug("done registered factory for inserting node --
" + toString());
+ // jxpc.setFactory(new AbstractFactory() {
+ // public boolean createObject(JXPathContext context, Pointer
pointer,
+ // Object parent, String name, int
index) {
+ // try {
+ // Object[] args = new Object[1];
+ // Class[] argTypes = new Class[1];
+ //
+ // // instantiate the new object
+ // argTypes[0] =
Class.forName(InsertBeanJXPathBinding.this.className);
+ // args[0] = argTypes[0].newInstance();
+ // // lookup the named method on the parent
+ //
+ // Method addMethod =
+ //
parent.getClass().getMethod(InsertBeanJXPathBinding.this.addMethodName,
argTypes);
+ // // invoke this method with this new beast.
+ //
+ // addMethod.invoke(parent, args);
+ //
+ // if (getLogger().isDebugEnabled())
+ // getLogger().debug("InsertBean jxpath factory
executed for index " + index);
+ // return true;
+ // } catch (Exception e) {
+ // throw new CascadingRuntimeException("InsertBean
jxpath factory failed.", e);
+ // }
+ // }
+ // });
+ //
+ // if (getLogger().isDebugEnabled())
+ // getLogger().debug("done registered factory for inserting node
-- " + toString());
}
public String toString() {
1.6 +24 -16
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/InsertNodeJXPathBinding.java
Index: InsertNodeJXPathBinding.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/InsertNodeJXPathBinding.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- InsertNodeJXPathBinding.java 11 Jan 2004 20:51:16 -0000 1.5
+++ InsertNodeJXPathBinding.java 27 Jan 2004 05:50:08 -0000 1.6
@@ -97,23 +97,31 @@
*/
public void doSave(Widget frmModel, JXPathContext jxpc) {
- jxpc.setFactory(new AbstractFactory() {
- public boolean createObject(JXPathContext context, Pointer
pointer,
- Object parent, String name, int index) {
-
- Node parentNode = (Node) parent;
- Document targetDoc = parentNode.getOwnerDocument();
- Node toInsert =
targetDoc.importNode(InsertNodeJXPathBinding.this.template, true);
- parentNode.appendChild(toInsert);
-
- if (getLogger().isDebugEnabled())
- getLogger().debug("InsertNode jxpath factory executed
for index." + index);
- return true;
- }
- });
+ Node parentNode = (Node)jxpc.getContextBean();
+ Document targetDoc = parentNode.getOwnerDocument();
+ Node toInsert = targetDoc.importNode(this.template, true);
+ parentNode.appendChild(toInsert);
if (getLogger().isDebugEnabled())
- getLogger().debug("done registered factory for inserting node --
" + toString());
+ getLogger().debug("InsertNode executed.");
+
+ // jxpc.setFactory(new AbstractFactory() {
+ // public boolean createObject(JXPathContext context, Pointer
pointer,
+ // Object parent, String name, int index) {
+ //
+ // Node parentNode = (Node) parent;
+ // Document targetDoc = parentNode.getOwnerDocument();
+ // Node toInsert =
targetDoc.importNode(InsertNodeJXPathBinding.this.template, true);
+ // parentNode.appendChild(toInsert);
+ //
+ // if (getLogger().isDebugEnabled())
+ // getLogger().debug("InsertNode jxpath factory executed
for index." + index);
+ // return true;
+ // }
+ // });
+ //
+ // if (getLogger().isDebugEnabled())
+ // getLogger().debug("done registered factory for inserting node
-- " + toString());
}
public String toString() {
1.16 +4 -2
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/RepeaterJXPathBinding.java
Index: RepeaterJXPathBinding.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/RepeaterJXPathBinding.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- RepeaterJXPathBinding.java 11 Jan 2004 20:51:16 -0000 1.15
+++ RepeaterJXPathBinding.java 27 Jan 2004 05:50:08 -0000 1.16
@@ -278,9 +278,11 @@
if (this.insertRowBinding != null) {
Iterator rowIterator = rowsToInsert.iterator();
//register the factory!
- this.insertRowBinding.saveFormToModel(repeater,
repeaterContext);
+ //this.insertRowBinding.saveFormToModel(repeater,
repeaterContext);
while (rowIterator.hasNext()) {
Repeater.RepeaterRow thisRow = (Repeater.RepeaterRow)
rowIterator.next();
+ // Perform the insert row binding.
+ this.insertRowBinding.saveFormToModel(repeater,
repeaterContext);
// --> create the path to let the context be created
Pointer newRowContextPointer =
repeaterContext.createPath(this.rowPathForInsert + "[" + indexCount + "]");
JXPathContext newRowContext =
repeaterContext.getRelativeContext(newRowContextPointer);
1.4 +99 -44
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/TempRepeaterJXPathBinding.java
Index: TempRepeaterJXPathBinding.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/TempRepeaterJXPathBinding.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TempRepeaterJXPathBinding.java 11 Jan 2004 20:51:16 -0000 1.3
+++ TempRepeaterJXPathBinding.java 27 Jan 2004 05:50:08 -0000 1.4
@@ -81,12 +81,13 @@
private final JXPathBindingBase rowBinding;
private final JXPathBindingBase insertRowBinding;
private final boolean deleteIfEmpty;
+ private final boolean virtualRows;
public TempRepeaterJXPathBinding(
JXpathBindingBuilderBase.CommonAttributes commonAtts,
String repeaterId, String repeaterPath,
String rowPath, String rowPathInsert,
- boolean clearOnLoad, boolean deleteIfEmpty,
+ boolean virtualRows, boolean clearOnLoad, boolean deleteIfEmpty,
JXPathBindingBase rowBinding, JXPathBindingBase insertBinding) {
super(commonAtts);
this.repeaterId = repeaterId;
@@ -97,38 +98,53 @@
this.rowBinding.setParent(this);
this.insertRowBinding = insertBinding;
this.insertRowBinding.setParent(this);
+ this.virtualRows = virtualRows;
this.clearOnLoad = clearOnLoad;
this.deleteIfEmpty = deleteIfEmpty;
}
public void doLoad(Widget frmModel, JXPathContext jctx) {
- // Find the repeater and clear it
+ // (There should be a general widget type checker for all the
bindings to use,
+ // coupled with a general informative exception class to throw if
the widget is
+ // of the wrong type or null.)
Repeater repeater = (Repeater) frmModel.getWidget(this.repeaterId);
-
- // TODO: RAD
if (repeater == null) {
+ String fullId = frmModel.getFullyQualifiedId();
+ if (fullId == null || fullId.length() == 0) {
+ fullId = "";
+ } else {
+ fullId = fullId + ".";
+ }
throw new RuntimeException(
- "frmModel.getLocation() = " + frmModel.getLocation() +
- " repeaterId = " + this.repeaterId);
+ "TempRepeaterJXPathBinding: Repeater \"" + fullId +
this.repeaterId +
+ "\" does not exist (" + frmModel.getLocation() + ")");
}
-
+
+ // Start by clearing the repeater, if necessary.
if (this.clearOnLoad) {
repeater.removeRows();
}
- // Move to repeater context
- Pointer ptr = jctx.getPointer(this.repeaterPath);
- if (ptr.getNode() != null) {
- // There are some nodes to load from
+ // Find the location of the repeater data.
+ Pointer repeaterPointer = jctx.getPointer(this.repeaterPath);
+
+ // Check if there is data present.
+ //
+ // (Otherwise, should we check the leniency config option
+ // to decide whether to be silent or throw an exception?)
+ if (repeaterPointer != null) {
- JXPathContext repeaterContext = jctx.getRelativeContext(ptr);
- // build a jxpath iterator for pointers
+ // Narrow to repeater context.
+ JXPathContext repeaterContext =
jctx.getRelativeContext(repeaterPointer);
+
+ // Build a jxpath iterator for the repeater row pointers.
Iterator rowPointers =
repeaterContext.iteratePointers(this.rowPath);
- //iterate through it
+ // Iterate through the rows of data.
int rowNum = 0;
while (rowPointers.hasNext()) {
- // Get a row. It is created if needed (depends on
clearOnLoad)
+
+ // Get or create a row widget.
Repeater.RepeaterRow thisRow;
if (repeater.getSize() > rowNum) {
thisRow = repeater.getRow(rowNum);
@@ -137,10 +153,29 @@
}
rowNum++;
- // make a jxpath sub context on the iterated element
- Pointer jxp = (Pointer) rowPointers.next();
- JXPathContext rowContext =
repeaterContext.getRelativeContext(jxp);
+ // Narrow to the row context.
+ Pointer rowPointer = (Pointer) rowPointers.next();
+ JXPathContext rowContext =
repeaterContext.getRelativeContext(rowPointer);
+
+ // If virtual rows are requested, place a deep clone of the
row data
+ // into a temporary node, and narrow the context to this
virtual row.
+ //
+ // (A clone of the data is used to prevent modifying the
source document.
+ // Otherwise, the appendChild method would remove the data
from the source
+ // document. Is this protection worth the penalty of a deep
clone?)
+ //
+ // (This implementation of virtual rows currently only
supports DOM
+ // bindings, but could easily be extended to support other
bindings.)
+
+ if (virtualRows == true) {
+ Node repeaterNode = (Node)repeaterPointer.getNode();
+ Node virtualNode =
repeaterNode.getOwnerDocument().createElementNS(null, "virtual");
+ Node clone =
((Node)rowPointer.getNode()).cloneNode(true);
+ virtualNode.appendChild(clone);
+ rowContext = JXPathContext.newContext(repeaterContext,
virtualNode);
+ }
+ // Finally, perform the load row binding.
this.rowBinding.loadFormFromModel(thisRow, rowContext);
}
}
@@ -150,47 +185,67 @@
}
public void doSave(Widget frmModel, JXPathContext jctx) throws
BindingException {
- // Find the repeater
+ // (See comment in doLoad about type checking and throwing a
meaningful exception.)
Repeater repeater = (Repeater) frmModel.getWidget(this.repeaterId);
+ // Perform shortcut binding if the repeater is empty
+ // and the deleteIfEmpty config option is selected.
if (repeater.getSize() == 0 && this.deleteIfEmpty) {
- // Repeater is empty : erase all
+ // Delete all of the old data for this repeater.
jctx.removeAll(this.repeaterPath);
+ // Otherwise perform the normal save binding.
} else {
- // Repeater is not empty
- // Move to repeater context and create the path if needed
+ // Narrow to the repeater context, creating the path if it did
not exist.
JXPathContext repeaterContext =
jctx.getRelativeContext(jctx.createPath(this.repeaterPath));
- // Delete all that is already present
+ // Start by deleting all of the old row data.
repeaterContext.removeAll(this.rowPath);
+ // Verify that repeater is not empty and has an insert row
binding.
if(repeater.getSize() > 0) {
if (this.insertRowBinding != null) {
+
//register the factory!
- this.insertRowBinding.saveFormToModel(repeater,
repeaterContext);
+ //this.insertRowBinding.saveFormToModel(repeater,
repeaterContext);
+
+ // Iterate through the repeater rows.
for (int i = 0; i < repeater.getSize(); i++) {
- java.lang.System.err.println("TempRepeater: Bind
row.");
- //String path = this.rowPathInsert + '[' + (i+1) +
']';
- // --> create the path to let the context be created
- //Pointer rowPtr = repeaterContext.createPath(path);
- //JXPathContext rowContext =
repeaterContext.getRelativeContext(rowPtr);
- Node node = (Node)repeaterContext.getContextBean();
- Node virtualNode =
node.getOwnerDocument().createElementNS(null, "virtual");
- //JXPathContext rowContext =
JXPathContext.newContext(repeaterContext, virtualNode);
- JXPathContext rowContext =
JXPathContext.newContext(repeaterContext, virtualNode);
- // + bind to children for output
+
+ // Narrow to the repeater row context.
+ Pointer rowPointer =
repeaterContext.getPointer(this.rowPathInsert);
+ JXPathContext rowContext =
repeaterContext.getRelativeContext(rowPointer);
+
+ // Variables used for virtual rows.
+ // They are initialized here just to keep the
compiler happy.
+ Node rowNode = null;
+ Node virtualNode = null;
+
+ // If virtual rows are requested, create a temporary
node and
+ // narrow the context to this initially empty new
virtual row.
+ if (virtualRows == true) {
+ rowNode = (Node)rowContext.getContextBean();
+ virtualNode =
rowNode.getOwnerDocument().createElementNS(null, "virtual");
+ rowContext =
JXPathContext.newContext(repeaterContext, virtualNode);
+ }
+
+ // Perform the insert row binding
+ this.insertRowBinding.saveFormToModel(repeater,
rowContext);
+
+ // Perform the save row binding.
this.rowBinding.saveFormToModel(repeater.getRow(i),
rowContext);
- // Append children to current path.
- NodeList list = virtualNode.getChildNodes();
- java.lang.System.err.println("Node count: " +
list.getLength());
- //node.appendChild(virtualNode);
- int count = list.getLength();
- for (int j = 0; j < count; j++) {
- java.lang.System.err.println("Hello, child not
null. j: " + j);
- node.appendChild(list.item(0));
- java.lang.System.err.println("After. j: " + j);
+
+ // If virtual rows are requested, finish by
appending the
+ // children of the virtual row to the real context
node.
+ if (virtualRows == true) {
+ NodeList list = virtualNode.getChildNodes();
+ int count = list.getLength();
+ for (int j = 0; j < count; j++) {
+ // The list shrinks when a child is appended
to the context
+ // node, so we always reference the first
child in the list.
+ rowNode.appendChild(list.item(0));
+ }
}
getLogger().debug("bound new row");
}
1.3 +6 -3
cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/TempRepeaterJXPathBindingBuilder.java
Index: TempRepeaterJXPathBindingBuilder.java
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/java/org/apache/cocoon/woody/binding/TempRepeaterJXPathBindingBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TempRepeaterJXPathBindingBuilder.java 11 Jan 2004 20:51:16 -0000
1.2
+++ TempRepeaterJXPathBindingBuilder.java 27 Jan 2004 05:50:08 -0000
1.3
@@ -82,6 +82,7 @@
String parentPath = DomHelper.getAttribute(bindingElem,
"parent-path");
String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
String rowPathInsert = DomHelper.getAttribute(bindingElem,
"row-path-insert", rowPath);
+ boolean virtualRows =
DomHelper.getAttributeAsBoolean(bindingElem, "virtual-rows", false);
boolean clearOnLoad =
DomHelper.getAttributeAsBoolean(bindingElem, "clear-before-load", true);
boolean deleteIfEmpty =
DomHelper.getAttributeAsBoolean(bindingElem, "delete-parent-if-empty", false);
@@ -98,13 +99,15 @@
if (insertWrapElement != null)
insertBindings =
assistant.makeChildBindings(insertWrapElement);
- return new TempRepeaterJXPathBinding( commonAtts, repeaterId,
parentPath, rowPath, rowPathInsert, clearOnLoad, deleteIfEmpty,
+ return new TempRepeaterJXPathBinding(
+ commonAtts, repeaterId, parentPath, rowPath, rowPathInsert,
virtualRows, clearOnLoad, deleteIfEmpty,
new
ComposedJXPathBindingBase(JXpathBindingBuilderBase.CommonAttributes.DEFAULT,
childBindings),
new
ComposedJXPathBindingBase(JXpathBindingBuilderBase.CommonAttributes.DEFAULT,
insertBindings));
} catch (BindingException e) {
throw e;
} catch (Exception e) {
- throw new BindingException("Error building temp-repeater binding
defined at " + DomHelper.getLocation(bindingElem), e);
+ throw new BindingException("Error building temp-repeater binding
defined at " +
+ DomHelper.getLocation(bindingElem), e);
}
}
}
1.2 +85 -125
cocoon-2.1/src/blocks/woody/samples/forms/form_model_gui_binding.xml
Index: form_model_gui_binding.xml
===================================================================
RCS file:
/home/cvs/cocoon-2.1/src/blocks/woody/samples/forms/form_model_gui_binding.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- form_model_gui_binding.xml 29 Dec 2003 06:14:50 -0000 1.1
+++ form_model_gui_binding.xml 27 Jan 2004 05:50:09 -0000 1.2
@@ -1,23 +1,25 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+Binding for example CForms form model GUI.
+
[EMAIL PROTECTED]: Tim Larson
[EMAIL PROTECTED] CVS $Id$
+-->
+
<wb:context
xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
xmlns:wd="http://apache.org/cocoon/woody/definition/1.0"
path="/wd:form"
lenient="true">
- <!--
- This binding needs lots of work...
-
- CVS $Id$
- Author: Timothy Larson
- -->
-
<wb:new id="widgets-class"/>
<wb:class id="widgets-class">
<wb:temp-repeater id="widgets"
parent-path="wd:widgets"
- row-path="*">
+ row-path="*" row-path-insert="."
+ virtual-rows="true">
<wb:on-bind>
<wb:new id="widget-row-class"/>
</wb:on-bind>
@@ -27,17 +29,10 @@
<wb:class id="widget-row-class">
<wb:javascript id="type" path=".">
<wb:load-form>
- widget.setValue(jxpathPointer.getNode().getLocalName());
+ var node = jxpathPointer.getNode().getFirstChild();
+ widget.setValue(node.getLocalName());
</wb:load-form>
<wb:save-form>
- /*
- var value = widget.getValue();
- var node = jxpathPointer.getNode();
- var doc = node.getOwnerDocument();
- var newNode =
doc.createElementNS("http://apache.org/cocoon/woody/binding/1.0", value);
- node.appendChild(newNode);
- jxpathContext =
jxpathContext.getRelativeContext(jxpathContext.getPointer(value));
- */
</wb:save-form>
</wb:javascript>
<wb:union id="union" path=".">
@@ -58,32 +53,24 @@
<wb:class id="action-class">
<wb:case id="action" path=".">
- <wb:struct id="action" path=".">
- <!--
- <wb:insert-node>
- <wd:action/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
- <wb:value id="label" path="wd:action/wb:label" direction="save"/>
- <wb:value id="id" path="wd:action/@id" direction="save"/>
+ <wb:insert-node>
+ <wd:action/>
+ </wb:insert-node>
+ <wb:struct id="action" path="wd:action">
+ <wb:value id="label" path="wd:label"/>
+ <wb:value id="id" path="@id"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="aggregatefield-class">
<wb:case id="aggregatefield" path=".">
- <wb:struct id="aggregatefield" path=".">
- <!--
- <wb:insert-node>
- <wd:aggregatefield/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
- <wb:value id="label" path="wd:aggregatefield/wb:label"
direction="save"/>
- <wb:value id="id" path="wd:aggregatefield/@id" direction="save"/>
+ <wb:insert-node>
+ <wd:aggregatefield/>
+ </wb:insert-node>
+ <wb:struct id="aggregatefield" path="wd:aggregatefield">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
<wb:insert-node><wd:widgets/></wb:insert-node>
<wb:new id="widgets-class"/>
</wb:struct>
@@ -92,29 +79,23 @@
<wb:class id="booleanfield-class">
<wb:case id="booleanfield" path=".">
- <wb:struct id="booleanfield" path=".">
- <!--
- <wb:insert-node>
- <wd:booleanfield/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
- <wb:value id="label" path="wb:booleanfield/wb:label"
direction="save"/>
- <wb:value id="id" path="wb:booleanfield/@id" direction="save"/>
+ <wb:insert-node>
+ <wd:booleanfield/>
+ </wb:insert-node>
+ <wb:struct id="booleanfield" path="wd:booleanfield">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="class-class">
<wb:case id="class" path=".">
- <wb:struct id="class" path=".">
- <!--
- <wb:insert-node>
- <wd:class/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
+ <wb:insert-node>
+ <wd:class/>
+ </wb:insert-node>
+ <wb:struct id="class" path="wd:class">
+ <wb:value id="id" path="@id"/>
<wb:insert-node><wd:widgets/></wb:insert-node>
<wb:new id="widgets-class"/>
</wb:struct>
@@ -123,15 +104,13 @@
<wb:class id="field-class">
<wb:case id="field" path=".">
- <wb:struct id="field" path=".">
- <!--
- <wb:insert-node>
- <wd:field/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
- <wb:value id="required" path="@required" direction="load">
+ <wb:insert-node>
+ <wd:field/>
+ </wb:insert-node>
+ <wb:struct id="field" path="wd:field">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
+ <wb:value id="required" path="@required">
<wd:convertor datatype="boolean"/>
</wb:value>
</wb:struct>
@@ -140,42 +119,36 @@
<wb:class id="new-class">
<wb:case id="new" path=".">
- <wb:struct id="new" path=".">
- <!--
- <wb:insert-node>
- <wd:new/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
+ <wb:insert-node>
+ <wd:new/>
+ </wb:insert-node>
+ <wb:struct id="new" path="wd:new">
+ <wb:value id="id" path="@id"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="output-class">
<wb:case id="output" path=".">
- <wb:struct id="output" path=".">
- <!--
- <wb:insert-node>
- <wd:output/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
+ <wb:insert-node>
+ <wd:output/>
+ </wb:insert-node>
+ <wb:struct id="output" path="wd:output">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="repeater-class">
<wb:case id="repeater" path=".">
- <wb:struct id="repeater" path=".">
- <!--
- <wb:insert-node>
- <wd:repeater/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
- <wb:value id="initial-size" path="@initial-size" direction="load">
+ <wb:insert-node>
+ <wd:repeater/>
+ </wb:insert-node>
+ <wb:struct id="repeater" path="wd:repeater">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
+ <wb:value id="initial-size" path="@initial-size">
<wd:convertor datatype="long"/>
</wb:value>
<wb:insert-node><wd:widgets/></wb:insert-node>
@@ -186,28 +159,24 @@
<wb:class id="row-action-class">
<wb:case id="row-action" path=".">
- <wb:struct id="row-action" path=".">
- <!--
- <wb:insert-node>
- <wd:row-action/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
+ <wb:insert-node>
+ <wd:row-action/>
+ </wb:insert-node>
+ <wb:struct id="row-action" path="wd:row-action">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="struct-class">
<wb:case id="struct" path=".">
- <wb:struct id="struct" path=".">
- <!--
- <wb:insert-node>
- <wd:struct/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
+ <wb:insert-node>
+ <wd:struct/>
+ </wb:insert-node>
+ <wb:struct id="struct" path="wd:struct">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
<wb:insert-node><wd:widgets/></wb:insert-node>
<wb:new id="widgets-class"/>
</wb:struct>
@@ -215,34 +184,25 @@
</wb:class>
<wb:class id="submit-class">
- <wb:case id="submit" path="/">
- <wb:struct id="submit" path=".">
- <!--
- <wb:insert-node>
- <wd:submit/>
- </wb:insert-node>
- -->
- <wb:insert-node>
- <wd:submit><wd:label/></wd:submit>
- </wb:insert-node>
- <wb:value id="id" path="@id" direction="load"/>
- <!-- wb:value id="id" path="wd:submit/@id" direction="save"/ -->
- <wb:value id="label" path="wd:label" direction="load"/>
- <!-- wb:value id="label" path="wd:submit/wd:label" direction="save"/
-->
+ <wb:case id="submit" path=".">
+ <wb:insert-node>
+ <wd:submit/>
+ </wb:insert-node>
+ <wb:struct id="submit" path="wd:submit">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
</wb:struct>
</wb:case>
</wb:class>
<wb:class id="union-class">
<wb:case id="union" path=".">
- <wb:struct id="union" path=".">
- <!--
- <wb:insert-node>
- <wd:union/>
- </wb:insert-node>
- -->
- <wb:value id="id" path="@id" direction="load"/>
- <wb:value id="label" path="wd:label" direction="load"/>
+ <wb:insert-node>
+ <wd:union/>
+ </wb:insert-node>
+ <wb:struct id="union" path="wd:union">
+ <wb:value id="id" path="@id"/>
+ <wb:value id="label" path="wd:label"/>
<wb:insert-node><wd:widgets/></wb:insert-node>
<wb:new id="widgets-class"/>
</wb:struct>