001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.forms.binding;
018:
019: import java.lang.reflect.Method;
020:
021: import org.apache.avalon.framework.CascadingRuntimeException;
022:
023: import org.apache.cocoon.forms.formmodel.Widget;
024:
025: import org.apache.commons.jxpath.JXPathContext;
026:
027: /**
028: * InsertBeanJXPathBinding provides an implementation of a {@link Binding}
029: * that inserts a new instance of the specified bean (classname) or a new instance
030: * created by the model itself into the target back-end model upon save.
031: * <p>
032: * NOTES: <ol>
033: * <li>This Binding does not perform any actions when loading.</li>
034: * <li>This expects the back-end model to be a Java Bean model.</li>
035: * </ol>
036: *
037: * @version $Id: InsertBeanJXPathBinding.java 517733 2007-03-13 15:37:22Z vgritsenko $
038: */
039: public class InsertBeanJXPathBinding extends JXPathBindingBase {
040:
041: private final String className;
042: private final String addMethodName;
043:
044: /**
045: * Constructs InsertBeanJXPathBinding
046: */
047: public InsertBeanJXPathBinding(
048: JXPathBindingBuilderBase.CommonAttributes commonAtts,
049: String className, String addMethod) {
050: super (commonAtts);
051: this .className = className;
052: this .addMethodName = addMethod;
053: }
054:
055: public String getClassName() {
056: return className;
057: }
058:
059: public String getAddMethodName() {
060: return addMethodName;
061: }
062:
063: /**
064: * Do-nothing implementation of the interface.
065: */
066: public void doLoad(Widget frmModel, JXPathContext jxpc) {
067: // doesn't do a thing when loading.
068: }
069:
070: /**
071: * Registers a JXPath Factory on the JXPath Context.
072: * <p>
073: * The factory will insert a new instance of the specified bean (classname)
074: * inside this object into the target objectmodel or it will just call the
075: * add method if classname is null.
076: */
077: public void doSave(Widget frmModel, JXPathContext jxpc)
078: throws BindingException {
079: try {
080: Object parent = jxpc.getContextBean();
081: Object[] args = new Object[1];
082: Class[] argTypes = new Class[1];
083:
084: // instantiate the new object
085: if (this .className != null) {
086: argTypes[0] = Class.forName(this .className);
087: args[0] = argTypes[0].newInstance();
088: } else {
089: argTypes = null;
090: args = null;
091: }
092:
093: // lookup the named method on the parent
094: Method addMethod = parent.getClass().getMethod(
095: this .addMethodName, argTypes);
096:
097: // invoke this method with this new beast.
098: addMethod.invoke(parent, args);
099:
100: if (getLogger().isDebugEnabled()) {
101: getLogger().debug("InsertBean performed.");
102: }
103: } catch (Exception e) {
104: throw new CascadingRuntimeException("InsertBean failed.", e);
105: }
106:
107: // jxpc.setFactory(new AbstractFactory() {
108: // public boolean createObject(JXPathContext context, Pointer pointer,
109: // Object parent, String name, int index) {
110: // try {
111: // Object[] args = new Object[1];
112: // Class[] argTypes = new Class[1];
113: //
114: // // instantiate the new object
115: // argTypes[0] = Class.forName(InsertBeanJXPathBinding.this.className);
116: // args[0] = argTypes[0].newInstance();
117: // // lookup the named method on the parent
118: //
119: // Method addMethod =
120: // parent.getClass().getMethod(InsertBeanJXPathBinding.this.addMethodName, argTypes);
121: // // invoke this method with this new beast.
122: //
123: // addMethod.invoke(parent, args);
124: //
125: // if (getLogger().isDebugEnabled())
126: // getLogger().debug("InsertBean jxpath factory executed for index " + index);
127: // return true;
128: // } catch (Exception e) {
129: // throw new CascadingRuntimeException("InsertBean jxpath factory failed.", e);
130: // }
131: // }
132: // });
133: //
134: // if (getLogger().isDebugEnabled())
135: // getLogger().debug("done registered factory for inserting node -- " + this);
136: }
137:
138: public String toString() {
139: return "InsertBeanJXPathBinding [for class " + this .className
140: + " to addMethod " + this .addMethodName + "]";
141: }
142:
143: }
|