List of usage examples for org.w3c.dom Element setAttributeNS
public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException;
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
/** * Generate the XForm based on a user supplied XML Schema. * * @param instanceDocument The document source for the XML Schema. * @param schemaDocument Schema document * @param rootElementName Name of the root element * @param resourceBundle Strings to use/*from w ww . ja v a 2 s . c o m*/ * @return The Document containing the XForm. * @throws org.chiba.tools.schemabuilder.FormBuilderException * If an error occurs building the XForm. */ public Pair<Document, XSModel> buildXForm(final Document instanceDocument, final Document schemaDocument, String rootElementName, final ResourceBundle resourceBundle) throws FormBuilderException { final XSModel schema = SchemaUtil.parseSchema(schemaDocument, true); this.typeTree = SchemaUtil.buildTypeTree(schema); //refCounter = 0; this.counter.clear(); final Document xformsDocument = this.createFormTemplate(rootElementName); //find form element: last element created final Element formSection = (Element) xformsDocument.getDocumentElement().getLastChild(); final Element modelSection = (Element) xformsDocument.getDocumentElement() .getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "model").item(0); //add XMLSchema if we use schema types final Element importedSchemaDocumentElement = (Element) xformsDocument .importNode(schemaDocument.getDocumentElement(), true); importedSchemaDocumentElement.setAttributeNS(null, "id", "schema-1"); NodeList nl = importedSchemaDocumentElement.getChildNodes(); boolean hasExternalSchema = false; for (int i = 0; i < nl.getLength(); i++) { Node current = nl.item(i); if (current.getNamespaceURI() != null && current.getNamespaceURI().equals(NamespaceConstants.XMLSCHEMA_NS)) { String localName = current.getLocalName(); if (localName.equals("include") || localName.equals("import")) { hasExternalSchema = true; break; } } } // ALF-8105 / ETWOTWO-1384: Only embed the schema if it does not reference externals if (!hasExternalSchema) { modelSection.appendChild(importedSchemaDocumentElement); } //check if target namespace final StringList schemaNamespaces = schema.getNamespaces(); final HashMap<String, String> schemaNamespacesMap = new HashMap<String, String>(); if (schemaNamespaces.getLength() != 0) { // will return null if no target namespace was specified this.targetNamespace = schemaNamespaces.item(0); if (LOGGER.isDebugEnabled()) LOGGER.debug("[buildXForm] using targetNamespace " + this.targetNamespace); for (int i = 0; i < schemaNamespaces.getLength(); i++) { if (schemaNamespaces.item(i) == null) { continue; } final String prefix = addNamespace(xformsDocument.getDocumentElement(), schemaDocument.lookupPrefix(schemaNamespaces.item(i)), schemaNamespaces.item(i)); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[buildXForm] adding namespace " + schemaNamespaces.item(i) + " with prefix " + prefix + " to xform and default instance element"); } schemaNamespacesMap.put(prefix, schemaNamespaces.item(i)); } } //if target namespace & we use the schema types: add it to form ns declarations // if (this.targetNamespace != null && this.targetNamespace.length() != 0) // envelopeElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, // "xmlns:schema", // this.targetNamespace); final XSElementDeclaration rootElementDecl = schema.getElementDeclaration(rootElementName, this.targetNamespace); if (rootElementDecl == null) { throw new FormBuilderException("Invalid root element tag name [" + rootElementName + ", targetNamespace = " + this.targetNamespace + "]"); } rootElementName = this.getElementName(rootElementDecl, xformsDocument); final Element instanceElement = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":instance"); modelSection.appendChild(instanceElement); this.setXFormsId(instanceElement); final Element defaultInstanceDocumentElement = xformsDocument.createElement(rootElementName); addNamespace(defaultInstanceDocumentElement, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX, NamespaceConstants.XMLSCHEMA_INSTANCE_NS); if (this.targetNamespace != null) { final String targetNamespacePrefix = schemaDocument.lookupPrefix(this.targetNamespace); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[buildXForm] adding target namespace " + this.targetNamespace + " with prefix " + targetNamespacePrefix + " to xform and default instance element"); } addNamespace(defaultInstanceDocumentElement, targetNamespacePrefix, this.targetNamespace); addNamespace(xformsDocument.getDocumentElement(), targetNamespacePrefix, this.targetNamespace); } Element prototypeInstanceElement = null; if (instanceDocument == null || instanceDocument.getDocumentElement() == null) { instanceElement.appendChild(defaultInstanceDocumentElement); } else { Element instanceDocumentElement = instanceDocument.getDocumentElement(); if (!instanceDocumentElement.getNodeName().equals(rootElementName)) { throw new IllegalArgumentException("instance document root tag name invalid. " + "expected " + rootElementName + ", got " + instanceDocumentElement.getNodeName()); } if (LOGGER.isDebugEnabled()) LOGGER.debug("[buildXForm] importing rootElement from other document"); prototypeInstanceElement = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":instance"); modelSection.appendChild(prototypeInstanceElement); this.setXFormsId(prototypeInstanceElement, "instance_prototype"); prototypeInstanceElement.appendChild(defaultInstanceDocumentElement); } final Element rootGroup = this.addElement(xformsDocument, modelSection, defaultInstanceDocumentElement, formSection, schema, rootElementDecl, "/" + this.getElementName(rootElementDecl, xformsDocument), new SchemaUtil.Occurrence(1, 1), resourceBundle); if (rootGroup.getNodeName() != NamespaceConstants.XFORMS_PREFIX + ":group") { throw new FormBuilderException("Expected root form element to be a " + NamespaceConstants.XFORMS_PREFIX + ":group, not a " + rootGroup.getNodeName() + ". Ensure that " + this.getElementName(rootElementDecl, xformsDocument) + " is a concrete type that has no extensions. " + "Types with extensions are not supported for " + "the root element of a form."); } this.setXFormsId(rootGroup, "alfresco-xforms-root-group"); if (prototypeInstanceElement != null) { Schema2XForms.rebuildInstance(prototypeInstanceElement, instanceDocument, instanceElement, schemaNamespacesMap); } this.createSubmitElements(xformsDocument, modelSection, rootGroup); this.createTriggersForRepeats(xformsDocument, rootGroup); final Comment comment = xformsDocument.createComment( "This XForm was generated by " + this.getClass().getName() + " on " + (new Date()) + " from the '" + rootElementName + "' element of the '" + this.targetNamespace + "' XML Schema."); xformsDocument.getDocumentElement().insertBefore(comment, xformsDocument.getDocumentElement().getFirstChild()); xformsDocument.normalizeDocument(); if (LOGGER.isDebugEnabled()) LOGGER.debug("[buildXForm] Returning XForm =\n" + XMLUtil.toString(xformsDocument)); return new Pair<Document, XSModel>(xformsDocument, schema); }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
@SuppressWarnings("unchecked") public static void rebuildInstance(final Node prototypeNode, final Node oldInstanceNode, final Node newInstanceNode, final HashMap<String, String> schemaNamespaces) { final JXPathContext prototypeContext = JXPathContext.newContext(prototypeNode); prototypeContext.registerNamespace(NamespaceService.ALFRESCO_PREFIX, NamespaceService.ALFRESCO_URI); final JXPathContext instanceContext = JXPathContext.newContext(oldInstanceNode); instanceContext.registerNamespace(NamespaceService.ALFRESCO_PREFIX, NamespaceService.ALFRESCO_URI); for (final String prefix : schemaNamespaces.keySet()) { prototypeContext.registerNamespace(prefix, schemaNamespaces.get(prefix)); instanceContext.registerNamespace(prefix, schemaNamespaces.get(prefix)); }//from ww w . j a v a2s.c o m // Evaluate non-recursive XPaths for all prototype elements at this level final Iterator<Pointer> it = prototypeContext.iteratePointers("*"); while (it.hasNext()) { final Pointer p = it.next(); Element proto = (Element) p.getNode(); String path = p.asPath(); // check if this is a prototype element with the attribute set boolean isPrototype = proto.hasAttributeNS(NamespaceService.ALFRESCO_URI, "prototype") && proto.getAttributeNS(NamespaceService.ALFRESCO_URI, "prototype").equals("true"); // We shouldn't locate a repeatable child with a fixed path if (isPrototype) { path = path.replaceAll("\\[(\\d+)\\]", "[position() >= $1]"); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[rebuildInstance] evaluating prototyped nodes " + path); } } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[rebuildInstance] evaluating child node with positional path " + path); } } Document newInstanceDocument = newInstanceNode.getOwnerDocument(); // Locate the corresponding nodes in the instance document List<Node> l = (List<Node>) instanceContext.selectNodes(path); // If the prototype node isn't a prototype element, copy it in as a missing node, complete with all its children. We won't need to recurse on this node if (l.isEmpty()) { if (!isPrototype) { LOGGER.debug("[rebuildInstance] copying in missing node " + proto.getNodeName() + " to " + XMLUtil.buildXPath(newInstanceNode, newInstanceDocument.getDocumentElement())); // Clone the prototype node and all its children Element clone = (Element) proto.cloneNode(true); newInstanceNode.appendChild(clone); if (oldInstanceNode instanceof Document) { // add XMLSchema instance NS addNamespace(clone, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX, NamespaceConstants.XMLSCHEMA_INSTANCE_NS); } } } else { // Otherwise, append the matches from the old instance document in order for (Node old : l) { Element oldEl = (Element) old; // Copy the old instance element rather than cloning it, so we don't copy over attributes Element clone = null; String nSUri = oldEl.getNamespaceURI(); if (nSUri == null) { clone = newInstanceDocument.createElement(oldEl.getTagName()); } else { clone = newInstanceDocument.createElementNS(nSUri, oldEl.getTagName()); } newInstanceNode.appendChild(clone); if (oldInstanceNode instanceof Document) { // add XMLSchema instance NS addNamespace(clone, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX, NamespaceConstants.XMLSCHEMA_INSTANCE_NS); } // Copy over child text if this is not a complex type boolean isEmpty = true; for (Node n = old.getFirstChild(); n != null; n = n.getNextSibling()) { if (n instanceof Text) { clone.appendChild(newInstanceDocument.importNode(n, false)); isEmpty = false; } else if (n instanceof Element) { break; } } // Populate the nil attribute. It may be true or false if (proto.hasAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, "nil")) { clone.setAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX + ":nil", String.valueOf(isEmpty)); } // Copy over attributes present in the prototype NamedNodeMap attributes = proto.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { Attr attribute = (Attr) attributes.item(i); String localName = attribute.getLocalName(); if (localName == null) { String name = attribute.getName(); if (oldEl.hasAttribute(name)) { clone.setAttributeNode( (Attr) newInstanceDocument.importNode(oldEl.getAttributeNode(name), false)); } else { LOGGER.debug("[rebuildInstance] copying in missing attribute " + attribute.getNodeName() + " to " + XMLUtil.buildXPath(clone, newInstanceDocument.getDocumentElement())); clone.setAttributeNode((Attr) attribute.cloneNode(false)); } } else { String namespace = attribute.getNamespaceURI(); if (!((!isEmpty && (namespace.equals(NamespaceConstants.XMLSCHEMA_INSTANCE_NS) && localName.equals("nil")) || (namespace.equals(NamespaceService.ALFRESCO_URI) && localName.equals("prototype"))))) { if (oldEl.hasAttributeNS(namespace, localName)) { clone.setAttributeNodeNS((Attr) newInstanceDocument .importNode(oldEl.getAttributeNodeNS(namespace, localName), false)); } else { LOGGER.debug("[rebuildInstance] copying in missing attribute " + attribute.getNodeName() + " to " + XMLUtil.buildXPath(clone, newInstanceDocument.getDocumentElement())); clone.setAttributeNodeNS((Attr) attribute.cloneNode(false)); } } } } // recurse on children rebuildInstance(proto, oldEl, clone, schemaNamespaces); } } // Now add in a new copy of the prototype if (isPrototype) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[rebuildInstance] appending " + proto.getNodeName() + " to " + XMLUtil.buildXPath(newInstanceNode, newInstanceDocument.getDocumentElement())); } newInstanceNode.appendChild(proto.cloneNode(true)); } } }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
protected String setXFormsId(final Element el, String id) { if (el.hasAttributeNS(null, "id")) { el.removeAttributeNS(null, "id"); }/* www . j a v a 2 s. c o m*/ if (id == null) { final String name = el.getLocalName(); final Long l = this.counter.get(name); final long count = (l != null) ? l : 0; // increment the counter this.counter.put(name, new Long(count + 1)); id = name + "_" + count; } el.setAttributeNS(null, "id", id); return id; }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
/** *///from w ww . jav a 2 s . c o m protected Map<String, Element> addChoicesForSelectSwitchControl(final Document xformsDocument, final Element formSection, final List<XSTypeDefinition> choiceValues, final String typeBindId) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addChoicesForSelectSwitchControl] values = "); for (XSTypeDefinition type : choiceValues) { LOGGER.debug(" - " + type.getName()); } } final Map<String, Element> result = new HashMap<String, Element>(); for (XSTypeDefinition type : choiceValues) { final String textValue = type.getName(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addChoicesForSelectSwitchControl] processing " + textValue); } //build the case element final Element caseElement = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":case"); caseElement.appendChild(this.createLabel(xformsDocument, textValue)); final String caseId = this.setXFormsId(caseElement); result.put(textValue, caseElement); final Element toggle = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":toggle"); this.setXFormsId(toggle); toggle.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":case", caseId); final Element setValue = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":setvalue"); setValue.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":bind", typeBindId); setValue.appendChild(xformsDocument.createTextNode(textValue)); formSection .appendChild(this.createTrigger(xformsDocument, null, typeBindId, textValue, toggle, setValue)); } return result; }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
private void addAttributeSet(final Document xformsDocument, final Element modelSection, final Element defaultInstanceElement, final Element formSection, final XSModel schema, final XSComplexTypeDefinition controlType, final XSElementDeclaration owner, final String pathToRoot, final boolean checkIfExtension, final ResourceBundle resourceBundle) throws FormBuilderException { XSObjectList attrUses = controlType.getAttributeUses(); if (attrUses == null) { return;/*from w ww .j a v a 2 s . c o m*/ } for (int i = 0; i < attrUses.getLength(); i++) { final XSAttributeUse currentAttributeUse = (XSAttributeUse) attrUses.item(i); final XSAttributeDeclaration currentAttribute = currentAttributeUse.getAttrDeclaration(); String attributeName = currentAttributeUse.getName(); if (attributeName == null || attributeName.length() == 0) { attributeName = currentAttributeUse.getAttrDeclaration().getName(); } //test if extended ! if (checkIfExtension && SchemaUtil.doesAttributeComeFromExtension(currentAttributeUse, controlType)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( "[addAttributeSet] This attribute comes from an extension: recopy form controls. Model section =\n" + XMLUtil.toString(modelSection)); } //find the existing bind Id //(modelSection is the enclosing bind of the element) final NodeList binds = modelSection.getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "bind"); String bindId = null; for (int j = 0; j < binds.getLength() && bindId == null; j++) { Element bind = (Element) binds.item(j); String nodeset = bind.getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"); if (nodeset != null) { //remove "@" in nodeset String name = nodeset.substring(1); if (name.equals(attributeName)) { bindId = bind.getAttributeNS(null, "id"); } } } //find the control Element control = null; if (bindId != null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("[addAttributeSet] bindId found: " + bindId); JXPathContext context = JXPathContext.newContext(formSection.getOwnerDocument()); final Pointer pointer = context .getPointer("//*[@" + NamespaceConstants.XFORMS_PREFIX + ":bind='" + bindId + "']"); if (pointer != null) { control = (Element) pointer.getNode(); } else if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addAttributeSet] unable to resolve pointer for: //*[@" + NamespaceConstants.XFORMS_PREFIX + ":bind='" + bindId + "']"); } } if (LOGGER.isDebugEnabled()) { if (control == null) { LOGGER.debug("[addAttributeSet] control = <not found>"); } else { LOGGER.debug("[addAttributeSet] control = " + control.getTagName()); } } //copy it if (control == null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Corresponding control not found"); } else { Element newControl = (Element) control.cloneNode(true); //set new Ids to XForm elements this.resetXFormIds(newControl); formSection.appendChild(newControl); } } else { String attrNamespace = currentAttribute.getNamespace(); String namespacePrefix = ""; if (attrNamespace != null && attrNamespace.length() > 0) { String prefix = NamespaceResolver.getPrefix(xformsDocument.getDocumentElement(), attrNamespace); if (prefix != null && prefix.length() > 0) { namespacePrefix = prefix + ":"; } } final String newPathToRoot = (pathToRoot == null || pathToRoot.length() == 0 ? "@" + namespacePrefix + currentAttribute.getName() : (pathToRoot.endsWith("/") ? pathToRoot + "@" + namespacePrefix + currentAttribute.getName() : pathToRoot + "/@" + namespacePrefix + currentAttribute.getName())); if (LOGGER.isDebugEnabled()) LOGGER.debug("[addAttributeSet] adding attribute " + attributeName + " at " + newPathToRoot); try { String defaultValue = (currentAttributeUse.getConstraintType() == XSConstants.VC_NONE ? null : currentAttributeUse.getConstraintValue()); // make sure boolean attributes have a default value if (defaultValue == null && "boolean".equals(currentAttribute.getTypeDefinition().getName())) { defaultValue = "false"; } if (namespacePrefix.length() > 0) { defaultInstanceElement.setAttributeNS(this.targetNamespace, attributeName, defaultValue); } else { defaultInstanceElement.setAttribute(attributeName, defaultValue); } } catch (Exception e) { throw new FormBuilderException("error retrieving default value for attribute " + attributeName + " at " + newPathToRoot, e); } this.addSimpleType(xformsDocument, modelSection, formSection, schema, currentAttribute.getTypeDefinition(), currentAttributeUse, newPathToRoot, resourceBundle); } } }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
private Element addComplexType(final Document xformsDocument, Element modelSection, final Element defaultInstanceElement, final Element formSection, final XSModel schema, final XSComplexTypeDefinition controlType, final XSElementDeclaration owner, String pathToRoot, final SchemaUtil.Occurrence occurs, boolean relative, final boolean checkIfExtension, final ResourceBundle resourceBundle) throws FormBuilderException { if (controlType == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] addComplexType control type is null for pathToRoot = " + pathToRoot); }/*from w w w .java 2 s .c o m*/ return null; } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] Start addComplexType for " + controlType.getName() + " (" + pathToRoot + ")," + " owner = " + (owner == null ? "null" : owner.getName())); } // add a group node and recurse final Element groupElement = this.createGroup(xformsDocument, modelSection, formSection, owner, resourceBundle); // final SchemaUtil.Occurrence o = SchemaUtil.getOccurrence(owner); final Element repeatSection = this.addRepeatIfNecessary(xformsDocument, modelSection, groupElement, controlType, pathToRoot, occurs); if (repeatSection != groupElement) { groupElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", "repeated"); // we have a repeat relative = true; } if (controlType.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED || (controlType.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_SIMPLE && controlType.getAttributeUses() != null && controlType.getAttributeUses().getLength() > 0)) { XSTypeDefinition base = controlType.getBaseType(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] Control type is mixed, base type = " + base.getName()); } if (base != null && base != controlType) { if (base.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) { this.addSimpleType(xformsDocument, modelSection, repeatSection, schema, (XSSimpleTypeDefinition) base, owner.getName(), owner, pathToRoot, occurs, resourceBundle); } else { LOGGER.warn("[addComplexType] addComplexTypeChildren for mixed type with basic type complex!"); } } } else if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] Control content type = " + controlType.getContentType()); } // check for compatible subtypes // of controlType. // add a type switch if there are any // compatible sub-types (i.e. anything // that derives from controlType) // add child elements if (relative) { pathToRoot = ""; //modelSection: find the last element put in the modelSection = bind modelSection = DOMUtil.getLastChildElement(modelSection); } //attributes this.addAttributeSet(xformsDocument, modelSection, defaultInstanceElement, repeatSection, schema, controlType, owner, pathToRoot, checkIfExtension, resourceBundle); //process group final XSParticle particle = controlType.getParticle(); if (particle != null) { final XSTerm term = particle.getTerm(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] Particle of " + controlType.getName() + " is" + (term instanceof XSModelGroup ? "" : " not") + " a group: " + term.getClass().getName()); } if (term instanceof XSModelGroup) { switch (((XSModelGroup) term).getCompositor()) { case XSModelGroup.COMPOSITOR_CHOICE: LOGGER.warn("term " + term.getName() + " of particle " + particle.getName() + " of type " + controlType.getName() + " in " + owner.getName() + " describes a " + NamespaceConstants.XMLSCHEMA_PREFIX + ":choice which is not yet supported, adding it as a " + NamespaceConstants.XMLSCHEMA_PREFIX + ":sequence"); break; case XSModelGroup.COMPOSITOR_ALL: LOGGER.warn("term " + term.getName() + " of particle " + particle.getName() + " of type " + controlType.getName() + " in " + owner.getName() + " describes a " + NamespaceConstants.XMLSCHEMA_PREFIX + ":all which is not yet supported, adding it as a " + NamespaceConstants.XMLSCHEMA_PREFIX + ":sequence"); break; case XSModelGroup.COMPOSITOR_SEQUENCE: break; } //call addGroup on this group this.addGroup(xformsDocument, modelSection, defaultInstanceElement, repeatSection, schema, (XSModelGroup) term, controlType, owner, pathToRoot, new SchemaUtil.Occurrence(particle), checkIfExtension, resourceBundle); } } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addComplexType] End of addComplexType for " + controlType.getName()); } return groupElement; }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
private Element addElementWithMultipleCompatibleTypes(final Document xformsDocument, Element modelSection, final Element defaultInstanceElement, final Element formSection, final XSModel schema, final XSElementDeclaration elementDecl, final TreeSet<XSTypeDefinition> compatibleTypes, final String pathToRoot, final ResourceBundle resourceBundle, final SchemaUtil.Occurrence occurs) throws FormBuilderException { if (LOGGER.isDebugEnabled()) LOGGER.debug("[addElementWithMultipleCompatibleTypes] adding element " + elementDecl + " at path " + pathToRoot);/*from w w w . jav a 2s .c o m*/ // look for compatible types final XSTypeDefinition controlType = elementDecl.getTypeDefinition(); //get possible values final List<XSTypeDefinition> enumValues = new LinkedList<XSTypeDefinition>(); //add the type (if not abstract) if (!((XSComplexTypeDefinition) controlType).getAbstract()) { enumValues.add(controlType); } //add compatible types enumValues.addAll(compatibleTypes); // multiple compatible types for this element exist // in the schema - allow the user to choose from // between compatible non-abstract types boolean isRepeated = isRepeated(occurs, controlType); Element bindElement = this.createBind(xformsDocument, pathToRoot + "/@xsi:type"); String bindId = bindElement.getAttributeNS(null, "id"); modelSection.appendChild(bindElement); this.startBindElement(bindElement, schema, controlType, null, occurs); //add the "element" bind, in addition final Element bindElement2 = this.createBind(xformsDocument, pathToRoot + (isRepeated ? "[position() != last()]" : "")); modelSection.appendChild(bindElement2); this.startBindElement(bindElement2, schema, controlType, null, occurs); // add content to select1 final Map<String, Element> caseTypes = this.addChoicesForSelectSwitchControl(xformsDocument, formSection, enumValues, bindId); //add switch final Element switchElement = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":switch"); switchElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":bind", bindId); switchElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", "full"); formSection.appendChild(switchElement); if (!((XSComplexTypeDefinition) controlType).getAbstract()) { final Element firstCaseElement = caseTypes.get(controlType.getName()); switchElement.appendChild(firstCaseElement); final Element firstGroupElement = this.addComplexType(xformsDocument, modelSection, defaultInstanceElement, firstCaseElement, schema, (XSComplexTypeDefinition) controlType, elementDecl, pathToRoot, SchemaUtil.getOccurrence(elementDecl), true, false, resourceBundle); firstGroupElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", ""); } defaultInstanceElement.setAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX + ":type", (((XSComplexTypeDefinition) controlType).getAbstract() ? compatibleTypes.first().getName() : controlType.getName())); defaultInstanceElement.setAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX + ":nil", "true"); /////////////// add sub types ////////////// // add each compatible type within // a case statement for (final XSTypeDefinition type : compatibleTypes) { final String compatibleTypeName = type.getName(); if (LOGGER.isDebugEnabled()) { LOGGER.debug(type == null ? ("[addElementWithMultipleCompatibleTypes] compatible type is null!! type = " + compatibleTypeName + ", targetNamespace = " + this.targetNamespace) : ("[addElementWithMultipleCompatibleTypes] adding compatible type " + type.getName())); } if (type == null || type.getTypeCategory() != XSTypeDefinition.COMPLEX_TYPE) { continue; } final Element caseElement = caseTypes.get(type.getName()); switchElement.appendChild(caseElement); // ALF-9524 fix, add an extra element to the instance for each type that extends the abstract parent Element newDefaultInstanceElement = xformsDocument.createElement(getElementName(type, xformsDocument)); Attr nodesetAttr = modelSection.getAttributeNodeNS(NamespaceConstants.XFORMS_NS, "nodeset"); // construct the nodeset that is used in bind for abstract type String desiredBindNodeset = getElementName(elementDecl, xformsDocument) + (isRepeated ? "[position() != last()]" : ""); // check the current bind if (nodesetAttr == null || !nodesetAttr.getValue().equals(desiredBindNodeset)) { // look for desired bind in children Element newModelSection = DOMUtil.getElementByAttributeValueNS(modelSection, NamespaceConstants.XFORMS_NS, "bind", NamespaceConstants.XFORMS_NS, "nodeset", desiredBindNodeset); if (newModelSection == null) { // look for absolute path desiredBindNodeset = "/" + desiredBindNodeset; newModelSection = DOMUtil.getElementByAttributeValueNS(modelSection, NamespaceConstants.XFORMS_NS, "bind", NamespaceConstants.XFORMS_NS, "nodeset", desiredBindNodeset); } modelSection = newModelSection; } // create the extra bind for each child of abstract type Element bindElement3 = this.createBind(xformsDocument, getElementName(type, xformsDocument)); modelSection.appendChild(bindElement3); bindElement3 = this.startBindElement(bindElement3, schema, controlType, elementDecl, occurs); // add the relevant attribute that checks the value of parent' @xsi:type bindElement3.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":relevant", "../@xsi:type='" + type.getName() + "'"); final Element groupElement = this.addComplexType(xformsDocument, modelSection, newDefaultInstanceElement, caseElement, schema, (XSComplexTypeDefinition) type, elementDecl, pathToRoot, SchemaUtil.getOccurrence(elementDecl), true, true, resourceBundle); groupElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", ""); defaultInstanceElement.appendChild(newDefaultInstanceElement.cloneNode(true)); // modify bind to add a "relevant" attribute that checks the value of @xsi:type if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementWithMultipleCompatibleTypes] Model section =\n" + XMLUtil.toString(bindElement3)); } final NodeList binds = bindElement3.getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "bind"); for (int i = 0; i < binds.getLength(); i++) { final Element subBind = (Element) binds.item(i); String name = subBind.getAttributeNS(NamespaceConstants.XFORMS_NS, "nodeset"); // ETHREEOH-3308 fix name = repeatableNamePattern.matcher(name).replaceAll(""); if (!subBind.getParentNode().getAttributes().getNamedItem("id").getNodeValue() .equals(bindElement3.getAttribute("id"))) { continue; } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementWithMultipleCompatibleTypes] Testing sub-bind with nodeset " + name); } Pair<String, String> parsed = parseName(name, xformsDocument); if (!SchemaUtil.isElementDeclaredIn(parsed.getFirst(), parsed.getSecond(), (XSComplexTypeDefinition) type, false) && !SchemaUtil.isAttributeDeclaredIn(parsed.getFirst(), parsed.getSecond(), (XSComplexTypeDefinition) type, false)) { continue; } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementWithMultipleCompatibleTypes] Element/Attribute " + name + " declared in type " + type.getName() + ": adding relevant attribute"); } //test sub types of this type //TreeSet subCompatibleTypes = (TreeSet) typeTree.get(type); String newRelevant = "../../@xsi:type='" + type.getName() + "'"; if (this.typeTree.containsKey(type.getName())) { for (XSTypeDefinition otherType : this.typeTree.get(type.getName())) { newRelevant = newRelevant + " or ../../@xsi:type='" + otherType.getName() + "'"; } } //change relevant attribute final String relevant = subBind.getAttributeNS(NamespaceConstants.XFORMS_NS, "relevant"); if (relevant != null && relevant.length() != 0) { newRelevant = ("(" + relevant + ") and " + newRelevant); } subBind.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":relevant", newRelevant); } } return switchElement; }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
@SuppressWarnings("unchecked") private void addElementToGroup(final Document xformsDocument, final Element modelSection, final Element defaultInstanceElement, final Element formSection, final XSModel schema, final XSElementDeclaration element, final String pathToRoot, final SchemaUtil.Occurrence occurs, final ResourceBundle resourceBundle) throws FormBuilderException { //add it normally final String elementName = this.getElementName(element, xformsDocument); final String path = (pathToRoot.length() == 0 ? elementName : pathToRoot + "/" + elementName); if (LOGGER.isDebugEnabled()) LOGGER.debug("[addElementToGroup] Start addElement to group " + elementName + " at " + path + " parentStack " + this.parentStack); if (this.parentStack.contains(element)) { throw new FormBuilderException("recursion detected at element " + elementName); }/* w w w . j a va 2s .com*/ if (LOGGER.isDebugEnabled()) LOGGER.debug("[addElementToGroup] pushing element " + element + " onto parent stack"); this.parentStack.push(element); final Element newDefaultInstanceElement = xformsDocument.createElement(elementName); if (element.getConstraintType() != XSConstants.VC_NONE) { Node value = xformsDocument.createTextNode(element.getConstraintValue()); newDefaultInstanceElement.appendChild(value); } else if ("boolean".equals(element.getTypeDefinition().getName())) { // we have a boolean element without a default value, default to false Node value = xformsDocument.createTextNode("false"); newDefaultInstanceElement.appendChild(value); } this.addElement(xformsDocument, modelSection, newDefaultInstanceElement, formSection, schema, element, path, occurs, resourceBundle); Object poppedElement = this.parentStack.pop(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementToGroup] popped element " + poppedElement + " from parent stack"); LOGGER.debug("[addElementToGroup] adding " + (occurs.maximum == 1 ? 1 : occurs.minimum + 1) + " default instance element for " + elementName + " at path " + path); } // update the default instance if (isRepeated(occurs, element.getTypeDefinition())) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementToGroup] adding " + (occurs.minimum + 1) + " default instance elements for " + elementName + " at path " + path); } for (int i = 0; i < occurs.minimum + 1; i++) { final Element e = (Element) newDefaultInstanceElement.cloneNode(true); if (i == occurs.minimum) { e.setAttributeNS(NamespaceService.ALFRESCO_URI, NamespaceService.ALFRESCO_PREFIX + ":prototype", "true"); } defaultInstanceElement.appendChild(e); } } else { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addElementToGroup] adding one default instance element for " + elementName + " at path " + path); } if (occurs.minimum == 0) { newDefaultInstanceElement.setAttributeNS(NamespaceConstants.XMLSCHEMA_INSTANCE_NS, NamespaceConstants.XMLSCHEMA_INSTANCE_PREFIX + ":nil", "true"); } defaultInstanceElement.appendChild(newDefaultInstanceElement); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addGroup] End of addElementToGroup, group = " + elementName); } }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
/** * Add a repeat section if maxOccurs > 1. *//*from w w w . j ava 2 s .c o m*/ private Element addRepeatIfNecessary(final Document xformsDocument, final Element modelSection, final Element formSection, final XSTypeDefinition controlType, final String pathToRoot, final SchemaUtil.Occurrence o) { // add xforms:repeat section if this element re-occurs if ((o.isOptional() && (controlType instanceof XSSimpleTypeDefinition || "anyType".equals(controlType.getName()))) || (o.maximum == 1 && o.minimum == 1) || (controlType instanceof XSComplexTypeDefinition && pathToRoot.equals(""))) { return formSection; } if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addRepeatIfNecessary] for multiple element for type " + controlType.getName() + ", maxOccurs = " + o.maximum); } final Element repeatSection = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":repeat"); //bind instead of repeat //repeatSection.setAttributeNS(NamespaceConstants.XFORMS_NS,NamespaceConstants.XFORMS_PREFIX + ":nodeset",pathToRoot); // bind -> last element in the modelSection Element bind = DOMUtil.getLastChildElement(modelSection); // ALF-9524 fix, previously we've added extra bind element, so last child is not correct for repeatable switch String attribute = bind.getAttribute(NamespaceConstants.XFORMS_PREFIX + ":relevant"); if (controlType instanceof XSComplexTypeDefinition && ((XSComplexTypeDefinition) controlType).getDerivationMethod() == XSConstants.DERIVATION_EXTENSION && attribute != null && !attribute.isEmpty()) { bind = modelSection; } String bindId = null; if (bind != null && bind.getLocalName() != null && "bind".equals(bind.getLocalName())) { bindId = bind.getAttributeNS(null, "id"); } else { LOGGER.warn("[addRepeatIfNecessary] bind not found: " + bind + " (model selection name = " + modelSection.getNodeName() + ")"); //if no bind is found -> modelSection is already a bind, get its parent last child bind = DOMUtil.getLastChildElement(modelSection.getParentNode()); if (bind != null && bind.getLocalName() != null && "bind".equals(bind.getLocalName())) { bindId = bind.getAttributeNS(null, "id"); } else { LOGGER.warn("[addRepeatIfNecessary] bind really not found"); } } repeatSection.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":bind", bindId); this.setXFormsId(repeatSection); //appearance=full is more user friendly repeatSection.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", "full"); formSection.appendChild(repeatSection); //add a group inside the repeat? final Element group = xformsDocument.createElementNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":group"); group.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", "repeated"); this.setXFormsId(group); repeatSection.appendChild(group); return group; }
From source file:org.alfresco.web.forms.xforms.Schema2XForms.java
/** *//*from www.ja v a 2s . c o m*/ private Element addSimpleType(final Document xformsDocument, final Element modelSection, Element formSection, final XSModel schema, final XSTypeDefinition controlType, final String owningElementName, final XSObject owner, final String pathToRoot, final SchemaUtil.Occurrence occurs, final ResourceBundle resourceBundle) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("[addSimpleType] for " + controlType.getName() + " (owningElementName = " + owningElementName + ")," + " occurs = [" + occurs + "]"); if (owner != null) { LOGGER.debug("[addSimpleType] owner is " + owner.getClass() + ", name is " + owner.getName()); } } // create the <xforms:bind> element and add it to the model. boolean isRepeated = isRepeated(occurs, controlType); Element bindElement = this.createBind(xformsDocument, pathToRoot + (isRepeated ? "[position() != last()]" : "")); String bindId = bindElement.getAttributeNS(null, "id"); modelSection.appendChild(bindElement); bindElement = this.startBindElement(bindElement, schema, controlType, owner, occurs); // add a group if a repeat ! if (owner instanceof XSElementDeclaration && occurs.isRepeated()) { final Element groupElement = this.createGroup(xformsDocument, modelSection, formSection, (XSElementDeclaration) owner, resourceBundle); groupElement.setAttributeNS(NamespaceConstants.XFORMS_NS, NamespaceConstants.XFORMS_PREFIX + ":appearance", "repeated"); //set content formSection = groupElement; } //eventual repeat final Element repeatSection = this.addRepeatIfNecessary(xformsDocument, modelSection, formSection, controlType, pathToRoot, occurs); // create the form control element //put a wrapper for the repeat content, but only if it is really a repeat if (repeatSection != formSection) { //if there is a repeat -> create another bind with "." final Element bindElement2 = this.createBind(xformsDocument, "."); final String bindId2 = bindElement2.getAttributeNS(null, "id"); bindElement.appendChild(bindElement2); bindElement = bindElement2; bindId = bindId2; } final String caption = (owner != null ? this.createCaption(owner, resourceBundle) : this.createCaption(owningElementName)); final Element formControl = this.createFormControl(xformsDocument, schema, caption, controlType, owner, bindId, bindElement, occurs, resourceBundle); repeatSection.appendChild(formControl); // if this is a repeatable then set ref to point to current element // not sure if this is a workaround or this is just the way XForms works... // //if (!repeatSection.equals(formSection)) //formControl.setAttributeNS(NamespaceConstants.XFORMS_NS, //NamespaceConstants.XFORMS_PREFIX + ":ref", //"."); //add selector if repeat //if (repeatSection != formSection) //this.addSelector(xformsDocument, (Element) formControl.getParentNode()); return formSection; }