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/16 15:48:35 UTC

svn commit: r289538 [2/8] - in /cocoon: blocks/forms/trunk/WEB-INF/xconf/ blocks/forms/trunk/conf/ blocks/forms/trunk/java/org/apache/cocoon/forms/ blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ blocks/forms/trunk/java/org/apache/cocoon/forms...

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -75,7 +75,7 @@
             String xpath = DomHelper.getAttribute(bindingElm, "path", ".");
             String widgetId = DomHelper.getAttribute(bindingElm, "id", null);
 
-            Object bindingInstance;
+            Object bindingInstance = null;
             
             String className = DomHelper.getAttribute(bindingElm, "class", null);
             if(className != null) {
@@ -90,24 +90,40 @@
                 Element configNode = 
                     DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "config");
                 
-                Class builderClass = Class.forName(builderClassName);
-                Method factoryMethod = null; 
-                Object[] args = null;
-                try {
-                    factoryMethod = builderClass.getMethod(factoryMethodName, DOMELEMENT_METHODARGS);
-                    args = new Object[1];
-                    args[0] = configNode; 
-                } catch (NoSuchMethodException e) {
-                    factoryMethod = null;
+                // only do it if attributes exist
+                if(! (builderClassName == null || factoryMethodName == null) ) {
+	                Class builderClass = Class.forName(builderClassName);
+	                Method factoryMethod = null; 
+	                Object[] args = null;
+	                try {
+	                    factoryMethod = builderClass.getMethod(factoryMethodName, DOMELEMENT_METHODARGS);
+	                    args = new Object[1];
+	                    args[0] = configNode; 
+	                } catch (NoSuchMethodException e) {
+	                    factoryMethod = null;
+	                }
+	                
+	                if (factoryMethod == null) {
+	                    factoryMethod = builderClass.getMethod(factoryMethodName, EMPTY_METHODARGS);
+	                    args = null;
+	                }
+	                  
+	                // we pass null to indicate that the method should be static
+	                bindingInstance = factoryMethod.invoke(null, args);
                 }
-                
-                if (factoryMethod == null) {
-                    factoryMethod = builderClass.getMethod(factoryMethodName, EMPTY_METHODARGS);
-                    args = null;
-                }
-                  
-                // we pass null to indicate that the method should be static
-                bindingInstance = factoryMethod.invoke(null, args);
+            }
+            
+//          do inheritance
+            CustomJXPathBinding otherBinding = (CustomJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            	if(bindingInstance==null)
+            		bindingInstance = otherBinding.getWrappedBinding();
             }
 
             CustomJXPathBinding customBinding = 

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -38,6 +38,12 @@
     public JXPathBindingBase buildBinding(Element bindingElm, Assistant assistant) throws BindingException {
         CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
 
+//      do inheritance
+        DeleteNodeJXPathBinding otherBinding = (DeleteNodeJXPathBinding)assistant.getContext().getSuperBinding();
+        if(otherBinding!=null) {
+        	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+        }
+        
         return new DeleteNodeJXPathBinding(commonAtts);
     }
 }

Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java?rev=289538&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.forms.binding;
+
+import org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant;
+import org.apache.cocoon.forms.binding.library.Library;
+import org.apache.cocoon.forms.binding.library.LibraryException;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * @version $Id$
+ */
+public class ExpandJXPathBindingBuilder extends JXPathBindingBuilderBase {
+
+	/* (non-Javadoc)
+	 * @see org.apache.cocoon.forms.binding.JXPathBindingBuilderBase#buildBinding(org.w3c.dom.Element, org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant)
+	 */
+	public JXPathBindingBase buildBinding(Element bindingElm,
+			Assistant assistant) throws BindingException {
+
+		Library lib = assistant.getContext().getLocalLibrary();
+		
+		String id = DomHelper.getAttribute(bindingElm, "id", null);
+		
+		if(id == null)
+			throw new BindingException("Attribute id is required! (at "+DomHelper.getLocation(bindingElm)+")");
+		
+		try {
+			return (JXPathBindingBase)lib.getBinding(id);
+		} catch(LibraryException e) {
+			throw new BindingException("Could not expand binding from library! (at "+DomHelper.getLocation(bindingElm)+")",e);
+		}	
+	}
+}

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -45,6 +45,8 @@
         this.widgetId = widgetId;
     }
 
