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 =