cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t..@apache.org
Subject cvs commit: cocoon-2.1/src/blocks/woody/samples/forms form_model_gui_binding.xml
Date Tue, 27 Jan 2004 05:50:09 GMT
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.
  +
  +@author: Tim Larson
  +@version 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>
  
  
  

Mime
View raw message