+    public String getId() { return widgetId; }
+    
     /**
      * Narrows the scope on the form-model to the member widget-field, and
      * narrows the scope on the object-model to the member xpath-context

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -38,12 +38,26 @@
     public JXPathBindingBase buildBinding(Element bindingElm, JXPathBindingManager.Assistant assistant)
             throws BindingException {
         try {
-            String widgetId = DomHelper.getAttribute(bindingElm, "id");
+            String widgetId = DomHelper.getAttribute(bindingElm, "id",null);
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
-            String xpath = DomHelper.getAttribute(bindingElm, "path");
+            String xpath = DomHelper.getAttribute(bindingElm, "path",null);
 
-            JXPathBindingBase[] childBindings = assistant.makeChildBindings(bindingElm);
+            JXPathBindingBase[] childBindings = new JXPathBindingBase[0];
 
+//          do inheritance
+            GroupJXPathBinding otherBinding = (GroupJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElm, childBindings);
+            
             GroupJXPathBinding groupBinding =
                 new GroupJXPathBinding(commonAtts, widgetId, xpath, childBindings);
             return groupBinding;

Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java?rev=289538&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.forms.binding;
+
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.commons.jxpath.JXPathContext;
+
+/**
+ * Dummy class cause binding doesn't accept null results from binding builders
+ * 
+ * @version $Id$
+ */
+public class ImportJXPathBinding extends JXPathBindingBase {
+
+	public ImportJXPathBinding() {
+		super(JXPathBindingBuilderBase.CommonAttributes.DEFAULT);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.cocoon.forms.binding.JXPathBindingBase#doLoad(org.apache.cocoon.forms.formmodel.Widget, org.apache.commons.jxpath.JXPathContext)
+	 */
+	public void doLoad(Widget frmModel, JXPathContext jxpc)
+			throws BindingException {
+		// dont do anything
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.cocoon.forms.binding.JXPathBindingBase#doSave(org.apache.cocoon.forms.formmodel.Widget, org.apache.commons.jxpath.JXPathContext)
+	 */
+	public void doSave(Widget frmModel, JXPathContext jxpc)
+			throws BindingException {
+//		 dont do anything
+
+	}
+
+}

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java?rev=289538&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.forms.binding;
+
+import org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant;
+import org.apache.cocoon.forms.binding.library.Library;
+import org.apache.cocoon.forms.binding.library.LibraryException;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Handles binding library imports
+ *
+ * @version $Id$
+ */
+public class ImportJXPathBindingBuilder extends JXPathBindingBuilderBase {
+
+	/* (non-Javadoc)
+	 * @see org.apache.cocoon.forms.binding.JXPathBindingBuilderBase#buildBinding(org.w3c.dom.Element, org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant)
+	 */
+	public JXPathBindingBase buildBinding(Element bindingElm,
+			Assistant assistant) throws BindingException {
+
+		Library lib = assistant.getContext().getLocalLibrary();
+		
+		String prefix = DomHelper.getAttribute(bindingElm, "prefix", null);
+		String uri = DomHelper.getAttribute(bindingElm, "uri", null);
+		
+		if(prefix==null || uri==null)
+			throw new BindingException("Import needs to specify both @uri and @prefix! (at "+DomHelper.getLocation(bindingElm)+")");
+		
+		try {
+			lib.includeAs(prefix,uri);
+		} catch(LibraryException e) {
+			throw new BindingException("Could not import library !(at "+DomHelper.getLocation(bindingElm)+")",e);
+		}
+		
+		return new ImportJXPathBinding();
+	}
+
+}

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -46,6 +46,9 @@
         this.className = className;
         this.addMethodName = addMethod;
     }
+    
+    public String getClassName() { return className; }
+    public String getAddMethodName() { return addMethodName; }
 
     /**
      * Do-nothing implementation of the interface.

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -48,8 +48,19 @@
             String className =
                 DomHelper.getAttribute(bindingElm, "classname", null);
             String addMethod =
-                DomHelper.getAttribute(bindingElm, "addmethod");
+                DomHelper.getAttribute(bindingElm, "addmethod",null);
 
+//          do inheritance
+            InsertBeanJXPathBinding otherBinding = (InsertBeanJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(className==null)
+            		className = otherBinding.getClassName();
+            	if(addMethod==null)
+            		addMethod = otherBinding.getAddMethodName();
+            }
+            
             return new InsertBeanJXPathBinding(commonAtts, className, addMethod);
         } catch (BindingException e) {
             throw e;

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -44,6 +44,8 @@
         super(commonAtts);
         this.template = domTemplate;
     }
+    
+    public DocumentFragment getTemplate() { return template; }
 
     /**
      * Do-nothing implementation of the interface.

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -57,8 +57,8 @@
 
             DocumentFragment domTemplate = null;
 
-            String src = bindingElm.getAttribute("src");
-            if (!src.equals("")) {
+            String src = DomHelper.getAttribute(bindingElm, "src", null);
+            if (src != null) {
                 ServiceManager manager = assistant.getServiceManager();
                 SourceResolver sourceResolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
                 Source source = null;
@@ -67,8 +67,8 @@
                     Document document = SourceUtil.toDOM(source);
                     Element element = document.getDocumentElement();
 
-                    String xpath = bindingElm.getAttribute("xpath");
-                    if (!xpath.equals("")) {
+                    String xpath = DomHelper.getAttribute(bindingElm, "xpath", null);
+                    if (xpath != null) {
                         XPathProcessor xpathProcessor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
                         try {
                             Node node = xpathProcessor.selectSingleNode(document, xpath);
@@ -89,13 +89,22 @@
                     }
                     manager.release(sourceResolver);
                 }
-            } else {
+            } else if(bindingElm.hasChildNodes()) {
                 domTemplate = bindingElm.getOwnerDocument().createDocumentFragment();
                 NodeList nested = bindingElm.getChildNodes();
                 int size = nested.getLength();
                 for (int i = 0; i < size; i++) {
                     domTemplate.appendChild(nested.item(i).cloneNode(true));
                 }
+            }
+            
+//          do inheritance
+            InsertNodeJXPathBinding otherBinding = (InsertNodeJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(domTemplate==null)
+            		domTemplate = otherBinding.getTemplate();
             }
 
             return new InsertNodeJXPathBinding(commonAtts, domTemplate);

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java Fri Sep 16 06:46:22 2005
@@ -16,12 +16,12 @@
 package org.apache.cocoon.forms.binding;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.avalon.framework.logger.LogEnabled;
 import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.forms.binding.library.Library;
 import org.apache.cocoon.forms.formmodel.Widget;
 import org.apache.cocoon.util.jxpath.DOMFactory;
 import org.apache.commons.jxpath.JXPathContext;
@@ -42,7 +42,12 @@
      * Avalon Logger to use in all subclasses.
      */
     private Logger logger;
-
+    
+    /**
+     * the local library, if this is the top binding
+     */
+    private Library localLibrary = null;
+    
     /**
      * Object holding the values of the common objects on all Bindings.
      */
@@ -66,7 +71,37 @@
             JXPathBindingBuilderBase.CommonAttributes commonAtts) {
         this.commonAtts = commonAtts;
     }
-
+    
+    public Library getLocalLibrary() {
+    	if(parent != null) {
+    		return parent.getLocalLibrary();
+    	} else {
+    		return localLibrary;
+    	}
+    }
+    public void setLocalLibary(Library lib) {
+    	this.localLibrary = lib;
+    }
+    
+    public boolean isValid() {
+    	if(this.localLibrary!=null) {
+    		if(parent!=null)
+    			return parent.isValid();
+    		return true; // no library used
+    	} else {
+    		try {
+    			return !this.localLibrary.dependenciesHaveChanged();
+    		} catch(Exception e) {
+    			logger.error("Error checking dependencies!",e);
+    			throw new RuntimeException("Error checking dependencies!",e);
+    		}
+    	}
+    }
+    
+    public JXPathBindingBuilderBase.CommonAttributes getCommonAtts() {
+    	return this.commonAtts;
+    }
+    
     /**
      * Gets source location of this binding.
      */
