You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by sy...@apache.org on 2005/09/20 17:30:53 UTC

svn commit: r290473 - in /cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding: BindingException.java RepeaterJXPathBinding.java RepeaterJXPathBindingBuilder.java

Author: sylvain
Date: Tue Sep 20 08:30:48 2005
New Revision: 290473

URL: http://svn.apache.org/viewcvs?rev=290473&view=rev
Log:
Fix NPE in repeater binding when no <fb:identity> is given

Modified:
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/BindingException.java
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBinding.java
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBindingBuilder.java

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/BindingException.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/BindingException.java?rev=290473&r1=290472&r2=290473&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/BindingException.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/BindingException.java Tue Sep 20 08:30:48 2005
@@ -15,19 +15,34 @@
  */
 package org.apache.cocoon.forms.binding;
 
-import org.apache.avalon.framework.CascadingException;
+import org.apache.cocoon.util.location.LocatedException;
+import org.apache.cocoon.util.location.Location;
 
 /**
  * This exception is thrown when something goes wrong with the binding.
  *
  * @version $Id$
  */
-public class BindingException extends CascadingException {
+public class BindingException extends LocatedException {
+
+    public BindingException(String message, Location location) {
+        super(message, location);
+        // TODO Auto-generated constructor stub
+    }
+
+    public BindingException(String message, Throwable cause, Location location) {
+        super(message, cause, location);
+        // TODO Auto-generated constructor stub
+    }
+
+    public BindingException(String message, Throwable cause) {
+        super(message, cause);
+        // TODO Auto-generated constructor stub
+    }
+
     public BindingException(String message) {
         super(message);
+        // TODO Auto-generated constructor stub
     }
 
-    public BindingException(String message, Exception e) {
-        super(message, e);
-    }
 }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBinding.java?rev=290473&r1=290472&r2=290473&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBinding.java Tue Sep 20 08:30:48 2005
@@ -16,6 +16,7 @@
 package org.apache.cocoon.forms.binding;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -37,7 +38,7 @@
  * @version $Id$
  */
 public class RepeaterJXPathBinding extends JXPathBindingBase {
-
+    
     private final String repeaterId;
     private final String repeaterPath;
     private final String rowPath;
@@ -46,7 +47,7 @@
     private final JXPathBindingBase insertRowBinding;
     private final JXPathBindingBase deleteRowBinding;
     private final ComposedJXPathBindingBase identityBinding;
-
+    
     /**
      * Constructs RepeaterJXPathBinding
      */
@@ -61,17 +62,17 @@
         this.repeaterPath = repeaterPath;
         this.rowPath = rowPath;
         this.rowPathForInsert = rowPathForInsert;
-
+        
         this.rowBinding = new ComposedJXPathBindingBase(
-                                  JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
-                                  childBindings);
+                JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
+                childBindings);
         this.rowBinding.setParent(this);
-
+        
         this.insertRowBinding = insertBinding;
         if (this.insertRowBinding != null) {
             this.insertRowBinding.setParent(this);
         }
-
+        
         if (deleteBindings != null) {
             this.deleteRowBinding = new ComposedJXPathBindingBase(
                     JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
@@ -80,17 +81,17 @@
         } else {
             this.deleteRowBinding = null;
         }
-
+        
         
         if (identityBindings != null) {
-        	
-        	this.identityBinding = new ComposedJXPathBindingBase(
-                                       JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
-                                       identityBindings);
-        	this.identityBinding.setParent(this);
+            
+            this.identityBinding = new ComposedJXPathBindingBase(
+                    JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
+                    identityBindings);
+            this.identityBinding.setParent(this);
         }
         else
-        	this.identityBinding = null;
+            this.identityBinding = null;
     }
     
     public String getId() { return repeaterId; }
@@ -101,14 +102,14 @@
     public ComposedJXPathBindingBase getDeleteRowBinding() { return (ComposedJXPathBindingBase)deleteRowBinding; }
     public ComposedJXPathBindingBase getIdentityBinding() { return (ComposedJXPathBindingBase)identityBinding; }
     public JXPathBindingBase getInsertRowBinding() { return insertRowBinding; }
-
+    
     /**
      * Binds the unique-id of the repeated rows, and narrows the context on
      * objectModelContext and Repeater to the repeated rows before handing
      * over to the actual binding-children.
      */
     public void doLoad(Widget frmModel, JXPathContext jxpc)
-            throws BindingException {
+    throws BindingException {
         // Find the repeater
         Repeater repeater = (Repeater) selectWidget(frmModel, this.repeaterId);
         if (repeater == null) {
@@ -117,7 +118,7 @@
         }
         repeater.clear();
         int initialSize = repeater.getSize();
-
+        
         // build a jxpath iterator for pointers
         JXPathContext repeaterContext =
             jxpc.getRelativeContext(jxpc.getPointer(this.repeaterPath));
@@ -135,39 +136,41 @@
             Pointer jxp = (Pointer)rowPointers.next();
             JXPathContext rowContext = repeaterContext.getRelativeContext(jxp);
             // hand it over to children
-            this.identityBinding.loadFormFromModel(thisRow, rowContext);
+            if (this.identityBinding != null) {
+                this.identityBinding.loadFormFromModel(thisRow, rowContext);
+            }
             this.rowBinding.loadFormFromModel(thisRow, rowContext);
         }
         if (getLogger().isDebugEnabled())
             getLogger().debug("done loading rows " + toString());
     }
-
+    
     /**
      * Uses the mapped identity of each row to detect if rows have been
      * updated, inserted or removed.  Depending on what happened the appropriate
      * child-bindings are allowed to visit the narrowed contexts.
      */
     public void doSave(Widget frmModel, JXPathContext jxpc)
-            throws BindingException {
+    throws BindingException {
         // Find the repeater
         Repeater repeater = (Repeater) selectWidget(frmModel, this.repeaterId);
         // and his context
         JXPathContext repeaterContext =
             jxpc.getRelativeContext(jxpc.getPointer(this.repeaterPath));
-
+        
         // create set of updatedRowIds
         Set updatedRows = new HashSet();
         //create list of rows to insert at end
         List rowsToInsert = new ArrayList();
-
+        
         // iterate rows in the form model...
         int formRowCount = repeater.getSize();
         for (int i = 0; i < formRowCount; i++) {
             Repeater.RepeaterRow thisRow = repeater.getRow(i);
-
+            
             // Get the identity
             List identity = getIdentity(thisRow);
-
+            
             if (hasNonNullElements(identity)) {
                 // iterate nodes to find match
                 Iterator rowPointers = repeaterContext.iteratePointers(this.rowPath);
@@ -222,7 +225,7 @@
                     getLogger().warn(
                             "RepeaterBinding has detected rows to delete, " +
                             "but misses the <on-delete-row> binding to do it."
-                            );
+                    );
                 }
             }
         }
@@ -246,7 +249,7 @@
                     Pointer newRowContextPointer = repeaterContext.createPath(
                             this.rowPathForInsert + "[" + indexCount + "]");
                     JXPathContext newRowContext =
-                            repeaterContext.getRelativeContext(newRowContextPointer);
+                        repeaterContext.getRelativeContext(newRowContextPointer);
                     if (getLogger().isDebugEnabled()) {
                         getLogger().debug("inserted row at " + newRowContextPointer.asPath());
                     }
@@ -258,7 +261,7 @@
             } else {
                 if (getLogger().isWarnEnabled()) {
                     getLogger().warn("RepeaterBinding has detected rows to insert, but misses "
-                                     + "the <on-insert-row> binding to do it.");
+                            + "the <on-insert-row> binding to do it.");
                 }
             }
         }
