From e2dd65b1b4df067a28a5efd573e9de4bd36f4865 Mon Sep 17 00:00:00 2001 From: Ariel Backenroth Date: Mon, 18 Jun 2007 19:06:51 +0000 Subject: [PATCH] fix and unit test for Schema2XForms - adding a unit test. currently just tests repeat properties and instance data. - fix for problem with obtaining particle for element references. addresses bug WCM-508 - new regenerate renditions icons from linton git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6010 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/forms/xforms/Schema2XForms.java | 146 ++++----- .../web/forms/xforms/Schema2XFormsTest.java | 297 ++++++++++++++++++ .../alfresco/web/forms/xforms/SchemaUtil.java | 20 +- .../xforms/customer-tests/nyronian-1.xsd | 48 +++ .../unit-tests/automated/one-string-test.xsd | 11 + .../automated/repeat-constraints-test.xsd | 58 ++++ .../unit-tests/simple-test/simple-test.xsd | 2 +- .../images/icons/regenerate_renditions.gif | Bin 580 -> 612 bytes .../icons/regenerate_renditions_large.gif | Bin 1398 -> 1448 bytes 9 files changed, 480 insertions(+), 102 deletions(-) create mode 100644 source/java/org/alfresco/web/forms/xforms/Schema2XFormsTest.java create mode 100644 source/test-resources/xforms/customer-tests/nyronian-1.xsd create mode 100644 source/test-resources/xforms/unit-tests/automated/one-string-test.xsd create mode 100644 source/test-resources/xforms/unit-tests/automated/repeat-constraints-test.xsd diff --git a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java index b05ae6955e..cab7438992 100644 --- a/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java +++ b/source/java/org/alfresco/web/forms/xforms/Schema2XForms.java @@ -272,7 +272,8 @@ public class Schema2XForms formSection, schema, rootElementDecl, - "/" + getElementName(rootElementDecl, xformsDocument), + "/" + this.getElementName(rootElementDecl, xformsDocument), + new SchemaUtil.Occurance(1, 1), resourceBundle); if (rootGroup.getNodeName() != NamespaceConstants.XFORMS_PREFIX + ":group") { @@ -818,27 +819,6 @@ public class Schema2XForms return result; } - private Element addAnyType(final Document xformsDocument, - final Element modelSection, - final Element formSection, - final XSModel schema, - final XSTypeDefinition controlType, - final XSElementDeclaration owner, - final String pathToRoot, - final ResourceBundle resourceBundle) - { - return this.addSimpleType(xformsDocument, - modelSection, - formSection, - schema, - controlType, - owner.getName(), - owner, - pathToRoot, - SchemaUtil.getOccurance(owner), - resourceBundle); - } - private void addAttributeSet(final Document xformsDocument, final Element modelSection, final Element defaultInstanceElement, @@ -973,6 +953,7 @@ public class Schema2XForms final XSComplexTypeDefinition controlType, final XSElementDeclaration owner, String pathToRoot, + final SchemaUtil.Occurance occurs, boolean relative, final boolean checkIfExtension, final ResourceBundle resourceBundle) @@ -1000,13 +981,13 @@ public class Schema2XForms formSection, owner, resourceBundle); - final SchemaUtil.Occurance o = SchemaUtil.getOccurance(owner); +// final SchemaUtil.Occurance o = SchemaUtil.getOccurance(owner); final Element repeatSection = this.addRepeatIfNecessary(xformsDocument, modelSection, groupElement, controlType, - o, - pathToRoot); + pathToRoot, + occurs); if (repeatSection != groupElement) { groupElement.setAttributeNS(NamespaceConstants.XFORMS_NS, @@ -1042,9 +1023,11 @@ public class Schema2XForms modelSection, repeatSection, schema, - (XSSimpleTypeDefinition) base, + (XSSimpleTypeDefinition)base, + owner.getName(), owner, pathToRoot, + occurs, resourceBundle); } else @@ -1132,6 +1115,7 @@ public class Schema2XForms final XSModel schema, final XSElementDeclaration elementDecl, final String pathToRoot, + final SchemaUtil.Occurance occurs, final ResourceBundle resourceBundle) throws FormBuilderException { @@ -1158,22 +1142,26 @@ public class Schema2XForms formSection, schema, (XSSimpleTypeDefinition) controlType, + elementDecl.getName(), elementDecl, pathToRoot, + occurs, resourceBundle); } if (controlType.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE && "anyType".equals(controlType.getName())) { - return this.addAnyType(xformsDocument, - modelSection, - formSection, - schema, - (XSComplexTypeDefinition)controlType, - elementDecl, - pathToRoot, - resourceBundle); + return this.addSimpleType(xformsDocument, + modelSection, + formSection, + schema, + (XSComplexTypeDefinition)controlType, + elementDecl.getName(), + elementDecl, + pathToRoot, + occurs, + resourceBundle); } if (controlType.getTypeCategory() != XSTypeDefinition.COMPLEX_TYPE) @@ -1237,22 +1225,21 @@ public class Schema2XForms if (!relative) { - LOGGER.debug("addElement: bind is not relative for " - + elementDecl.getName()); + LOGGER.debug("addElement: bind is not relative for " + elementDecl.getName()); } else { - final SchemaUtil.Occurance o = SchemaUtil.getOccurance(elementDecl); +// final SchemaUtil.Occurance occurs = SchemaUtil.getOccurance(elementDecl); //create the bind in case it is a repeat LOGGER.debug("Adding empty bind for control " + controlType + " type " + typeName + " nodeset " + pathToRoot + - " occurs " + o); + " occurs " + occurs); // create the element and add it to the model. final Element bindElement = this.createBind(xformsDocument, - pathToRoot + (o.isRepeated() ? "[position() != last()]" : "")); + pathToRoot + (occurs.isRepeated() ? "[position() != last()]" : "")); final String bindId = bindElement.getAttributeNS(null, "id"); modelSection.appendChild(bindElement); @@ -1260,7 +1247,7 @@ public class Schema2XForms schema, controlType, null, - o); + occurs); } return this.addComplexType(xformsDocument, modelSection, @@ -1270,6 +1257,7 @@ public class Schema2XForms (XSComplexTypeDefinition)controlType, elementDecl, pathToRoot, + occurs, true, false, resourceBundle); @@ -1343,6 +1331,7 @@ public class Schema2XForms (XSComplexTypeDefinition)controlType, elementDecl, pathToRoot, + SchemaUtil.getOccurance(elementDecl), true, false, resourceBundle); @@ -1390,6 +1379,7 @@ public class Schema2XForms (XSComplexTypeDefinition) type, elementDecl, pathToRoot, + SchemaUtil.getOccurance(elementDecl), true, true, resourceBundle); @@ -1464,7 +1454,7 @@ public class Schema2XForms final XSComplexTypeDefinition controlType, final XSElementDeclaration owner, final String pathToRoot, - final SchemaUtil.Occurance o, + final SchemaUtil.Occurance occurs, final boolean checkIfExtension, final ResourceBundle resourceBundle) throws FormBuilderException @@ -1478,8 +1468,8 @@ public class Schema2XForms modelSection, formSection, owner.getTypeDefinition(), - o, - pathToRoot); + pathToRoot, + occurs); if (LOGGER.isDebugEnabled()) { @@ -1492,16 +1482,15 @@ public class Schema2XForms { final XSParticle currentNode = (XSParticle)particles.item(counter); XSTerm term = currentNode.getTerm(); - + final SchemaUtil.Occurance childOccurs = new SchemaUtil.Occurance(currentNode); if (LOGGER.isDebugEnabled()) { - LOGGER.debug(" : next term = " + term.getName()); + LOGGER.debug(" : next term = " + term.getName() + + " occurs = " + childOccurs); } - final SchemaUtil.Occurance childOccurs = new SchemaUtil.Occurance(currentNode); if (term instanceof XSModelGroup) { - if (LOGGER.isDebugEnabled()) { LOGGER.debug(" term is a group"); @@ -1590,6 +1579,7 @@ public class Schema2XForms schema, element, pathToRoot, + childOccurs, resourceBundle); } else @@ -1610,6 +1600,7 @@ public class Schema2XForms schema, element, pathToRoot, + childOccurs, resourceBundle); } } @@ -1634,9 +1625,11 @@ public class Schema2XForms final XSModel schema, final XSElementDeclaration element, final String pathToRoot, + final SchemaUtil.Occurance occurs, final ResourceBundle resourceBundle) throws FormBuilderException { + LOGGER.debug("addElement to group " + element + " at " + pathToRoot); //add it normally final String elementName = this.getElementName(element, xformsDocument); final String path = (pathToRoot.length() == 0 @@ -1657,24 +1650,25 @@ public class Schema2XForms schema, element, path, + occurs, resourceBundle); - final SchemaUtil.Occurance elementOccurs = SchemaUtil.getOccurance(element); - LOGGER.debug("adding " + (elementOccurs.maximum == 1 +// final SchemaUtil.Occurance occurs = SchemaUtil.getOccurance(element); + LOGGER.debug("adding " + (occurs.maximum == 1 ? 1 - : elementOccurs.minimum + 1) + + : occurs.minimum + 1) + " default instance element for " + elementName + " at path " + path); // update the default instance - if (elementOccurs.isRepeated()) + if (occurs.isRepeated()) { - LOGGER.debug("adding " + (elementOccurs.minimum + 1) + + LOGGER.debug("adding " + (occurs.minimum + 1) + " default instance elements for " + elementName + " at path " + path); - for (int i = 0; i < elementOccurs.minimum + 1; i++) + for (int i = 0; i < occurs.minimum + 1; i++) { final Element e = (Element)newDefaultInstanceElement.cloneNode(true); - if (i == elementOccurs.minimum) + if (i == occurs.minimum) { e.setAttributeNS(NamespaceService.ALFRESCO_URI, NamespaceService.ALFRESCO_PREFIX + ":prototype", @@ -1687,7 +1681,7 @@ public class Schema2XForms { LOGGER.debug("adding one default instance element for " + elementName + " at path " + path); - if (elementOccurs.minimum == 0) + if (occurs.minimum == 0) { newDefaultInstanceElement.setAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX + ":nil", @@ -1704,8 +1698,8 @@ public class Schema2XForms final Element modelSection, final Element formSection, final XSTypeDefinition controlType, - final SchemaUtil.Occurance o , - final String pathToRoot) + final String pathToRoot, + final SchemaUtil.Occurance o) { // add xforms:repeat section if this element re-occurs @@ -1789,13 +1783,14 @@ public class Schema2XForms final String owningElementName, final XSObject owner, final String pathToRoot, - final SchemaUtil.Occurance o, + final SchemaUtil.Occurance occurs, final ResourceBundle resourceBundle) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("addSimpleType for " + controlType.getName() + - " (owningElementName=" + owningElementName + ")"); + " (owningElementName=" + owningElementName + ")" + + " occurs = " + occurs); if (owner != null) { LOGGER.debug("owner is " + owner.getClass() + @@ -1805,13 +1800,13 @@ public class Schema2XForms // create the element and add it to the model. Element bindElement = - this.createBind(xformsDocument, pathToRoot + (o.isRepeated() ? "[position() != last()]" : "")); + this.createBind(xformsDocument, pathToRoot + (occurs.isRepeated() ? "[position() != last()]" : "")); String bindId = bindElement.getAttributeNS(null, "id"); modelSection.appendChild(bindElement); - bindElement = this.startBindElement(bindElement, schema, controlType, owner, o); + bindElement = this.startBindElement(bindElement, schema, controlType, owner, occurs); // add a group if a repeat ! - if (owner instanceof XSElementDeclaration && o.maximum != 1) + if (owner instanceof XSElementDeclaration && occurs.maximum != 1) { final Element groupElement = this.createGroup(xformsDocument, modelSection, @@ -1831,8 +1826,8 @@ public class Schema2XForms modelSection, formSection, controlType, - o, - pathToRoot); + pathToRoot, + occurs); // create the form control element //put a wrapper for the repeat content, but only if it is really a repeat @@ -1856,7 +1851,7 @@ public class Schema2XForms owner, bindId, bindElement, - o, + occurs, resourceBundle); repeatSection.appendChild(formControl); @@ -1875,27 +1870,6 @@ public class Schema2XForms return formSection; } - private Element addSimpleType(final Document xformsDocument, - final Element modelSection, - final Element formSection, - final XSModel schema, - final XSSimpleTypeDefinition controlType, - final XSElementDeclaration owner, - final String pathToRoot, - final ResourceBundle resourceBundle) - { - return this.addSimpleType(xformsDocument, - modelSection, - formSection, - schema, - controlType, - owner.getName(), - owner, - pathToRoot, - SchemaUtil.getOccurance(owner), - resourceBundle); - } - private Element addSimpleType(final Document xformsDocument, final Element modelSection, final Element formSection, diff --git a/source/java/org/alfresco/web/forms/xforms/Schema2XFormsTest.java b/source/java/org/alfresco/web/forms/xforms/Schema2XFormsTest.java new file mode 100644 index 0000000000..2651cb1f6c --- /dev/null +++ b/source/java/org/alfresco/web/forms/xforms/Schema2XFormsTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.forms.xforms; + +import java.io.*; +import java.util.*; + +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.web.forms.XMLUtil; +import org.alfresco.util.BaseTest; +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.jxpath.Pointer; +import org.chiba.xml.ns.NamespaceConstants; +import org.w3c.dom.*; +import org.xml.sax.*; + +/** + * JUnit tests to exercise the the schema to xforms converter + * + * @author ariel backenroth + */ +public class Schema2XFormsTest + extends BaseTest +{ + + public void testOneStringTestWithEmptyInstanceDocument() + throws Exception + { + final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/automated/one-string-test.xsd"); + final Document xformsDocument = this.buildXForm(null, schemaDocument, "one-string-test"); + final JXPathContext xpathContext = JXPathContext.newContext(xformsDocument); + Pointer pointer = xpathContext.getPointer("//*[@id='input_0']"); + assertNotNull(pointer); + String s = ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "bind"); + assertNotNull(s); + pointer = xpathContext.getPointer("//*[@id='" + s + "']"); + assertNotNull(pointer); + assertEquals("true()", ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "required")); + pointer = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']/one-string-test/string"); + assertNotNull(pointer); + assertEquals("default-value", ((Element)pointer.getNode()).getTextContent()); + } + + public void testOneStringTestWithInstanceDocument() + throws Exception + { + final Document instanceDocument = XMLUtil.parse("test"); + final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/automated/one-string-test.xsd"); + final Document xformsDocument = this.buildXForm(instanceDocument, schemaDocument, "one-string-test"); + final JXPathContext xpathContext = JXPathContext.newContext(xformsDocument); + Pointer pointer = xpathContext.getPointer("//*[@id='input_0']"); + assertNotNull(pointer); + String s = ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "bind"); + pointer = xpathContext.getPointer("//*[@id='" + s + "']"); + assertNotNull(pointer); + assertEquals("true()", ((Element)pointer.getNode()).getAttributeNS(NamespaceConstants.XFORMS_NS, "required")); + pointer = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']/one-string-test/string"); + assertNotNull(pointer); + assertEquals("test", ((Element)pointer.getNode()).getTextContent()); + } + + public void testRepeatConstraintsTest() + throws Exception + { + final Document schemaDocument = this.loadTestResourceDocument("xforms/unit-tests/automated/repeat-constraints-test.xsd"); + final Document xformsDocument = this.buildXForm(null, schemaDocument, "repeat-constraints-test"); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/one-to-inf", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/zero-to-inf", + new SchemaUtil.Occurance(0, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/one-to-five", + new SchemaUtil.Occurance(1, 5)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/three-to-five", + new SchemaUtil.Occurance(3, 5)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/zero-to-five", + new SchemaUtil.Occurance(0, 5)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/referenced-string", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-zero-to-inf", + new SchemaUtil.Occurance(0, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-zero-to-inf/nested-zero-to-inf-inner-zero-to-inf", + new SchemaUtil.Occurance(0, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-zero-to-inf/nested-zero-to-inf-inner-one-to-inf", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-one-to-inf", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-one-to-inf/nested-one-to-inf-inner-zero-to-inf", + new SchemaUtil.Occurance(0, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-one-to-inf/nested-one-to-inf-inner-one-to-inf", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-three-to-five", + new SchemaUtil.Occurance(3, 5)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-three-to-five/nested-three-to-five-inner-zero-to-inf", + new SchemaUtil.Occurance(0, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-three-to-five/nested-three-to-five-inner-one-to-inf", + new SchemaUtil.Occurance(1, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-outer-three-to-inf", + new SchemaUtil.Occurance(3, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-outer-three-to-inf/nested-outer-inner-five-to-inf", + new SchemaUtil.Occurance(5, SchemaUtil.Occurance.UNBOUNDED)); + this.assertRepeatProperties(xformsDocument, + "/repeat-constraints-test/nested-outer-outer-three-to-inf/nested-outer-inner-five-to-inf/nested-inner-inner-seven-to-inf", + new SchemaUtil.Occurance(7, SchemaUtil.Occurance.UNBOUNDED)); + } + + private void assertRepeatProperties(final Document xformsDocument, final String nodeset, final SchemaUtil.Occurance o) + { + final Element[] bindElements = this.resolveBind(xformsDocument, nodeset); + assertNotNull("unable to resolve bind for nodeset " + nodeset, bindElements); + assertFalse("unable to resolve bind for nodeset " + nodeset, 0 == bindElements.length); + final Element nodesetBindElement = bindElements[bindElements.length - 1]; + assertEquals("unexpected minimum value for nodeset " + nodeset, + o.minimum, + Integer.parseInt(nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs"))); + if (o.isUnbounded()) + { + assertEquals("unexpected maximum value for nodeset " + nodeset, + "unbounded", + nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs")); + } + else + { + assertEquals("unexpected maximum value for nodeset " + nodeset, + o.maximum, + Integer.parseInt(nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs"))); + } + assertEquals("unexpected required value for nodeset " + nodeset, + (o.minimum != 0 && nodesetBindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "type")) + "()", + nodesetBindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "required")); + + JXPathContext xpathContext = JXPathContext.newContext(xformsDocument); + String xpath = "//*[@" + NamespaceConstants.XFORMS_PREFIX + ":bind='" + nodesetBindElement.getAttribute("id") + "']"; + assertEquals(4, xpathContext.selectNodes(xpath).size()); + xpath = ("//" + NamespaceConstants.XFORMS_PREFIX + + ":repeat[@" + NamespaceConstants.XFORMS_PREFIX + + ":bind='" + nodesetBindElement.getAttribute("id") + "']"); + assertEquals(1, xpathContext.selectNodes(xpath).size()); + xpath = ("//" + NamespaceConstants.XFORMS_PREFIX + + ":trigger[@" + NamespaceConstants.XFORMS_PREFIX + + ":bind='" + nodesetBindElement.getAttribute("id") + "']"); + assertEquals(3, xpathContext.selectNodes(xpath).size()); + + int nestingFactor = 1; + for (int i = 0; i < bindElements.length - 1; i++) + { + final SchemaUtil.Occurance parentO = this.occuranceFromBind(bindElements[i]); + if (parentO.isRepeated()) + { + nestingFactor = nestingFactor * (1 + parentO.minimum); + } + } + final Pointer instance0 = xpathContext.getPointer("//" + NamespaceConstants.XFORMS_PREFIX + ":instance[@id='instance_0']"); + assertNotNull(instance0); + assertNotNull(instance0.getNode()); + xpathContext = xpathContext.getRelativeContext(instance0); + xpath = nodeset.substring(1); + assertEquals("unexpected result for instance nodeset " + xpath + " in " + instance0.getNode(), + nestingFactor * (o.minimum + 1), + xpathContext.selectNodes(xpath).size()); + xpath = nodeset.substring(1) + "[@" + NamespaceService.ALFRESCO_PREFIX + ":prototype='true']"; + assertEquals("unexpected result for instance prototype nodeset " + nodeset + " in " + instance0.getNode(), + nestingFactor, + xpathContext.selectNodes(xpath).size()); + } + + /** + * Returns the resolved bind and all parents binds for the nodeset. + */ + private Element[] resolveBind(final Document xformsDocument, final String nodeset) + { + JXPathContext xpathContext = JXPathContext.newContext(xformsDocument); + assertNotNull(nodeset); + assertEquals('/', nodeset.charAt(0)); + final String rootNodePath = nodeset.replaceFirst("(\\/[^\\/]+).*", "$1"); + assertNotNull(rootNodePath); + String xpath = ("//" + NamespaceConstants.XFORMS_PREFIX + + ":bind[@" + NamespaceConstants.XFORMS_PREFIX + + ":nodeset='" + rootNodePath + "']"); + Pointer pointer = xpathContext.getPointer(xpath); + assertNotNull("unable to resolve xpath for root node " + xpath, pointer); + assertNotNull("unable to resolve xpath for root node " + xpath, pointer.getNode()); + if (nodeset.equals(rootNodePath)) + { + return new Element[] { (Element)pointer.getNode() }; + } + xpathContext = xpathContext.getRelativeContext(pointer); + // substring the path to the next slash and split it + final LinkedList result = new LinkedList(); + result.add((Element)pointer.getNode()); + for (String p : nodeset.substring(rootNodePath.length() + 1).split("/")) + { + xpath = NamespaceConstants.XFORMS_PREFIX + ":bind[starts-with(@" + NamespaceConstants.XFORMS_PREFIX + ":nodeset, '" + p + "')]"; + pointer = xpathContext.getPointer(xpath); + assertNotNull("unable to resolve path " + xpath + + " on bind with nodeset " + result.getLast().getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"), + pointer); + assertNotNull("unable to resolve path " + xpath + + " on bind with nodeset " + result.getLast().getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"), + pointer.getNode()); + xpathContext = xpathContext.getRelativeContext(pointer); + result.add((Element)pointer.getNode()); + } + return (Element[])result.toArray(new Element[result.size()]); + } + + private Document loadTestResourceDocument(final String path) + throws IOException, SAXException + { + File f = new File(this.getResourcesDir()); + for (final String p : path.split("/")) + { + f = new File(f, p); + } + return XMLUtil.parse(f); + } + + private Document buildXForm(final Document instanceDocument, + final Document schemaDocument, + final String rootElementName) + throws FormBuilderException + { + final Schema2XForms s2xf = new Schema2XForms("/test_action", + Schema2XForms.SubmitMethod.POST, + "http://fake.base.url"); + return s2xf.buildXForm(instanceDocument, + schemaDocument, + rootElementName, + new ResourceBundle() + { + public Object handleGetObject(final String key) + { + if (key == null) + { + throw new NullPointerException(); + } + return null; + } + + public Enumeration getKeys() + { + return new Vector().elements(); + } + }); + } + + + private SchemaUtil.Occurance occuranceFromBind(final Element bindElement) + { + return new SchemaUtil.Occurance(bindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs") + ? Integer.parseInt(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "minOccurs")) + : 1, + bindElement.hasAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs") + ? ("unbounded".equals(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs")) + ? SchemaUtil.Occurance.UNBOUNDED + : Integer.parseInt(bindElement.getAttributeNS(NamespaceConstants.XFORMS_NS, "maxOccurs"))) + : 1); + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java b/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java index 39038d42d5..1e89a256e6 100644 --- a/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java +++ b/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java @@ -51,23 +51,14 @@ public class SchemaUtil public Occurance(final XSParticle particle) { - if (particle == null) - { - this.minimum = 1; - this.maximum = 1; - } - else - { - this.minimum = particle.getMinOccurs(); - this.maximum = (particle.getMaxOccursUnbounded() - ? Occurance.UNBOUNDED - : particle.getMaxOccurs()); - } + this(particle.getMinOccurs(), (particle.getMaxOccursUnbounded() + ? Occurance.UNBOUNDED + : particle.getMaxOccurs())); } public Occurance(final int minimum) { - this(minimum, UNBOUNDED); + this(minimum, Occurance.UNBOUNDED); } public Occurance(final int minimum, final int maximum) @@ -737,8 +728,7 @@ public class SchemaUtil //get occurance on encosing element declaration final XSParticle particle = SchemaUtil.findCorrespondingParticleInComplexType(elDecl); - final Occurance result = new Occurance(particle); - + final Occurance result = particle == null ? new Occurance(1, 1) : new Occurance(particle); if (LOGGER.isDebugEnabled()) { LOGGER.debug("getOccurance for " + elDecl.getName() + diff --git a/source/test-resources/xforms/customer-tests/nyronian-1.xsd b/source/test-resources/xforms/customer-tests/nyronian-1.xsd new file mode 100644 index 0000000000..de06462c2b --- /dev/null +++ b/source/test-resources/xforms/customer-tests/nyronian-1.xsd @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/test-resources/xforms/unit-tests/automated/one-string-test.xsd b/source/test-resources/xforms/unit-tests/automated/one-string-test.xsd new file mode 100644 index 0000000000..5781468893 --- /dev/null +++ b/source/test-resources/xforms/unit-tests/automated/one-string-test.xsd @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/source/test-resources/xforms/unit-tests/automated/repeat-constraints-test.xsd b/source/test-resources/xforms/unit-tests/automated/repeat-constraints-test.xsd new file mode 100644 index 0000000000..07e5c87892 --- /dev/null +++ b/source/test-resources/xforms/unit-tests/automated/repeat-constraints-test.xsd @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/test-resources/xforms/unit-tests/simple-test/simple-test.xsd b/source/test-resources/xforms/unit-tests/simple-test/simple-test.xsd index f105a6ddb1..57c240b012 100644 --- a/source/test-resources/xforms/unit-tests/simple-test/simple-test.xsd +++ b/source/test-resources/xforms/unit-tests/simple-test/simple-test.xsd @@ -1,7 +1,7 @@ - + diff --git a/source/web/images/icons/regenerate_renditions.gif b/source/web/images/icons/regenerate_renditions.gif index f614348cc70c2b429da540bb4acd5f1171464e63..3003358a5396b105a81534625e00e7bf4294902d 100644 GIT binary patch delta 514 zcmV+d0{#8O1mpyNM@dFFIbje05CG;{0P^M8mX?lq$+AXX`TYF+?d|RJ^Yh!=+wt-7_xJbN+1c{)^48YY`}v;w`ugPLgxFT_=}5+#l^+%@9(_4ysfRR($doS_Fnw^y#4&g*|uT&`Ip(YXz=jx-qFO~%((gY zZ|m8``S*0zuwV4;j;fc0+t0$@-rk*yciOjb*RgHe&cW>L?Dz1<)~{CQ+RfUxaq;O( z+0DT6>Sg&L_=4KEd)v5(;o;%ixQ*Ddg4wlO-_yp}wN=`jlMw-LeFarBN;M`iyR9JECUW3Ehm?XDFY2i zD+C1wCZbvg0xN=qhKQFg5Fn0_l9ZN<9|;$ko1LGbi!cgPq!9xG6E6)xj4A{}uL2Ge zOBy9r0N`3E1rN6nIWHPgSX4<-OaNLQ1`@yt2@NG#H8d4P@F4+ABvYVZhY=tZZa{hR zqsO9Z1PFk*g2M-o86Ds)8dspe1sxr1G_it3qat|*NRSY6#EBAcCba+zK(i(hMu7kT EJEyT4ZvX%Q delta 465 zcmV;?0WSXJ1jGb?M@dFFIbje05CG-?00000|NsBLy}rA-x^kb-`1W4;_iy?4bouy# z`uUgp`JVjyy#4&g@##zQ>Sgrpj`#4$*tJ#JwOiS?UfH%`)~{C9uwU7>Xxg`M+P87n zv2EJ7d)l~y+qj6>vVz;VjqBOP>)+Dq-qG&j)#TB>>es}7+04J~;M4Nu+0w+g+1S|A z($db&&B@5f$j8UU#KgnG!ltFA{QUg;`}_L(`uOER@9*#J?d|OB z?Cb06>gww0>FMa`=;r3;<>lq$G(#grmz`(%2zrVM)x2>(M zmX?-~kdTWDi;IGSf_Zs)|NsA!ApvZYFaa2UA^8LW002_}EC2ui01yBW000M}fK!5k zAcKa7D2X14D2Ik99Ul-I8I6vDC>#t63K%IYEiX+;gCH6Y3JC}f79}z>N=rzCC>I9? z1rsAQyi8D1v=bB!5)mggHpw~*n)dV{@ zgwwD_V)Dj^z7{H z@bK{Q@$ul`;OXh<`uh6s@9*a3=Huhz;^N}v<>lw+=kD(A`1ttw`T6VX>-_xu`}_Ok zWZc6N5Rx3}ly;g^?}%F4>x+S=LK*{P|iy}iB9qjrvtj^f6t z)~{8bo}QMLmYkfN)YQ~xXJ^sT(fRjvXlQ8s`@qqqbNTml&Z2eLvV&%3X3nB^l!$xT zy`cN~oa@?r?AwR>`H$DJZvFk&`S*6#uU7Z8O`uKx#a&mETadmZd*~hc*Sd6?cJ^E*jf4aanYu9?%ulk_>BGi)SQok^y5yudtDE z`1Weiq+;pUN%r(P`}(K%^-%x+|C7-H%zq*I1OWg5y8tWz0000W03ZMW2>$?gfiN+q z42U90N+=PrLWYzbJ~r%{NU@^DT^%xDfC0k;h6WZY7zhABz!ESME~=bpqyYvG9y5R> zFtVfwEMXq3yqKjy28}X95(sbrfC3gjT6B@Hv!V$L78*zuI`V)31!A-Su|lIM#eX9N zDpUwrfhN(C30Qns%f#!%8wLo-m0Pu>f&>l*Ah^)Pt-t^Q3nWS&#+*!gwg4;cRVhCFH z?9rr4S8ky|!GVLPQKy!zdNu3Tu74_@446IutXQ&U3#VQCp{+_P7Z8a5hdY<~DR@Cq4;n}yV{Nz9XdH2RU4M{+4VQ3% z2_-7L5=^g_$a4`!g zXiO4EA1a(c(F_a3xd3?L)p>zp1u)>sBX!I{3M#pG8#vW=|QVS%Fw1v6Sf(5WhR^{AdIaItmR)wauAJ_^%fTj~HU+1g0EZxO2O#=#z=0!vCAz2! ZQ%tdlA&Dq*$SANxaz-1m6rxf<06W?Xz3Tt~ delta 1089 zcmV-H1it&I3-$_sM@dFFIbk3GAOQCO00000|NsATpU?O8RQUF2`S))5_jURBd;0m7 z`uUjq`knmywfgvl`}v>z`@sGD&+FYm>)l1{-dXJ4TJGS1?%{^#(pTrxUFXwb=+trO z)O+dHlkw!Z@#MSe)|>0tug;%h&Yxq>pJ>jXZ0q0B?&8&d(#*y6@94{!X3eF0&!&CO zrF_n&eAKIg)U1NjtAW_EjM%e`*RhM%u!`{G*459+^6cjE>*e$C?d;#v@8Z_{{QUd- z`}+F&`T6+0(2 z>FMd{=;-Hv=jZ0;=H=z($@($Ue;(9qD&&(F@z&dtru%*@Qn%F4;f$;ZdX#>U3Q z#l^$J!@|PC!NI}6z`(!1zrDS^ySux(y1KZyxVE-NwzRagv$M0Yv9YkQu&u4FtgNi7 ztE;N2s;Q}|sHmu?r>CZ-rlqB&q@<*yqobmtqM@OoprD|ipP!zdo}HbYoSdAFj*gQ) z0?(6B0(*ZU`2+y~0FnSK00000AOIi$00{p8B?%lT2?oJ~2ooyQfkKC*6AB|L9HBx* z2No+t)DSaf%$YN3)UatI=ZM6CDmZ+2u%UvB9Xx#a00Jb)5F$nJuYBtJY8hIsJ;0%Z_3YT8_CsI2@^Gm#w5;R8>MA}GX6D`g+#S~!x znNS^0L@8yIPgFS}6fgEj1r<%sIFKDsSZO5`Ny=A66<|1t&>c}g;pUrB2%uwt0$5?i z7mRo*5FS!U(Vw4l4tT{CUo@hpBzY{UsG@QPDgYK)cwuOe1L?8lrI(f|Ko(kb;mB>F zdsuPis8!f$#h`;?0V$_iaPbJJqLNcus-37_p=uVax_T%dwf1W3t+;9-tQK3mN~u7H z{Gsf!fB+ImAc90Y2qA?SV#pzgBoc`jN+@)N7-fVj?zrTRE5;QO8G)RQ?6&K!jVT&I HP(T1XpWsud