@@ -89,7 +124,14 @@
     }
 
     public Binding getClass(String id) {
-        Binding classBinding = null;
+    	
+    	Binding classBinding = null;
+    	
+    	try {
+    		if(this.localLibrary!=null && (classBinding = this.localLibrary.getBinding(id))!=null)
+    			return classBinding;
+    	} catch(Exception ignore) {}
+        
         if (classes != null) {
             // Query cache for class
             classBinding = (Binding)classes.get(id);
@@ -98,11 +140,14 @@
             // Query parent for class
             if (parent != null) {
                 classBinding = parent.getClass(id);
+                // dont cache, doesn't matter and makes things complicated with libraries
+                // **************************************
                 // Cache result
-                if (classes == null) {
+                /*if (classes == null) {
                     classes = new HashMap();
                 }
-                classes.put(id, classBinding);
+                classes.put(id, classBinding);*/
+                // **************************************
             } else {
                 throw new RuntimeException("Class \"" + id + "\" not found (" + getLocation() + ")");
             }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBuilderBase.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBuilderBase.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBuilderBase.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingBuilderBase.java Fri Sep 16 06:46:22 2005
@@ -50,6 +50,7 @@
             logger.debug("JXPathBindingBuilderBase got logger...");
         }
     }
+    
 
     /**
      * Makes the logger available to the subclasses.
@@ -135,6 +136,29 @@
             throw new BindingException("Error building binding defined at " + DomHelper.getLocation(bindingElm), e);
         }
      }
+    
+    public static CommonAttributes mergeCommonAttributes(CommonAttributes existing, CommonAttributes extra) {
+    	
+    	if (extra == null)
+    		return existing;
+    	
+    	Boolean leniency = null;
+    	if(existing.leniency==null)
+    		leniency = extra.leniency;
+    	else
+    		leniency = existing.leniency;
+    	
+    	String strLeniency = null;
+    	if(leniency != null)
+    		strLeniency = leniency.toString();
+    	
+    	String direction = existing.direction;
+    	if(extra.direction!=null) // was defined
+    		direction = extra.direction;
+    	
+    	
+    	return new CommonAttributes(extra.location,direction,strLeniency,extra.nsDeclarations);
+    }
 
      /**
       * CommonAttributes is a simple helper class for holding the distinct data
@@ -143,6 +167,10 @@
       */
      protected static class CommonAttributes{
 
+    	/**
+    	 * store direction (load/save enabledness) too for easier merging
+    	 */
+    	String direction;
         /**
          * Source location of this binding.
          */
@@ -169,9 +197,11 @@
 
         CommonAttributes(String location, String direction, String leniency, Map nsDeclarations){
             this(location, isLoadEnabled(direction), isSaveEnabled(direction), decideLeniency(leniency), nsDeclarations);
+            this.direction = direction;
         }
 
         CommonAttributes(String location, boolean loadEnabled, boolean saveEnabled, Boolean leniency, Map nsDeclarations){
+        	this.direction = null;
             this.location = location;
             this.loadEnabled = loadEnabled;
             this.saveEnabled = saveEnabled;
@@ -207,5 +237,6 @@
         private static Boolean decideLeniency(String leniency) {
             return BooleanUtils.toBooleanObject(leniency);
         }
+        
     }
 }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingManager.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingManager.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingManager.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JXPathBindingManager.java Fri Sep 16 06:46:22 2005
@@ -15,6 +15,9 @@
  */
 package org.apache.cocoon.forms.binding;
 
+import java.util.ArrayList;
+import java.util.Stack;
+
 import org.apache.avalon.framework.activity.Disposable;
 import org.apache.avalon.framework.activity.Initializable;
 import org.apache.avalon.framework.configuration.Configurable;
@@ -30,9 +33,14 @@
 import org.apache.avalon.framework.thread.ThreadSafe;
 import org.apache.cocoon.components.LifecycleHelper;
 import org.apache.cocoon.forms.CacheManager;
+import org.apache.cocoon.forms.binding.library.Library;
+import org.apache.cocoon.forms.binding.library.LibraryException;
+import org.apache.cocoon.forms.binding.library.LibraryManager;
+import org.apache.cocoon.forms.binding.library.LibraryManagerImpl;
 import org.apache.cocoon.forms.datatype.DatatypeManager;
 import org.apache.cocoon.forms.util.DomHelper;
 import org.apache.cocoon.forms.util.SimpleServiceSelector;
+import org.apache.cocoon.util.location.LocationAttributes;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
 import org.w3c.dom.Document;
@@ -63,6 +71,8 @@
     private CacheManager cacheManager;
 
 	private Context avalonContext;
+	
+	private LibraryManagerImpl libraryManager;
 
 	public void contextualize(Context context) throws ContextException {
 		this.avalonContext = context;
@@ -87,10 +97,22 @@
                                        this.avalonContext,
                                        this.manager,
                                        configuration.getChild("bindings"));
+        
+        libraryManager = new LibraryManagerImpl();
+        libraryManager.setBindingManager(this);
+        LifecycleHelper.setupComponent(libraryManager,
+        								getLogger(),
+        								this.avalonContext,
+        								this.manager,
+        								configuration.getChild("library"));
     }
 
     public Binding createBinding(Source source) throws BindingException {
         Binding binding = (Binding) this.cacheManager.get(source, PREFIX);
+        
+        if (binding != null && !binding.isValid())
+        	binding = null; //invalidate
+        
         if (binding == null) {
             try {
                 InputSource is = new InputSource(source.getInputStream());
@@ -146,7 +168,7 @@
         }
     }
 
-    private Assistant getBuilderAssistant() {
+    public Assistant getBuilderAssistant() {
         return new Assistant();
     }
 
@@ -177,7 +199,10 @@
      */
     public class Assistant {
 
-        private JXPathBindingBuilderBase getBindingBuilder(String bindingType)
+    	private BindingBuilderContext context = new BindingBuilderContext();
+    	private Stack contextStack = new Stack();
+    	
+    	private JXPathBindingBuilderBase getBindingBuilder(String bindingType)
                 throws BindingException {
             try {
                 return (JXPathBindingBuilderBase) bindingBuilderSelector
@@ -197,30 +222,141 @@
                 Element configElm) throws BindingException {
             String bindingType = configElm.getLocalName();
             JXPathBindingBuilderBase bindingBuilder = getBindingBuilder(bindingType);
+            
+            boolean flag = false;
+            if(context.getLocalLibrary() == null) {
+            	Library lib = new Library(libraryManager);
+            	context.setLocalLibrary(lib);
+            	lib.setAssistant(getBuilderAssistant());
+            	lib.setSourceURI(LocationAttributes.getURI(configElm));
+            	flag = true;
+            }
+            
+            if(context.getLocalLibrary()!=null 
+            		&& configElm.hasAttribute("extends")) {
+        		try {
+        			context.setSuperBinding(context.getLocalLibrary().getBinding(configElm.getAttribute("extends")));
+        			
+        		} catch(LibraryException e) {
+        			throw new RuntimeException("Error extending binding! (at "+DomHelper.getLocation(configElm)+")",e);
+        		}
+        	} else {
+        		context.setSuperBinding(null);
+        	}
+            
             JXPathBindingBase childBinding = bindingBuilder.buildBinding(configElm, this);
+            
+            if(flag && childBinding != null) {
+            	childBinding.setLocalLibary(context.getLocalLibrary());
+            }
+            
+            // this might get called unnecessarily, but solves issues with the libraries
+            if(childBinding != null)
+            	childBinding.enableLogging(getLogger());
+            
+            
             return childBinding;
         }
 
+        private JXPathBindingBase[] mergeBindings(JXPathBindingBase[] existing, JXPathBindingBase[] extra) {
+        	
+        	if(existing == null || existing.length == 0)
+        		return extra;
+        	
+        	if(extra == null || extra.length == 0)
+        		return existing;
+        	
+        	// have to do it the stupid painter way..
+        	ArrayList list = new ArrayList(existing.length);
+        	for(int i=0; i<existing.length; i++)
+        		list.add(existing[i]);
+        	
+        	for(int i=0; i<extra.length; i++) {
+        		if(extra[i].getId()==null)
+        			list.add(extra[i]);
+        		else {
+        			// try to replace existing one
+        			boolean match = false;
+        			for(int j=0; j<list.size(); j++) {
+        				if(extra[i].getId().equals(((JXPathBindingBase)list.get(j)).getId())) {
+        					list.set(j,extra[i]);
+        					match = true;
+        					break; // stop searching
+        				}
+        			}
+        			// if no match, just add
+        			if(!match)
+        				list.add(extra[i]);
+        		}
+        	}	
+        	
+        	return (JXPathBindingBase[])list.toArray(new JXPathBindingBase[0]);
+        }
+        
+        /**
+         * proxy for compatibility
+         * 
+         */
+        public JXPathBindingBase[] makeChildBindings(Element parentElement) throws BindingException {
+        	return makeChildBindings(parentElement,new JXPathBindingBase[0]);
+        }
+        
         /**
          * Makes an array of childBindings for the child-elements of the
          * provided configuration element.
          */
-        public JXPathBindingBase[] makeChildBindings(Element parentElement)
+        public JXPathBindingBase[] makeChildBindings(Element parentElement, JXPathBindingBase[] existingBindings)
                 throws BindingException {
+        	if (existingBindings == null)
+        		existingBindings = new JXPathBindingBase[0];
+        	
             if (parentElement != null) {
                 Element[] childElements = DomHelper.getChildElements(
                         parentElement, BindingManager.NAMESPACE);
                 if (childElements.length > 0) {
                     JXPathBindingBase[] childBindings = new JXPathBindingBase[childElements.length];
                     for (int i = 0; i < childElements.length; i++) {
+                    	
+                    	pushContext();
+                    	context.setSuperBinding(null);
+                    	
+                    	String id = DomHelper.getAttribute(childElements[i], "id", null);
+                    	String path = DomHelper.getAttribute(childElements[i], "path", null);
+                    	if(context.getLocalLibrary()!=null && childElements[i].getAttribute("extends")!=null) {
+                    		try {
+                    			context.setSuperBinding(context.getLocalLibrary().getBinding(childElements[i].getAttribute("extends")));
+                    			
+                    			if(context.getSuperBinding() == null) // not found in library
+                    				context.setSuperBinding(getBindingByIdOrPath(id,path,existingBindings));
+                    			
+                    		} catch(LibraryException e) {
+                    			throw new RuntimeException("Error extending binding! (at "+DomHelper.getLocation(childElements[i])+")",e);
+                    		}
+                    	}
+                    	
                         childBindings[i] = getBindingForConfigurationElement(childElements[i]);
+                        
+                        popContext();
                     }
-                    return childBindings;
+                    return mergeBindings(existingBindings,childBindings);
                 }
             }
-            return null;
+            return existingBindings;
         }
 
+        private JXPathBindingBase getBindingByIdOrPath(String id, String path, JXPathBindingBase[] bindings) {
+            	String name = id;
+            	if(name == null) {
+            		name = "Context:"+path;
+            	}
+            		
+            	for(int i=0; i<bindings.length; i++) {
+            		if(name.equals(bindings[i].getId()))
+            			return bindings[i];
+            	}
+            	return null;
+        }
+        
         public DatatypeManager getDatatypeManager() {
             return datatypeManager;
         }
@@ -228,5 +364,26 @@
         public ServiceManager getServiceManager() {
             return manager;
         }
+        
+        public LibraryManager getLibraryManager() {
+        	return libraryManager;
+        }
+        
+        public BindingBuilderContext getContext() {
+        	return this.context;
+        }
+        private void pushContext() {
+        	BindingBuilderContext c = new BindingBuilderContext(context);
+        	contextStack.push(context);
+        	context = c;
+        }
+        private void popContext() {
+        	if(!contextStack.empty()) {
+        		context = (BindingBuilderContext)contextStack.pop();
+        	} else {
+        		context = new BindingBuilderContext();
+        	}
+        }
+        
     }
 }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -42,6 +42,7 @@
     private final Function loadScript;
     private final Function saveScript;
     private final Scriptable childBindings;
+    private final Map childBindingsMap;
     
     final static String[] LOAD_PARAMS = { "widget", "jxpathPointer", "jxpathContext", "childBindings" };
     final static String[] SAVE_PARAMS = { "widget", "jxpathPointer", "jxpathContext", "childBindings" };
@@ -60,9 +61,17 @@
         for(Iterator iter = childBindings.values().iterator(); iter.hasNext(); ) {
         	    ((Binding)iter.next()).setParent(this);
         }
-
+        
+        this.childBindingsMap = childBindings;
         this.childBindings = new ScriptableMap(childBindings);
     }
+    
+    public String getPath() { return path; }
+    public String getId() { return id; }
+    public Context getContext() { return avalonContext; }
+    public Function getLoadScript() { return loadScript; }
+    public Function getSaveScript() { return saveScript; }
+    public Map getChildBindingsMap() { return childBindingsMap; }
 
     public void doLoad(Widget frmModel, JXPathContext jctx) {
         if (this.loadScript != null) {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/JavaScriptJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -17,6 +17,7 @@
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.avalon.framework.context.Context;
@@ -79,49 +80,72 @@
         try {
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(element);
 
-            String id = DomHelper.getAttribute(element, "id");
-            String path = DomHelper.getAttribute(element, "path");
+            String id = DomHelper.getAttribute(element, "id", null);
+            String path = DomHelper.getAttribute(element, "path", null);
 
+            JavaScriptJXPathBinding otherBinding = (JavaScriptJXPathBinding)assistant.getContext().getSuperBinding();
+            
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(id==null)
+            		id=otherBinding.getId();
+            	if(path==null)
+            		path=otherBinding.getPath();
+            }
+            
             // Build load script
             Function loadScript = null;
             if (commonAtts.loadEnabled) {
+                if (otherBinding != null)
+                	loadScript = otherBinding.getLoadScript();
+            	
                 Element loadElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "load-form");
-                if (loadElem == null) {
-                    throw new BindingException("Element \"load-form\" is missing (" +
-                        DomHelper.getLocation(element) + ")");
+                if (loadElem != null) {
+                	loadScript = JavaScriptHelper.buildFunction(loadElem, "loadForm", JavaScriptJXPathBinding.LOAD_PARAMS);
                 }
-                loadScript = JavaScriptHelper.buildFunction(loadElem, "loadForm", JavaScriptJXPathBinding.LOAD_PARAMS);
             }
 
             // Build save script
             Function saveScript = null;
             if (commonAtts.saveEnabled) {
+            	if (otherBinding != null)
+            		saveScript = otherBinding.getSaveScript();
+            	
                 Element saveElem = DomHelper.getChildElement(element, BindingManager.NAMESPACE, "save-form");
-                if (saveElem == null) {
-                    throw new BindingException("Element \"save-form\" is missing (" +
-                        DomHelper.getLocation(element) + ")");
+                if (saveElem != null) {
+                	saveScript = JavaScriptHelper.buildFunction(saveElem, "saveForm", JavaScriptJXPathBinding.SAVE_PARAMS);
                 }
-                saveScript = JavaScriptHelper.buildFunction(saveElem, "saveForm", JavaScriptJXPathBinding.SAVE_PARAMS);
             }
 
             // Build child bindings
-            Map childBindings;
+            Map childBindings = new HashMap();
+            
+            if (otherBinding != null) {
+            	Map otherChildren = otherBinding.getChildBindingsMap();
+            	Iterator it = otherChildren.entrySet().iterator();
+            	while(it.hasNext()) {
+            		Map.Entry entry = (Map.Entry)it.next();
+            		childBindings.put(entry.getKey(),entry.getValue());
+            	}
+            }
+            
             Element[] children = DomHelper.getChildElements(element, BindingManager.NAMESPACE, "child-binding");
-            if (children.length == 0) {
-                childBindings = Collections.EMPTY_MAP;
-            } else {
-                childBindings = new HashMap();
+            if (children.length != 0) {
                 for (int i = 0; i < children.length; i++) {
                     Element child = children[i];
 
                     // Get the binding name and check its uniqueness
                     String name = DomHelper.getAttribute(child, "name");
+                    
+                    JXPathBindingBase[] otherBindings = null;
                     if (childBindings.containsKey(name)) {
-                        throw new BindingException("Duplicate name '" + name + "' at " + DomHelper.getLocation(child));
+                        //throw new BindingException("Duplicate name '" + name + "' at " + DomHelper.getLocation(child));
+                    	otherBindings = ((ComposedJXPathBindingBase)childBindings.get(name)).getChildBindings();
                     }
-
+                    
                     // Build the child binding
-                    JXPathBindingBase[] bindings = assistant.makeChildBindings(child);
+                    JXPathBindingBase[] bindings = assistant.makeChildBindings(child,otherBindings);
                     if (bindings == null) {
                         bindings = new JXPathBindingBase[0];
                     }

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -15,8 +15,11 @@
  */
 package org.apache.cocoon.forms.binding;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Locale;
 
 import org.apache.avalon.framework.logger.Logger;
@@ -53,6 +56,13 @@
         this.convertor = convertor;
         this.convertorLocale = convertorLocale;
     }
+    
+    public String getId() { return multiValueId; }
+    public String getMultiValuePath() { return multiValuePath; }
+    public String getRowPath() { return rowPath; }
+    public ComposedJXPathBindingBase getUpdateBinding() { return (ComposedJXPathBindingBase)updateBinding; }
+    public Convertor getConvertor() { return convertor; }
+    public Locale getLocale() { return convertorLocale; }
 
     public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException {
         Widget widget = selectWidget(frmModel,this.multiValueId);
@@ -104,7 +114,23 @@
         JXPathContext multiValueContext = jctx.getRelativeContext(jctx.createPath(this.multiValuePath));
 
         // Delete all that is already present
-        multiValueContext.removeAll(this.rowPath);
+        
+        // Unfortunately the following statement doesn't work (it doesn't removes all elements from the 
+        // list because of a bug in JXPath) so I had to work out another immediate solution
+        //multiValueContext.removeAll(this.rowPath);
+        
+        Iterator rowPointers = multiValueContext.iteratePointers(this.rowPath);
+        List l = new ArrayList();
+        while( rowPointers.hasNext() )
+        {
+            Pointer p = (Pointer)rowPointers.next();
+            l.add(p.asPath());
+        }
+        Collections.sort(l);
+        for( int i = l.size()-1; i >= 0; i-- )
+        {
+            multiValueContext.removePath((String)l.get(i));
+        }
 
         boolean update = false;
 

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/MultiValueJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -49,26 +49,47 @@
         try {
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElem);
 
-            String multiValueId = DomHelper.getAttribute(bindingElem, "id");
-            String parentPath = DomHelper.getAttribute(bindingElem, "parent-path");
-            String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
-
-            Element updateWrapElement =
-                DomHelper.getChildElement(bindingElem, BindingManager.NAMESPACE, "on-update");
-            JXPathBindingBase[] updateBindings = assistant.makeChildBindings(updateWrapElement);
+            String multiValueId = DomHelper.getAttribute(bindingElem, "id", null);
+            String parentPath = DomHelper.getAttribute(bindingElem, "parent-path", null);
+            String rowPath = DomHelper.getAttribute(bindingElem, "row-path", null);
 
+            
             Convertor convertor = null;
             Locale convertorLocale = Locale.US;
             Element convertorEl = DomHelper.getChildElement(bindingElem, Constants.DEFINITION_NS, "convertor");
             if (convertorEl != null) {
-                String datatype = DomHelper.getAttribute(convertorEl, "datatype");
-                String localeStr = convertorEl.getAttribute("locale");
-                if (localeStr != null && !localeStr.equals("")) {
+                String datatype = DomHelper.getAttribute(convertorEl, "datatype", null);
+                String localeStr = DomHelper.getAttribute(convertorEl, "locale", null);
+                if (localeStr != null) {
                     convertorLocale = I18nUtils.parseLocale(localeStr);
                 }
 
                 convertor = assistant.getDatatypeManager().createConvertor(datatype, convertorEl);
             }
+            
+            MultiValueJXPathBinding existingBinding = (MultiValueJXPathBinding)assistant.getContext().getSuperBinding();
+            JXPathBindingBase[] existingBindings = new JXPathBindingBase[0]; 
+            if(existingBinding != null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(existingBinding.getCommonAtts(),commonAtts);
+            	existingBindings = existingBinding.getUpdateBinding().getChildBindings();
+            	
+            	if(multiValueId == null)
+            		multiValueId = existingBinding.getId();
+            	if(parentPath == null)
+            		parentPath = existingBinding.getMultiValuePath();
+            	if(rowPath == null)
+            		rowPath = existingBinding.getRowPath();
+            	
+            	if(convertor == null) {
+            		convertor = existingBinding.getConvertor();
+            		convertorLocale = existingBinding.getLocale();
+            	}	
+            }
+            
+            Element updateWrapElement =
+                DomHelper.getChildElement(bindingElem, BindingManager.NAMESPACE, "on-update");
+            JXPathBindingBase[] updateBindings = assistant.makeChildBindings(updateWrapElement,existingBindings);
+
 
             return new MultiValueJXPathBinding( commonAtts, multiValueId, parentPath, rowPath,
                                                 updateBindings, convertor, convertorLocale);

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -47,6 +47,8 @@
         this.widgetId = widgetId;
         this.classBinding = null;
     }
+    
+    public String getId() { return widgetId; }
 
     /**
      * Recursively resolves references.

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/NewJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -38,11 +38,23 @@
     public JXPathBindingBase buildBinding(Element bindingElm, JXPathBindingManager.Assistant assistant)
             throws BindingException {
         try {
-            String widgetId = DomHelper.getAttribute(bindingElm, "id");
+            String widgetId = DomHelper.getAttribute(bindingElm, "id", null);
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
 
-            JXPathBindingBase[] childBindings = assistant.makeChildBindings(bindingElm);
+            JXPathBindingBase[] childBindings = new JXPathBindingBase[0];
 
+//          do inheritance
+            NewJXPathBinding otherBinding = (NewJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElm,childBindings);
+            
             NewJXPathBinding newBinding = new NewJXPathBinding(commonAtts, widgetId, childBindings);
             return newBinding;
         } catch (BindingException 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=289538&r1=289537&r2=289538&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 Fri Sep 16 06:46:22 2005
@@ -81,13 +81,26 @@
             this.deleteRowBinding = null;
         }
 
-        this.identityBinding = new ComposedJXPathBindingBase(
+        
+        if (identityBindings != null) {
+        	
+        	this.identityBinding = new ComposedJXPathBindingBase(
                                        JXPathBindingBuilderBase.CommonAttributes.DEFAULT,
                                        identityBindings);
-        if (this.identityBinding != null) {
-            this.identityBinding.setParent(this);
+        	this.identityBinding.setParent(this);
         }
+        else
+        	this.identityBinding = null;
     }
+    
+    public String getId() { return repeaterId; }
+    public String getRepeaterPath() { return repeaterPath; }
+    public String getRowPath() { return rowPath; }
+    public String getInsertRowPath() { return rowPathForInsert; }
+    public ComposedJXPathBindingBase getRowBinding() { return (ComposedJXPathBindingBase)rowBinding; }
+    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
@@ -331,6 +344,10 @@
     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;
+        
         JXPathBindingBase[] childBindings = this.identityBinding.getChildBindings();
         if (childBindings != null) {
             int size = childBindings.length;

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=289538&r1=289537&r2=289538&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 Fri Sep 16 06:46:22 2005
@@ -68,29 +68,57 @@
             CommonAttributes commonAtts =
                 JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
 
-            String repeaterId = DomHelper.getAttribute(bindingElm, "id");
+            String repeaterId = DomHelper.getAttribute(bindingElm, "id", null);
             String parentPath =
-                DomHelper.getAttribute(bindingElm, "parent-path");
-            String rowPath = DomHelper.getAttribute(bindingElm, "row-path");
+                DomHelper.getAttribute(bindingElm, "parent-path", null);
+            String rowPath = DomHelper.getAttribute(bindingElm, "row-path", null);
             String rowPathForInsert =
                 DomHelper.getAttribute(bindingElm, "row-path-insert", rowPath);
+            
+//          do inheritance
+            RepeaterJXPathBinding otherBinding = (RepeaterJXPathBinding)assistant.getContext().getSuperBinding();
+            JXPathBindingBase[] existingOnBind = null;
+            JXPathBindingBase[] existingOnDelete = null;
+            JXPathBindingBase[] existingOnInsert = null;
+            JXPathBindingBase[] existingIdentity = null;
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(repeaterId==null)
+            		repeaterId = otherBinding.getId();
+            	if(parentPath==null)
+            		parentPath = otherBinding.getRepeaterPath();
+            	if(rowPath==null)
+            		rowPath = otherBinding.getRowPath();
+            	if(rowPathForInsert==null)
+            		rowPathForInsert = otherBinding.getInsertRowPath();
+            	
+            	if(otherBinding.getRowBinding() != null)
+            		existingOnBind = otherBinding.getRowBinding().getChildBindings();
+            	if(otherBinding.getDeleteRowBinding() != null)
+            		existingOnDelete = otherBinding.getDeleteRowBinding().getChildBindings();
+            	if(otherBinding.getIdentityBinding() != null)
+            		existingIdentity = otherBinding.getIdentityBinding().getChildBindings();
+            	if(otherBinding.getInsertRowBinding() != null)
+            		existingOnInsert = new JXPathBindingBase[] { otherBinding.getInsertRowBinding() };
+            }
 
             Element childWrapElement =
                 DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "on-bind");
-            if (childWrapElement == null) {
-                throw new BindingException(
-                      "RepeaterBinding misses '<on-bind>' child definition. " +
-                      DomHelper.getLocation(bindingElm));
-            }
+            
             JXPathBindingBase[] childBindings =
-                assistant.makeChildBindings(childWrapElement);
+                assistant.makeChildBindings(childWrapElement,existingOnBind);
+            if(childBindings == null)
+            	childBindings = existingOnBind;
 
             Element deleteWrapElement = DomHelper.getChildElement(bindingElm,
                     BindingManager.NAMESPACE, "on-delete-row");
             JXPathBindingBase[] deleteBindings = null;
             if (deleteWrapElement != null) {
                 deleteBindings =
-                    assistant.makeChildBindings(deleteWrapElement);
+                    assistant.makeChildBindings(deleteWrapElement,existingOnDelete);
+                if(deleteBindings == null)
+                	deleteBindings = existingOnDelete;
             }
 
             Element insertWrapElement = DomHelper.getChildElement(bindingElm,
@@ -98,10 +126,12 @@
             JXPathBindingBase insertBinding = null;
             if (insertWrapElement != null) {
                 insertBinding =
-                    assistant.makeChildBindings(insertWrapElement)[0];
+                    assistant.makeChildBindings(insertWrapElement,existingOnInsert)[0];
                     // TODO: we now safely take only the first element here,
                     // but we should in fact send out a warning to the log 
                     // if more were available!
+                if(insertBinding == null && existingOnInsert != null)
+                	insertBinding = existingOnInsert[0];
             }
 
             Element identityWrapElement = DomHelper.getChildElement(bindingElm,
@@ -111,7 +141,7 @@
                 // TODO: we can only handle ValueJXPathBinding at the moment:
                 // http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107906438632484&w=4
                 identityBinding =
-                    assistant.makeChildBindings(identityWrapElement);
+                    assistant.makeChildBindings(identityWrapElement,existingIdentity);
                 if (identityBinding != null) {
                     for (int i = 0; i < identityBinding.length;i++) {
                         if (!(identityBinding[i] instanceof ValueJXPathBinding)) {
@@ -122,6 +152,8 @@
                                     " if you want to know more on this.");
                         }
                     }
+                } else {
+                	identityBinding = existingIdentity;
                 }
             }
 

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -41,6 +41,9 @@
         this.name = attName;
         this.value = attValue;
     }
+    
+    public String getId() { return name; }
+    public String getValue() { return value; }
 
     /**
      * Do-Nothing implementation.

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SetAttributeJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -45,9 +45,20 @@
             CommonAttributes commonAtts =
                 JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
 
-            String attName = DomHelper.getAttribute(bindingElm, "name");
-            String attValue = DomHelper.getAttribute(bindingElm, "value");
+            String attName = DomHelper.getAttribute(bindingElm, "name", null);
+            String attValue = DomHelper.getAttribute(bindingElm, "value", null);
 
+            // do inheritance
+            SetAttributeJXPathBinding otherBinding = (SetAttributeJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(attName==null)
+            		attName = otherBinding.getId();
+            	if(attValue==null)
+            		attValue = otherBinding.getValue();
+            }
+            
             SetAttributeJXPathBinding attBinding =
                 new SetAttributeJXPathBinding(commonAtts, attName, attValue);
             return attBinding;

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -56,6 +56,13 @@
         this.clearOnLoad = clearOnLoad;
         this.deleteIfEmpty = deleteIfEmpty;
     }
+    
+    public String getId() { return repeaterId; }
+    public String getRepeaterPath() { return repeaterPath; }
+    public String getRowPath() { return rowPath; }
+    public boolean getClearOnLoad() { return clearOnLoad; }
+    public boolean getDeleteIfEmpty() { return deleteIfEmpty; }
+    public JXPathBindingBase[] getChildBindings() { return ((ComposedJXPathBindingBase)rowBinding).getChildBindings(); }
 
     public void doLoad(Widget frmModel, JXPathContext jctx)
             throws BindingException {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/SimpleRepeaterJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -41,17 +41,36 @@
             CommonAttributes commonAtts =
                 JXPathBindingBuilderBase.getCommonAttributes(bindingElem);
 
-            String repeaterId = DomHelper.getAttribute(bindingElem, "id");
+            String repeaterId = DomHelper.getAttribute(bindingElem, "id", null);
             String parentPath = DomHelper.getAttribute(
-                    bindingElem, "parent-path");
-            String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
+                    bindingElem, "parent-path", null);
+            String rowPath = DomHelper.getAttribute(bindingElem, "row-path", null);
             boolean clearOnLoad = DomHelper.getAttributeAsBoolean(
                     bindingElem, "clear-before-load", true);
             boolean deleteIfEmpty = DomHelper.getAttributeAsBoolean(
                     bindingElem, "delete-parent-if-empty", false);
 
-            JXPathBindingBase[] childBindings =
-                assistant.makeChildBindings(bindingElem);
+            JXPathBindingBase[] childBindings = null;
+            
+            // do inheritance
+            SimpleRepeaterJXPathBinding otherBinding = (SimpleRepeaterJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(parentPath==null)
+            		parentPath = otherBinding.getRepeaterPath();
+            	if(repeaterId==null)
+            		repeaterId = otherBinding.getId();
+            	if(rowPath==null)
+            		rowPath = otherBinding.getRowPath();
+            	if(!bindingElem.hasAttribute("clear-before-load"))
+            		clearOnLoad = otherBinding.getClearOnLoad();
+            	if(!bindingElem.hasAttribute("delete-parent-if-empty"))
+            		deleteIfEmpty = otherBinding.getDeleteIfEmpty();
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElem, childBindings);
 
             return new SimpleRepeaterJXPathBinding(commonAtts, repeaterId,
                     parentPath, rowPath, clearOnLoad, deleteIfEmpty,

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -44,6 +44,8 @@
         super(commonAtts, xpath, childBindings);
         this.widgetId = widgetId;
     }
+    
+    public String getId() { return widgetId; }
 
     /**
      * Narrows the scope on the form-model to the member widget-field, and

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/StructJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -44,8 +44,22 @@
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
             String xpath = DomHelper.getAttribute(bindingElm, "path");
 
-            JXPathBindingBase[] childBindings = assistant.makeChildBindings(bindingElm);
+            JXPathBindingBase[] childBindings = new JXPathBindingBase[0];
 
+//          do inheritance
+            StructJXPathBinding otherBinding = (StructJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElm,childBindings);
+            
             StructJXPathBinding structBinding =
                 new StructJXPathBinding(commonAtts, widgetId, xpath, childBindings);
             return structBinding;

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -67,6 +67,16 @@
         this.clearOnLoad = clearOnLoad;
         this.deleteIfEmpty = deleteIfEmpty;
     }
+    
+    public String getId() { return repeaterId; }
+    public String getRepeaterPath() { return repeaterPath; }
+    public String getRowPath() { return rowPath; }
+    public String getRowPathInsert() { return rowPathInsert; }
+    public boolean getVirtualRows() { return virtualRows; }
+    public boolean getClearOnLoad() { return clearOnLoad; }
+    public boolean getDeleteIfEmpty() { return deleteIfEmpty; }
+    public JXPathBindingBase[] getChildBindings() { return ((ComposedJXPathBindingBase)rowBinding).getChildBindings(); }
+    public JXPathBindingBase[] getInsertChildBindings() { return ((ComposedJXPathBindingBase)insertRowBinding).getChildBindings(); }
 
     public void doLoad(Widget frmModel, JXPathContext jctx) throws BindingException {
         // (There should be a general widget type checker for all the bindings to use,

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/TempRepeaterJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -40,10 +40,10 @@
         try {
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElem);
 
-            String repeaterId = DomHelper.getAttribute(bindingElem, "id");
+            String repeaterId = DomHelper.getAttribute(bindingElem, "id", null);
             String parentPath = DomHelper.getAttribute(bindingElem,
-                    "parent-path");
-            String rowPath = DomHelper.getAttribute(bindingElem, "row-path");
+                    "parent-path", null);
+            String rowPath = DomHelper.getAttribute(bindingElem, "row-path", null);
             String rowPathInsert = DomHelper.getAttribute(bindingElem,
                     "row-path-insert", rowPath);
             boolean virtualRows = DomHelper.getAttributeAsBoolean(
@@ -53,17 +53,42 @@
             boolean deleteIfEmpty = DomHelper.getAttributeAsBoolean(
                     bindingElem, "delete-parent-if-empty", false);
 
+            JXPathBindingBase[] insertBindings = null;
+            JXPathBindingBase[] childBindings = null;
+            
+            // do inheritance
+            TempRepeaterJXPathBinding otherBinding = (TempRepeaterJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	insertBindings = otherBinding.getInsertChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(parentPath==null)
+            		parentPath = otherBinding.getRepeaterPath();
+            	if(repeaterId==null)
+            		repeaterId = otherBinding.getId();
+            	if(rowPath==null)
+            		rowPath = otherBinding.getRowPath();
+            	if(rowPathInsert==null)
+            		rowPathInsert = otherBinding.getRowPathInsert();
+            	if(!bindingElem.hasAttribute("virtual-rows"))
+            		clearOnLoad = otherBinding.getVirtualRows();
+            	if(!bindingElem.hasAttribute("clear-before-load"))
+            		clearOnLoad = otherBinding.getClearOnLoad();
+            	if(!bindingElem.hasAttribute("delete-parent-if-empty"))
+            		deleteIfEmpty = otherBinding.getDeleteIfEmpty();
+            }
+            
             Element childWrapElement = DomHelper.getChildElement(
                     bindingElem, BindingManager.NAMESPACE, "on-bind");
-            JXPathBindingBase[] childBindings =
-                    assistant.makeChildBindings(childWrapElement);
+            childBindings = assistant.makeChildBindings(childWrapElement,childBindings);
 
             Element insertWrapElement = DomHelper.getChildElement(bindingElem,
                     BindingManager.NAMESPACE, "on-insert-row");
-            JXPathBindingBase[] insertBindings = null;
+            
             if (insertWrapElement != null) {
                 insertBindings =
-                    assistant.makeChildBindings(insertWrapElement);
+                    assistant.makeChildBindings(insertWrapElement,insertBindings);
             }
             return new TempRepeaterJXPathBinding(commonAtts, repeaterId,
                     parentPath, rowPath, rowPathInsert, virtualRows,

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -48,6 +48,9 @@
         this.widgetId = widgetId;
         this.xpath = xpath;
     }
+    
+    public String getXPath() { return xpath; }
+    public String getId() { return widgetId; }
 
     /**
      * Narrows the scope on the form-model to the member widget-field, and

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/UnionJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -37,12 +37,26 @@
     public JXPathBindingBase buildBinding(Element bindingElm, JXPathBindingManager.Assistant assistant)
             throws BindingException {
         try {
-            String widgetId = DomHelper.getAttribute(bindingElm, "id");
+            String widgetId = DomHelper.getAttribute(bindingElm, "id", null);
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
-            String xpath = DomHelper.getAttribute(bindingElm, "path");
+            String xpath = DomHelper.getAttribute(bindingElm, "path", null);
 
-            JXPathBindingBase[] childBindings = assistant.makeChildBindings(bindingElm);
+            JXPathBindingBase[] childBindings = new JXPathBindingBase[0];
 
+//          do inheritance
+            UnionJXPathBinding otherBinding = (UnionJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElm,childBindings);
+            
             UnionJXPathBinding unionBinding = new UnionJXPathBinding(commonAtts, widgetId, xpath, childBindings);
             return unionBinding;
         } catch (BindingException e) {

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBinding.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBinding.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBinding.java Fri Sep 16 06:46:22 2005
@@ -75,6 +75,9 @@
         this.convertor = convertor;
         this.convertorLocale = convertorLocale;
     }
+    
+    public String getId() { return fieldId; }
+    public ComposedJXPathBindingBase getUpdateBinding() { return (ComposedJXPathBindingBase)updateBinding; }
 
     /**
      * Actively performs the binding from the ObjectModel wrapped in a jxpath

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBindingBuilder.java?rev=289538&r1=289537&r2=289538&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBindingBuilder.java (original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/binding/ValueJXPathBindingBuilder.java Fri Sep 16 06:46:22 2005
@@ -49,25 +49,45 @@
 
         try {
             CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
-            String xpath = DomHelper.getAttribute(bindingElm, "path");
-            String widgetId = DomHelper.getAttribute(bindingElm, "id");
-
-            Element updateWrapElement =
-                DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "on-update");
-            JXPathBindingBase[] updateBindings = assistant.makeChildBindings(updateWrapElement);
+            String xpath = DomHelper.getAttribute(bindingElm, "path", null);
+            String widgetId = DomHelper.getAttribute(bindingElm, "id", null);
 
             Convertor convertor = null;
             Locale convertorLocale = Locale.US;
             Element convertorEl = DomHelper.getChildElement(bindingElm, Constants.DEFINITION_NS, "convertor");
             if (convertorEl != null) {
                 String datatype = DomHelper.getAttribute(convertorEl, "datatype");
-                String localeStr = convertorEl.getAttribute("locale");
-                if (localeStr != null && !localeStr.equals("")) {
+                String localeStr = DomHelper.getAttribute(convertorEl, "locale", null);
+                if (localeStr != null) {
                     convertorLocale = I18nUtils.parseLocale(localeStr);
                 }
 
                 convertor = assistant.getDatatypeManager().createConvertor(datatype, convertorEl);
             }
+            
+            // do inheritance
+            ValueJXPathBinding otherBinding = (ValueJXPathBinding)assistant.getContext().getSuperBinding();
+            JXPathBindingBase[] existingUpdateBindings = null;
+            if(otherBinding!=null) {
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+            	if(widgetId==null)
+            		widgetId = otherBinding.getId();
+            	if(convertor==null)
+            		convertor = otherBinding.getConvertor();
+            	if(convertorLocale==null)
+            		convertorLocale = otherBinding.getConvertorLocale();
+            	if(convertorLocale==null)
+            		convertorLocale = otherBinding.getConvertorLocale();
+            	
+            	existingUpdateBindings = otherBinding.getUpdateBinding().getChildBindings();
+            }
+            
+            Element updateWrapElement =
+                DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "on-update");
+            JXPathBindingBase[] updateBindings = assistant.makeChildBindings(updateWrapElement,existingUpdateBindings);
 
             ValueJXPathBinding fieldBinding =
                     new ValueJXPathBinding(commonAtts,