@@ -266,7 +269,7 @@
             getLogger().debug("done saving rows " + toString());
         }
     }
-
+    
     /**
      * Tests if an identity is already contained in a Set of identities.
      * @param identitySet the Set of identities.
@@ -283,7 +286,7 @@
         }
         return false;
     }
-
+    
     /**
      * Tests if any of the elements in a List is not null.
      * @param list
@@ -298,7 +301,7 @@
         }
         return false;
     }
-
+    
     /**
      * Get the identity of the given row context. That's infact a list of all
      * the values of the fields in the bean or XML that constitute the identity. 
@@ -306,8 +309,12 @@
      * @return List the identity of the row context
      */
     private List getIdentity(JXPathContext rowContext) {
-        List identity = new ArrayList();
+        if (this.identityBinding == null) {
+            return Collections.EMPTY_LIST;
+        }
 
+        List identity = new ArrayList();
+        
         JXPathBindingBase[] childBindings = this.identityBinding.getChildBindings();
         if (childBindings != null) {
             int size = childBindings.length;
@@ -325,7 +332,7 @@
                     } else {
                         if (getLogger().isWarnEnabled()) {
                             getLogger().warn("Convertor ignored on backend-value " +
-                                    "which isn't of type String.");
+                            "which isn't of type String.");
                         }
                     }
                 }
