coliver 2003/02/23 11:21:32
Modified: src/java/org/apache/cocoon/components/xmlform Form.java Log: 'Updated to support using the Cocoon flow layer with XMLForm' Revision Changes Path 1.17 +104 -70 xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Form.java Index: Form.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xmlform/Form.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Form.java 31 Jan 2003 22:51:40 -0000 1.16 +++ Form.java 23 Feb 2003 19:21:32 -0000 1.17 @@ -74,8 +74,15 @@ import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.JXPathException; import org.apache.commons.jxpath.Pointer; +import org.apache.commons.jxpath.ri.model.NodePointer; import org.w3c.dom.Element; import org.w3c.dom.Text; +// Unfortunately I have to introduce this dependency on +// org.mozilla.javascript classes to support using JavaScript +// nodes in JXPath +import org.mozilla.javascript.NativeArray; +import org.mozilla.javascript.ScriptableObject; +import org.mozilla.javascript.Context; /** * <p> @@ -184,55 +191,77 @@ jxcontext_.setValue(xpath, value); } - public void setValue(String xpath, Object[] values) { + public void setValue(String xpath, Object[] values) { + Pointer ptr = jxcontext_.getPointer(xpath); - // // Dmitri Plotnikov's patch - // - // // if there are multiple values to set - // // (like in the selectMany case), - // // iterate over the array and set individual values - // if ( values.length > 1 ) - // { - // Iterator iter = jxcontext_.iteratePointers(xpath); - // for (int i = 0; i < values.length; i++ ) - // { - // Pointer ptr = (Pointer)iter.next(); - // ptr.setValue(values[i]); - // } - // } - // else - // { - // // This is supposed to do the right thing - // jxcontext_.setValue(xpath, values); - // } - // - - Pointer pointer = jxcontext_.getPointer(xpath); - Object property = pointer.getValue(); - // if there are multiple values to set - // (like in the selectMany case), - // iterate over the array and set individual values - - // when the instance property is array - if (property != null && property.getClass().isArray()) { - Class componentType = property.getClass().getComponentType(); - property = - java.lang.reflect.Array.newInstance( - componentType, - values.length); - java.lang.System.arraycopy(values, 0, property, 0, values.length); - pointer.setValue(property); - } else if (property instanceof Collection) { - Collection cl = (Collection) property; - cl.clear(); - cl.addAll(java.util.Arrays.asList(values)); - } - // otherwise set the value of the first element - // (and the only) from the values array - else { - pointer.setValue(values[0]); - } - } + // // Dmitri Plotnikov's patch + // + // // if there are multiple values to set + // // (like in the selectMany case), + // // iterate over the array and set individual values + // if ( values.length > 1 ) + // { + // Iterator iter = jxcontext_.iteratePointers(xpath); + // for (int i = 0; i < values.length; i++ ) + // { + // Pointer ptr = (Pointer)iter.next(); + // ptr.setValue(values[i]); + // } + // } + // else + // { + // // This is supposed to do the right thing + // jxcontext_.setValue(xpath, values); + // } + // + + Pointer pointer = jxcontext_.getPointer(xpath); + Object property = pointer.getNode(); + // if there are multiple values to set + // (like in the selectMany case), + // iterate over the array and set individual values + + // when the instance property is array + if (property != null && property.getClass().isArray()) { + Class componentType = property.getClass().getComponentType(); + property = + java.lang.reflect.Array.newInstance( + componentType, + values.length); + java.lang.System.arraycopy(values, 0, property, 0, values.length); + pointer.setValue(property); + } else if (property instanceof Collection) { + Collection cl = (Collection) property; + cl.clear(); + cl.addAll(java.util.Arrays.asList(values)); + } else if (property instanceof NativeArray) { + Context.enter(); + try { + NativeArray arr = (NativeArray)property; + ScriptableObject.putProperty(arr, "length", + new Integer(0)); + ScriptableObject.putProperty(arr, "length", + new Integer(values.length)); + for (int i = 0; i < values.length; i++) { + Object val = values[i]; + if (!(val == null + || val instanceof String + || val instanceof Number + || val instanceof Boolean)) { + val = Context.toObject(val, arr); + } + ScriptableObject.putProperty(arr, i, val); + } + } catch (Exception willNotBeThrown) { + // shouldn't happen + willNotBeThrown.printStackTrace(); + } finally { + Context.exit(); + } + } else { + jxcontext_.setValue(xpath, values[0]); + } + } /** * Encapsulates access to the model @@ -245,22 +274,24 @@ * */ public Object getValue(String xpath) { - if (model_ == null) throw new IllegalStateException("Form model not set"); - Pointer pointer = jxcontext_.getPointer(xpath); - Object property = pointer.getValue(); - if (property != null) { - // handle DOM elements - if (property instanceof Element) { - String textPath = pointer.asPath() + "/text()"; - property = getValue(textPath); - } else if (property instanceof Text) { - Text node = (Text) property; - property = node.getData(); + Object result = jxcontext_.getValue(xpath); + if (result instanceof NativeArray) { + // Convert JavaScript array to Collection + NativeArray arr = (NativeArray)result; + int len = (int)arr.jsGet_length(); + List list = new ArrayList(len); + for (int i = 0; i < len; i++) { + Object obj = arr.get(i, arr); + if (obj == Context.getUndefinedValue()) { + obj = null; } + list.add(obj); + } + result = list; } - return property; + return result; } /** @@ -282,10 +313,12 @@ if (model_ == null) throw new IllegalStateException("Form model not set"); List nodeset = new LinkedList(); + Pointer ptr = jxcontext_.getPointer(xpathSelector); Iterator iter = jxcontext_.iteratePointers(xpathSelector); while (iter.hasNext()) { - Pointer nextPointer = (Pointer) iter.next(); - nodeset.add(nextPointer.asPath()); + Pointer nextPointer = (Pointer) iter.next(); + String path = nextPointer.asPath(); + nodeset.add(path); } return nodeset; } @@ -313,14 +346,14 @@ validator_.setProperty(Validator.PROPERTY_PHASE, phase); List vs = validator_.validate(model_); - - if (violations_ != null) { + if (vs != null) { + if (violations_ != null) { violations_.addAll(vs); - } else { - if (vs != null && !vs.isEmpty()) - violations_ = vs; + } else { + if (!vs.isEmpty()) + violations_ = vs; + } } - if (violations_ == null) return true; else { @@ -373,12 +406,13 @@ Object[] values = (Object[]) entry.getValue(); try { + System.out.println("attempting to set value of " + path + " to " + java.util.Arrays.asList(values)); setValue(path, values); } catch (JXPathException ex) { Violation v = new Violation(); v.setPath(path); String message = VIOLATION_MESSAGE_DATA_FORMAT_ERROR; - v.setMessage(message); + v.setMessage(ex.getMessage()); pviolations.add(v); } } // while