cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [85/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 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.avalon.framework.CascadingRuntimeException;
+import org.apache.cocoon.forms.binding.JXPathBindingBuilderBase.CommonAttributes;
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.commons.jxpath.AbstractFactory;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.Pointer;
+
+/**
+ * ContextJXPathBinding provides an implementation of a {@link Binding}
+ * that narrows the binding scope to some xpath-context on the target
+ * objectModel to load and save from.
+ *
+ * @version $Id: ContextJXPathBinding.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class ContextJXPathBinding extends ComposedJXPathBindingBase {
+
+    /**
+     * the relative contextPath for the sub-bindings of this context
+     */
+    private final String xpath;
+    
+    /**
+     * The name of a factory class for building intermediate elements. Must implement 
+     * {@link org.apache.commons.jxpath.AbstractFactory}.
+     */
+    private AbstractFactory factory;
+
+    /**
+     * Constructs ContextJXPathBinding for the specified xpath sub-context
+     */
+    public ContextJXPathBinding(CommonAttributes commonAtts, String contextPath, JXPathBindingBase[] childBindings) {
+        super(commonAtts, childBindings);
+        this.xpath = contextPath;
+    }
+
+    /**
+     * Constructs ContextJXPathBinding for the specified xpath sub-context and optional JXPath factory class.
+     */
+    public ContextJXPathBinding(JXPathBindingBuilderBase.CommonAttributes commonAtts, String contextPath, String factoryClassName, JXPathBindingBase[] childBindings) {
+        super(commonAtts, childBindings);
+        this.xpath = contextPath;
+        if (factoryClassName != null) {
+            try {
+                this.factory = (AbstractFactory) ClassUtils.newInstance(factoryClassName);
+            } catch (Exception e) {
+                throw new CascadingRuntimeException("Cannot create an instance of " + factoryClassName, e);
+            }
+        }
+    }
+    
+    public String getFactoryClassName() {
+        return this.factory == null ? null : this.factory.getClass().getName();
+    }
+
+    /**
+     * Actively performs the binding from the ObjectModel wrapped in a jxpath
+     * context to the CocoonForm.
+     */
+    public void doLoad(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        Pointer ptr = jxpc.getPointer(this.xpath);
+        if (ptr.getNode() != null) {
+            JXPathContext subContext = jxpc.getRelativeContext(ptr);
+            super.doLoad(frmModel, subContext);
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("done loading " + toString());
+        } else {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("non-existent path: skipping " + toString());
+            }
+        }
+    }
+
+    /**
+     * Actively performs the binding from the CocoonForm to the ObjectModel
+     * wrapped in a jxpath context.
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        if (this.factory != null) {
+            jxpc.setFactory(this.factory);
+        }
+        Pointer ptr = jxpc.getPointer(this.xpath);
+        if (ptr.getNode() == null) {
+            jxpc.createPath(this.xpath);
+            // Need to recreate the pointer after creating the path
+            ptr = jxpc.getPointer(this.xpath);
+        }
+        JXPathContext subContext = jxpc.getRelativeContext(ptr);
+        super.doSave(frmModel, subContext);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("done saving " + toString());
+        }
+    }
+    
+    /** To allow child classes to know which path they bind to */
+    public String getXPath() {
+        return this.xpath;
+    }
+
+    public String toString() {
+        return "ContextJXPathBinding [xpath=" + this.xpath + "]";
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 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.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * ContextJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link ContextJXPathBinding} out of the configuration in the
+ * provided configElement which looks like:
+ * <pre><code>
+ * &lt;fb:context path="<i>xpath expression</i>"&gt;
+ *   &lt;!-- in here come the nested child bindings on the sub-context --&gt;
+ * &lt;/fb:context&gt;
+ * </code></pre>
+ * <p>The <code>fb:context</code> element can have an optional <code>factory</code>
+ * attribute, whose value, if present, must be the name of a class extending
+ * {@link org.apache.commons.jxpath.AbstractFactory}. If this attribute is present,
+ * an instance of the named class is registered with the JXPath context and can be used to
+ * create an object corresponding to the path of the <code>fb:context</code> element
+ * upon save, if needed.</p>
+ *
+ * @version $Id: ContextJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class ContextJXPathBindingBuilder extends JXPathBindingBuilderBase {
+
+    /**
+     * Creates an instance of ContextJXPathBinding with the configured
+     * path and nested child bindings from the declarations in the bindingElm
+     */
+    public JXPathBindingBase buildBinding(Element bindingElm,
+        JXPathBindingManager.Assistant assistant) throws BindingException {
+
+        try {
+            CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
+            String xpath = DomHelper.getAttribute(bindingElm, "path", null);
+            String factory = DomHelper.getAttribute(bindingElm, "factory", null);
+
+            JXPathBindingBase[] childBindings = new JXPathBindingBase[0]; 
+            
+            // do inheritance
+            ContextJXPathBinding otherBinding = (ContextJXPathBinding)assistant.getContext().getSuperBinding();
+            if(otherBinding!=null) {
+            	childBindings = otherBinding.getChildBindings();
+            	commonAtts = JXPathBindingBuilderBase.mergeCommonAttributes(otherBinding.getCommonAtts(),commonAtts);
+            	
+            	if(xpath==null)
+            		xpath = otherBinding.getXPath();
+             if (factory == null)
+                 factory = otherBinding.getFactoryClassName();
+            
+            }
+            
+            childBindings = assistant.makeChildBindings(bindingElm,childBindings);
+            
+            ContextJXPathBinding contextBinding = new ContextJXPathBinding(commonAtts, xpath, factory, childBindings);
+            return contextBinding;
+        } catch (BindingException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new BindingException("Error building context binding defined at " + DomHelper.getLocation(bindingElm), e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ContextJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 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.JXPathBindingBuilderBase.CommonAttributes;
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.commons.jxpath.JXPathContext;
+
+/**
+ * CustomJXPathBinding
+ */
+public class CustomJXPathBinding extends JXPathBindingBase {
+    
+    /** 
+     * The id of the cforms widget
+     */
+    private final String widgetId;
+    
+    /**
+     * The path into the objectModel to select
+     */
+    private final String xpath;
+    
+    /**
+     * The actual custom provided binding
+     */
+    private final AbstractCustomBinding wrappedBinding;
+    
+    /**
+     * Constructs CustomJXPathBinding
+     * 
+     * @param commonAtts common configuration attributes {@link org.apache.cocoon.forms.binding.JXPathBindingBuilderBase.CommonAttributes}
+     * @param widgetId id of the widget to bind to
+     * @param xpath jxpath expression to narrow down the context to before calling the wrapped Binding
+     * @param wrappedBinding the actual custom written Binding implementation of {@link Binding}
+     */
+    public CustomJXPathBinding(CommonAttributes commonAtts, String widgetId, 
+                               String xpath, AbstractCustomBinding wrappedBinding) {
+        super(commonAtts);
+        this.widgetId = widgetId;
+        this.xpath = xpath;
+        this.wrappedBinding = wrappedBinding;
+    }
+    
+    public String getXPath() { return xpath; }
+    public String getId() { return widgetId; }
+    public AbstractCustomBinding getWrappedBinding() { return wrappedBinding; }
+    
+    /**
+     * Delegates the actual loading operation to the provided Custom Binding Class
+     * after narrowing down on the selected widget (@id) and context (@path)
+     * 
+     * @param frmModel the narrowed widget-scope from the parent binding
+     * @param jxpc the narrowed jxpath context from the parent binding 
+     * @throws BindingException when the wrapped CustomBinding fails
+     */
+    public void doLoad(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        Widget selectedWidget = selectWidget(frmModel, this.widgetId);
+        JXPathContext context = jxpc.getRelativeContext(jxpc.getPointer(this.xpath));
+        
+        this.wrappedBinding.loadFormFromModel(selectedWidget, context);
+    }    
+
+    /**
+     * Delegates the actual saving operation to the provided Custom Binding Class
+     * after narrowing down on the selected widget (@id) and context (@path)
+     * 
+     * @param frmModel the narrowed widget-scope from the parent binding
+     * @param jxpc the narrowed jxpath context from the parent binding 
+     * @throws BindingException when the wrapped CustomBinding fails
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        Widget selectedWidget = selectWidget(frmModel, this.widgetId);
+        JXPathContext context = jxpc.getRelativeContext(jxpc.getPointer(this.xpath));
+        
+        this.wrappedBinding.saveFormToModel(selectedWidget, context);
+    }
+    
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1999-2004 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 java.lang.reflect.Method;
+
+import org.apache.cocoon.forms.binding.JXPathBindingManager.Assistant;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * CustomJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link CustomJXPathBinding} out of the configuration in the
+ * provided configElement which looks like one of the following:
+ * 
+ * <p> 1. No additional configuration requirements:
+ * <pre><code>
+ * &lt;fb:custom id="<i>widget-id</i>" path="<i>xpath expression</i>"
+ *     class="your.package.CustomBindingX" /&gt;
+ * </code></pre>
+ *
+ * <p> 2. With custom configuration requirements:
+ * <pre><code>
+ * &lt;fb:custom id="<i>widget-id</i>" path="<i>xpath expression</i>"
+ *     builderclass="your.package.CustomBindingXBuilder" 
+ *     factorymethod="makeBinding"
+ * &gt;
+ *   &lt;fb:config custom-atts="someValue"&gt;
+ *     &lt;!-- in here come the nested custom elements (recommended in own namespace) 
+ *             that make up the custom config --&gt;
+ *   &lt;/fb:config&gt;
+ * &lt;/fb:context&gt;
+ * </code></pre>
+ *
+ * @version $Id: CustomJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class CustomJXPathBindingBuilder extends JXPathBindingBuilderBase {
+    private static final Class[] DOMELEMENT_METHODARGS;
+    private static final Class[] EMPTY_METHODARGS;
+    
+    static {
+        DOMELEMENT_METHODARGS = new Class[1];
+        DOMELEMENT_METHODARGS[0] = Element.class;
+        EMPTY_METHODARGS = null;
+    }
+
+    /**
+     * Builds the custom Binding class and wraps it into a CustomJXPathBinding
+     * 
+     * @param bindingElm configuration element describing the binding to build  
+     * @param assistant helper-class for building possible nested bindings 
+     * @return the freshly built binding based on the configuration element
+     * @throws BindingException
+     */
+    public JXPathBindingBase buildBinding(Element bindingElm, 
+        Assistant assistant) throws BindingException {
+
+        try {
+            CommonAttributes commonAtts = 
+                JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
+            String xpath = DomHelper.getAttribute(bindingElm, "path", ".");
+            String widgetId = DomHelper.getAttribute(bindingElm, "id", null);
+
+            Object bindingInstance = null;
+            
+            String className = DomHelper.getAttribute(bindingElm, "class", null);
+            if(className != null) {
+                Class clazz = Class.forName(className);
+                bindingInstance = clazz.newInstance();
+                
+            } else {
+                String builderClassName = 
+                    DomHelper.getAttribute(bindingElm, "builderclass");
+                String factoryMethodName = 
+                    DomHelper.getAttribute(bindingElm, "factorymethod");                
+                Element configNode = 
+                    DomHelper.getChildElement(bindingElm, BindingManager.NAMESPACE, "config");
+                
+                // 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);
+                }
+            }
+            
+//          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 = 
+                new CustomJXPathBinding(commonAtts, widgetId, xpath, (AbstractCustomBinding)bindingInstance);
+            return customBinding;
+        } catch (BindingException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new BindingException("Error building custom binding defined at " + DomHelper.getLocation(bindingElm), e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/CustomJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 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;
+
+/**
+ * DeleteNodeJXPathBinding provides an implementation of a {@link Binding}
+ * that deletes the current context-bean from the target
+ * back-end model upon save.
+ * <p>
+ * NOTES: <ol>
+ * <li>This Binding does not perform any actions when loading.</li>
+ * </ol>
+ *
+ * @version $Id: DeleteNodeJXPathBinding.java 151179 2005-02-03 16:55:16Z tim $
+ */
+public class DeleteNodeJXPathBinding extends JXPathBindingBase {
+
+    public DeleteNodeJXPathBinding(JXPathBindingBuilderBase.CommonAttributes commonAtts) {
+        super(commonAtts);
+    }
+
+    public void doLoad(Widget frmModel, JXPathContext jxpc) {
+        // doesn't do a thing when loading.
+    }
+
+    /**
+     * Removes the current context-bean from the jxpath context.
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) {
+        // get rid of the contextbean
+        jxpc.removePath(".");
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 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.w3c.dom.Element;
+
+/**
+ * DeleteNodeJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link DeleteNodeJXPathBinding} out of the configuration in the
+ * provided configElement which looks like:
+ * <pre><code>
+ * &lt;fb:delete-node /&gt;
+ * </code></pre>
+ *
+ * @version $Id: DeleteNodeJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class DeleteNodeJXPathBindingBuilder
+    extends JXPathBindingBuilderBase {
+
+    /**
+     * Creates an instance of {@link DeleteNodeJXPathBinding}.
+     */
+    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);
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/DeleteNodeJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java Thu Nov  3 05:41:06 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: ExpandJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+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/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ExpandJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 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.Group;
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.commons.jxpath.JXPathContext;
+
+/**
+ * GroupJXPathBinding provides an implementation of a {@link Binding}
+ * that narrows the context towards provided childbindings.
+ * <p>
+ * NOTES: <ol>
+ * <li>This Binding assumes that the provided widget-id points to a widget
+ * that contains other widgets.</li>
+ * </ol>
+ *
+ * @version $Id$
+ */
+public class GroupJXPathBinding extends ContextJXPathBinding {
+
+    private final String widgetId;
+
+    /**
+     * Constructs GroupJXPathBinding
+     * @param widgetId
+     * @param xpath
+     * @param childBindings
+     */
+    public GroupJXPathBinding(JXPathBindingBuilderBase.CommonAttributes commonAtts, String widgetId, String xpath, JXPathBindingBase[] childBindings) {
+        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
+     * narrows the scope on the object-model to the member xpath-context
+     * before continuing the binding over the child-bindings.
+     */
+    public void doLoad(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        Group groupWidget = (Group)selectWidget(frmModel, this.widgetId);
+        super.doLoad(groupWidget, jxpc);
+    }
+
+    /**
+     * 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
+     * before continuing the binding over the child-bindings.
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        Group groupWidget = (Group)selectWidget(frmModel, this.widgetId);
+        super.doSave(groupWidget, jxpc);
+    }
+
+    public String toString() {
+        return "GroupJXPathBinding [widget=" + this.widgetId + ", xpath=" + getXPath() + "]";
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2004 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.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * GroupJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link GroupJXPathBinding} out of the configuration in the
+ * provided configElement which looks like:
+ * <pre><code>
+ * &lt;fb:group id="<i>widget-id</i>" path="<i>xpath-expression</i>"
+ *     direction="<i>load|save</i>" lenient="<i>true|false</i>" &gt;
+ *   &lt;fb:field id="<i>sub-widget-id</i>" path="<i>relative-xpath</i>" />
+ * &lt;/fb:group&gt;
+ * </code></pre>
+ *
+ * @version $Id$
+ */
+public class GroupJXPathBindingBuilder
+    extends JXPathBindingBuilderBase {
+
+    public JXPathBindingBase buildBinding(Element bindingElm, JXPathBindingManager.Assistant assistant)
+            throws BindingException {
+        try {
+            String widgetId = DomHelper.getAttribute(bindingElm, "id",null);
+            CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
+            String xpath = DomHelper.getAttribute(bindingElm, "path",null);
+
+            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;
+        } catch (BindingException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new BindingException("Error building group binding defined at " + DomHelper.getLocation(bindingElm), e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/GroupJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java Thu Nov  3 05:41:06 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: ImportJXPathBinding.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+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/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java Thu Nov  3 05:41:06 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: ImportJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+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/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/ImportJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1999-2004 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 java.lang.reflect.Method;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.cocoon.forms.formmodel.Widget;
+import org.apache.commons.jxpath.JXPathContext;
+
+/**
+ * InsertBeanJXPathBinding provides an implementation of a {@link Binding}
+ * that inserts a new instance of the specified bean (classname) or a new instance
+ * created by the model itself into the target back-end model upon save.
+ * <p>
+ * NOTES: <ol>
+ * <li>This Binding does not perform any actions when loading.</li>
+ * <li>This expects the back-end model to be a Java Bean model.</li>
+ * </ol>
+ *
+ * @version $Id: InsertBeanJXPathBinding.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class InsertBeanJXPathBinding extends JXPathBindingBase {
+
+    private final String className;
+    private final String addMethodName;
+
+    /**
+     * Constructs InsertBeanJXPathBinding
+     */
+    public InsertBeanJXPathBinding(JXPathBindingBuilderBase.CommonAttributes commonAtts, String className, String addMethod) {
+        super(commonAtts);
+        this.className = className;
+        this.addMethodName = addMethod;
+    }
+    
+    public String getClassName() { return className; }
+    public String getAddMethodName() { return addMethodName; }
+
+    /**
+     * Do-nothing implementation of the interface.
+     */
+    public void doLoad(Widget frmModel, JXPathContext jxpc) {
+        // doesn't do a thing when loading.
+    }
+
+    /**
+     * Registers a JXPath Factory on the JXPath Context.
+     * <p>
+     * The factory will insert a new instance of the specified bean (classname)
+     * inside this object into the target objectmodel or it will just call the
+     * add method if classname is null.
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) throws BindingException {
+        try {
+            Object parent = jxpc.getContextBean();
+            Object[] args = new Object[1];
+            Class[] argTypes = new Class[1];
+
+            // instantiate the new object
+            if(this.className != null) {
+	            argTypes[0] = Class.forName(this.className);
+	            args[0] = argTypes[0].newInstance();
+            } else {
+            	argTypes = null;
+            	args = null;
+            }
+
+            // lookup the named method on the parent
+            Method addMethod =
+                parent.getClass().getMethod(this.addMethodName, argTypes);
+
+            // invoke this method with this new beast.
+            addMethod.invoke(parent, args);
+
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("InsertBean performed.");
+        } catch (Exception e) {
+            throw new CascadingRuntimeException("InsertBean failed.", e);
+        }
+
+        // jxpc.setFactory(new AbstractFactory() {
+        //     public boolean createObject(JXPathContext context, Pointer pointer,
+        //                                 Object parent, String name, int index) {
+        //         try {
+        //             Object[] args = new Object[1];
+        //             Class[] argTypes = new Class[1];
+        //
+        //             // instantiate the new object
+        //             argTypes[0] = Class.forName(InsertBeanJXPathBinding.this.className);
+        //             args[0] = argTypes[0].newInstance();
+        //             // lookup the named method on the parent
+        //
+        //             Method addMethod =
+        //                 parent.getClass().getMethod(InsertBeanJXPathBinding.this.addMethodName, argTypes);
+        //             // invoke this method with this new beast.
+        //
+        //             addMethod.invoke(parent, args);
+        //
+        //             if (getLogger().isDebugEnabled())
+        //                 getLogger().debug("InsertBean jxpath factory executed for index " + index);
+        //             return true;
+        //         } catch (Exception e) {
+        //             throw new CascadingRuntimeException("InsertBean jxpath factory failed.", e);
+        //         }
+        //     }
+        // });
+        //
+        // if (getLogger().isDebugEnabled())
+        //     getLogger().debug("done registered factory for inserting node -- " + toString());
+    }
+
+    public String toString() {
+        return "InsertBeanJXPathBinding [for class " + this.className + " to addMethod " + this.addMethodName + "]";
+    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1999-2004 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.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * InsertBeanJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link InsertBeanJXPathBinding} out of the configuration in the
+ * provided configElement which looks like:
+ * <pre><code>
+ * &lt;fb:insert-bean classname="..child-bean-class.." addmethod="..method-to-add.."/&gt;
+ * </code></pre>
+ * or if the add method creates the new instance itself:
+ * <pre><code>
+ * &lt;fb:insert-bean addmethod="..method-to-add.."/&gt;
+ * </code></pre>
+ *
+ * @version $Id: InsertBeanJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class InsertBeanJXPathBindingBuilder extends JXPathBindingBuilderBase {
+
+    /**
+     * Creates an instance of {@link InsertBeanJXPathBinding} configured
+     * with the nested template of the bindingElm.
+     */
+    public JXPathBindingBase buildBinding(Element bindingElm, Assistant assistant) throws BindingException {
+
+        try {
+            CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
+
+            String className =
+                DomHelper.getAttribute(bindingElm, "classname", null);
+            String 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;
+        } catch (Exception e) {
+            throw new BindingException("Error building a insert-bean binding defined at " + DomHelper.getLocation(bindingElm), e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertBeanJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 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;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+
+/**
+ * InsertNodeJXPathBinding provides an implementation of a {@link Binding}
+ * that inserts a clone of some 'template document-fragment' into the target
+ * back-end model upon save.
+ * <p>
+ * NOTES: <ol>
+ * <li>This Binding does not perform any actions when loading.</li>
+ * <li>This expects the back-end model to be an XML file.</li>
+ * </ol>
+ *
+ * @version $Id: InsertNodeJXPathBinding.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class InsertNodeJXPathBinding extends JXPathBindingBase {
+
+    private final DocumentFragment template;
+
+    /**
+     * Constructs InsertNodeJXPathBinding
+     */
+    public InsertNodeJXPathBinding(JXPathBindingBuilderBase.CommonAttributes commonAtts, DocumentFragment domTemplate) {
+        super(commonAtts);
+        this.template = domTemplate;
+    }
+    
+    public DocumentFragment getTemplate() { return template; }
+
+    /**
+     * Do-nothing implementation of the interface.
+     */
+    public void doLoad(Widget frmModel, JXPathContext jxpc) {
+        // doesn't do a thing when loading.
+    }
+
+    /**
+     * Registers a JXPath Factory on the JXPath Context.
+     * <p>
+     * The factory will inserts a clone of the 'template' DocumentFragment
+     * inside this object into the target objectmodel.
+     */
+    public void doSave(Widget frmModel, JXPathContext jxpc) {
+
+        Node parentNode = (Node)jxpc.getContextBean();
+        Document targetDoc = parentNode.getOwnerDocument();
+        Node toInsert = targetDoc.importNode(this.template, true);
+        parentNode.appendChild(toInsert);
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("InsertNode executed.");
+
+        // jxpc.setFactory(new AbstractFactory() {
+        //     public boolean createObject(JXPathContext context, Pointer pointer,
+        //         Object parent, String name, int index) {
+        //
+        //         Node parentNode = (Node) parent;
+        //         Document targetDoc = parentNode.getOwnerDocument();
+        //         Node toInsert = targetDoc.importNode(InsertNodeJXPathBinding.this.template, true);
+        //         parentNode.appendChild(toInsert);
+        //
+        //         if (getLogger().isDebugEnabled())
+        //             getLogger().debug("InsertNode jxpath factory executed for index." + index);
+        //         return true;
+        //     }
+        // });
+        //
+        // if (getLogger().isDebugEnabled())
+        //     getLogger().debug("done registered factory for inserting node -- " + toString());
+    }
+
+    public String toString() {
+        return "InsertNodeJXPathBinding [for nested template]";
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1999-2004 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.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * InsertNodeJXPathBindingBuilder provides a helper class for the Factory
+ * implemented in {@link JXPathBindingManager} that helps construct the
+ * actual {@link InsertNodeJXPathBinding} out of the configuration in the
+ * provided configElement which looks like:
+ * <pre><code>
+ * &lt;fb:insert-node&gt;
+ *   &lt;!-- in here comes a template that will be inserted in the target
+ *           document --&gt;
+ * &lt;/fb:insert-node&gt;
+ * </code></pre>
+ *
+ * @version $Id: InsertNodeJXPathBindingBuilder.java 289538 2005-09-16 13:46:22Z sylvain $
+ */
+public class InsertNodeJXPathBindingBuilder
+    extends JXPathBindingBuilderBase {
+
+    /**
+     * Creates an instance of {@link InsertNodeJXPathBinding} configured
+     * with the nested template of the bindingElm.
+     */
+    public JXPathBindingBase buildBinding(
+        Element bindingElm,
+        JXPathBindingManager.Assistant assistant) throws BindingException {
+
+        try {
+            CommonAttributes commonAtts = JXPathBindingBuilderBase.getCommonAttributes(bindingElm);
+
+            DocumentFragment domTemplate = null;
+
+            String src = DomHelper.getAttribute(bindingElm, "src", null);
+            if (src != null) {
+                ServiceManager manager = assistant.getServiceManager();
+                SourceResolver sourceResolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+                Source source = null;
+                try {
+                    source = sourceResolver.resolveURI(src);
+                    Document document = SourceUtil.toDOM(source);
+                    Element element = document.getDocumentElement();
+
+                    String xpath = DomHelper.getAttribute(bindingElm, "xpath", null);
+                    if (xpath != null) {
+                        XPathProcessor xpathProcessor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
+                        try {
+                            Node node = xpathProcessor.selectSingleNode(document, xpath);
+                            if (node == null)
+                                throw new BindingException("XPath expression \"" + xpath + "\" didn't return a result.");
+                            if (!(node instanceof Element))
+                                throw new BindingException("XPath expression \"" + xpath + "\" did not return an element node.");
+                            element = (Element)node;
+                        } finally {
+                            manager.release(xpathProcessor);
+                        }
+                    }
+                    domTemplate = document.createDocumentFragment();
+                    domTemplate.appendChild(element);
+                } finally {
+                    if (source != null) {
+                        sourceResolver.release(source);
+                    }
+                    manager.release(sourceResolver);
+                }
+            } 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);
+        } catch (Exception e) {
+            throw new BindingException("Error building the insert-node binding defined at " + DomHelper.getLocation(bindingElm), e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/InsertNodeJXPathBindingBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,387 @@
+/*
+ * Copyright 1999-2004 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 java.util.Collection;
+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;
+import org.apache.commons.jxpath.Pointer;
+import org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer;
+import org.apache.commons.jxpath.util.TypeUtils;
+import org.apache.commons.lang.exception.NestableRuntimeException;
+
+/**
+ * Provides a base class for hooking up Binding implementations that use the
+ * Jakarta Commons <a href="http://jakarta.apache.org/commons/jxpath/index.html">
+ * JXPath package</a>.
+ *
+ * @version $Id: JXPathBindingBase.java 292395 2005-09-29 06:38:10Z sylvain $
+ */
+public abstract class JXPathBindingBase implements Binding, LogEnabled {
+
+    /**
+     * 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.
+     */
+    private final JXPathBindingBuilderBase.CommonAttributes commonAtts;
+
+    /**
+     * Parent binding of this binding.
+     */
+    protected Binding parent;
+
+    /**
+     * Cache of class definitions
+     */
+    protected Map classes;
+
+    private JXPathBindingBase() {
+        this(JXPathBindingBuilderBase.CommonAttributes.DEFAULT);
+    }
+
+    protected JXPathBindingBase(
+            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 NestableRuntimeException("Error checking dependencies!",e);
+    		}
+    	}
+    }
+    
+    public JXPathBindingBuilderBase.CommonAttributes getCommonAtts() {
+    	return this.commonAtts;
+    }
+    
+    /**
+     * Gets source location of this binding.
+     */
+    public String getLocation() {
+        return this.commonAtts.location;
+    }
+
+    /**
+     * Sets parent binding.
+     */
+    public void setParent(Binding binding) {
+        this.parent = binding;
+    }
+
+    /**
+     * Returns binding definition id.
+     */
+    public String getId() {
+        return null;
+    }
+
+    public Binding getClass(String id) {
+        
+        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);
+        }
+        if (classBinding == null) {
+            // 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) {
+                 classes = new HashMap();
+                 }
+                 classes.put(id, classBinding);*/
+                // **************************************
+            } else {
+                throw new RuntimeException("Class \"" + id + "\" not found (" + getLocation() + ")");
+            }
+        }
+        return classBinding;
+    }
+
+    /**
+     * Helper method that selects a child-widget with a given id from a parent.
+     *  
+     * @param parent containing the child-widget to return. 
+     * @param id of the childWidget to find, if this is <code>null</code> then the parent is returned.
+     * @return the selected widget
+     * 
+     * @throws RuntimeException  if the id is not null and points to a 
+     *   child-widget that cannot be found. 
+     */
+    protected Widget selectWidget(Widget parent, String id) {
+        if (id == null) return parent;
+        
+        Widget childWidget = null;
+        
+        childWidget = parent.lookupWidget(id);
+            
+        if (childWidget == null) {
+            String containerId = parent.getRequestParameterName();
+            if(containerId == null || "".equals(containerId)) {
+                containerId = "top-level form-widget";
+            } else {
+                containerId = "container \"" + containerId + "\"";
+            }
+            throw new RuntimeException(getClass().getName() + " (" + getLocation() + "): Widget \"" +
+                    id + "\" does not exist in the " + containerId +
+                    " (" + parent.getLocation() + ").");
+        }
+        
+        return childWidget;
+    }
+
+    /**
+     * Performs the actual load binding regardless of the configured value of the "direction" attribute.
+     * Abstract method that subclasses need to implement for specific activity.
+     */
+    public abstract void doLoad(Widget frmModel, JXPathContext jxpc)
+        throws BindingException;
+
+    /**
+     * Redefines the Binding action as working on a JXPathContext Type rather
+     * then on generic objects.
+     * Executes the actual loading via {@link #doLoad(Widget, JXPathContext)}
+     * depending on the configured value of the "direction" attribute.
+     */
+    public final void loadFormFromModel(Widget frmModel, JXPathContext jxpc)
+            throws BindingException {
+        boolean inheritedLeniency = jxpc.isLenient();
+        applyLeniency(jxpc);
+        applyNSDeclarations(jxpc);
+        if (this.commonAtts.loadEnabled) {
+            doLoad(frmModel, jxpc);
+        }
+        jxpc.setLenient(inheritedLeniency);
+    }
+
+    /**
+     * Hooks up with the more generic Binding of any objectModel by wrapping
+     * it up in a JXPathContext object and then transfering control over to
+     * the new overloaded version of this method.
+     */
+    public final void loadFormFromModel(Widget frmModel, Object objModel)
+            throws BindingException {
+        if (objModel != null) {
+            JXPathContext jxpc = makeJXPathContext(objModel);
+            loadFormFromModel(frmModel, jxpc);
+        } else {
+            throw new NullPointerException(
+                    "null object passed to loadFormFromModel() method");
+        }
+    }
+
+    /**
+     * Performs the actual save binding regardless of the configured value of the "direction" attribute.
+     * Abstract method that subclasses need to implement for specific activity.
+     */
+    public abstract void doSave(Widget frmModel, JXPathContext jxpc)
+            throws BindingException;
+
+    /**
+     * Redefines the Binding action as working on a JXPathContext Type rather
+     * then on generic objects.
+     * Executes the actual saving via {@link #doSave(Widget, JXPathContext)}
+     * depending on the configured value of the "direction" attribute.
+     */
+    public final void saveFormToModel(Widget frmModel, JXPathContext jxpc)
+            throws BindingException{
+        boolean inheritedLeniency = jxpc.isLenient();
+        applyLeniency(jxpc);
+        applyNSDeclarations(jxpc);
+        if (this.commonAtts.saveEnabled) {
+            doSave(frmModel, jxpc);
+        }
+        jxpc.setLenient(inheritedLeniency);
+    }
+
+    /**
+     * Hooks up with the more generic Binding of any objectModel by wrapping
+     * it up in a JXPathContext object and then transfering control over to
+     * the new overloaded version of this method.
+     */
+    public void saveFormToModel(Widget frmModel, Object objModel)
+                throws BindingException {
+        if (objModel != null) {
+            JXPathContext jxpc = makeJXPathContext(objModel);
+            saveFormToModel(frmModel, jxpc);    
+        } else {
+            throw new NullPointerException(
+                    "null object passed to saveFormToModel() method");
+        }
+    }
+
+    private void applyLeniency(JXPathContext jxpc) {
+        if (this.commonAtts.leniency != null) {
+            jxpc.setLenient(this.commonAtts.leniency.booleanValue());
+        }
+    }
+
+    private void applyNSDeclarations(JXPathContext jxpc)
+    {
+        if (this.commonAtts.nsDeclarations != null)
+        {
+            Iterator keysIter = this.commonAtts.nsDeclarations.keySet().iterator();
+            while (keysIter.hasNext())
+            {
+                String nsuri = (String) keysIter.next();
+                String pfx = (String) this.commonAtts.nsDeclarations.get(nsuri);
+                jxpc.registerNamespace(pfx, nsuri);
+            }
+        }
+    }
+
+    private JXPathContext makeJXPathContext(Object objModel) {
+        JXPathContext jxpc;
+        if (!(objModel instanceof JXPathContext)) {
+            jxpc = JXPathContext.newContext(objModel);
+            jxpc.setLenient(true);
+            jxpc.setFactory(new BindingJXPathFactory());
+        } else {
+            jxpc = (JXPathContext) objModel;
+        }
+        return jxpc;
+    }
+
+    /**
+     * Receives the Avalon logger to use.
+     * Subclasses should always start with <code>super.enableLogging(logger)
+     * </code> in possible overriding versions.
+     */
+    public void enableLogging(Logger logger) {
+        this.logger = logger;
+    }
+
+    protected Logger getLogger() {
+        return logger;
+    }
+    
+    /**
+     * JXPath factory that combines the DOMFactory and support for collections.
+     */
+    private static class BindingJXPathFactory extends DOMFactory {
+        
+        public boolean createObject(JXPathContext context, Pointer pointer, Object parent, String name, int index) {
+            if (createCollectionItem(context, pointer, parent, name, index)) {
+                return true;
+            // AG: If this is a bean, then the object is supposed to exists.  
+            } else if (pointer instanceof BeanPropertyPointer) {
+                return createBeanField(context, pointer, parent, name, index);
+            } else {
+                return super.createObject(context, pointer, parent, name, index);
+            }
+        }
+        
+        private boolean createCollectionItem(JXPathContext context, Pointer pointer, Object parent, String name, int index) {
+            // FIXME: don't clearly understand how this works.
+            // see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111148567029114&w=2
+            final Object o = context.getValue(name);
+            if (o == null) {
+                return false;
+            } 
+            if (o instanceof Collection) {
+                ((Collection)o).add(null);
+            } else if(o.getClass().isArray()) {
+                // not yet supported
+                return false;
+            } else {
+                return false;
+            }
+            return true;
+        }
+
+        // AG: Create the Object for the field as defined in the Bean.
+        // The value we will set here is not important. JXPath knows that it is UNITIALIZED.
+        // if we set it Pointer Value to null then the code will throw an exception.
+        //
+        // In short, there is no harm. The value will never show up.
+        // TODO: Manage other forms' types as Date, Bean and others not covered by this method.
+        private boolean createBeanField(JXPathContext context, Pointer pointer, Object parent, String name, int index) {
+            try {
+                Class clazz = parent.getClass().getDeclaredField(name).getType();
+                Object o = context.getValue(name);
+                if (o == null) {
+                    final Class[] parametersTypes = {String.class};
+                    final Object[] initArgs = {"0"};
+                    try {
+                        // AG: Here we service Booleans, Strings and Number() + his Direct know subclasses:
+                        // (BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short)
+                        // as well as other classes that use an String as Constructor parameter.
+                        o = clazz.getConstructor(parametersTypes).newInstance(initArgs);
+                    } catch (Exception e) {
+                        // AG: The class has not a constructor using a String as a parameter.
+                        // ie: Boolean(String), Integer(String), etc.
+                        // Lets try with a constructor with no parameters. ie: Number().
+                        o = clazz.newInstance();
+                    }
+                } else if (TypeUtils.canConvert(o, clazz)) {
+                    o = TypeUtils.convert(o, clazz);
+                }
+                if (o != null) {
+                    pointer.setValue(o);
+                    return true;  // OK. We have an initial Object of the right Class initialized.
+                }
+            } catch (Exception e) {
+                // TODO: Output info in logs.
+            }
+            return false;
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/JXPathBindingBase.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message