@@ -334,7 +341,7 @@
         }
         return identity;
     }
-
+    
     /**
      * Get the identity of the given row. That's infact a list of all the values
      * of the fields in the form model that constitute the identity. 
@@ -342,11 +349,12 @@
      * @return List the identity of the row
      */
     private List getIdentity(Repeater.RepeaterRow row) {
-        List identity = new ArrayList();
-
         // quit if we don't have an identity binding
-        if(this.identityBinding == null)
-        	return identity;
+        if (this.identityBinding == null) {
+            return Collections.EMPTY_LIST;
+        }
+        
+        List identity = new ArrayList();
         
         JXPathBindingBase[] childBindings = this.identityBinding.getChildBindings();
         if (childBindings != null) {
@@ -360,12 +368,12 @@
         }
         return identity;
     }
-
+    
     public String toString() {
         return "RepeaterJXPathBinding [widget=" + this.repeaterId +
-               ", xpath=" + this.repeaterPath + "]";
+        ", xpath=" + this.repeaterPath + "]";
     }
-
+    
     public void enableLogging(Logger logger) {
         super.enableLogging(logger);
         if (this.deleteRowBinding != null) {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBindingBuilder.java?rev=290473&r1=290472&r2=290473&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/RepeaterJXPathBindingBuilder.java Tue Sep 20 08:30:48 2005
@@ -16,6 +16,7 @@
 package org.apache.cocoon.forms.binding;
 
 import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.cocoon.util.location.LocationAttributes;
 import org.w3c.dom.Element;
 
 /**
@@ -52,7 +53,7 @@
  * @version $Id$
  */
 public class RepeaterJXPathBindingBuilder extends JXPathBindingBuilderBase {
-
+    
     /**
      * Creates an instance of {@link RepeaterJXPathBinding} according to the
      * attributes and nested comfiguration elements of the bindingElm.
@@ -63,6 +64,16 @@
      */
     public JXPathBindingBase buildBinding(Element bindingElm,
             JXPathBindingManager.Assistant assistant) throws BindingException {
+        
+        if (bindingElm.hasAttribute("unique-row-id")) {
+            throw new BindingException("Attribute 'unique-row-id' is no more supported, use <fb:identity> instead",
+                    LocationAttributes.getLocation(bindingElm));
+        }
+
+        if (bindingElm.hasAttribute("unique-path")) {
+            throw new BindingException("Attribute 'unique-path' is no more supported, use <fb:identity> instead",
+                    LocationAttributes.getLocation(bindingElm));
+        }
 
         try {
             CommonAttributes commonAtts =