Example usage for org.dom4j Element getQName

List of usage examples for org.dom4j Element getQName

Introduction

In this page you can find the example usage for org.dom4j Element getQName.

Prototype

QName getQName();

Source Link

Document

Returns the QName of this element which represents the local name, the qualified name and the Namespace.

Usage

From source file:org.mule.intents.AppBuilder.java

License:Open Source License

public void addAction(Action action) throws IOException, DocumentException {
    Document snippet = action.getTemplate().loadSnippet();
    addNamespaces(snippet);/*from w  w w.  j ava 2 s  . c  om*/
    addSchemaLocations(snippet);
    for (Object o : snippet.getRootElement().content()) {
        if (o instanceof Element) {
            Element e = (Element) ((Element) o).detach();
            config.getRootElement().add(e);
            if (e.getQName().getName().equals("sub-flow")) {
                Element element = flow.addElement("flow-ref");
                element.addAttribute("name", e.attribute("name").getValue());
                addInterceptor(action, flow);
            }
        }
    }
}

From source file:org.nuxeo.ecm.jsf2.migration.parser.NamespaceParser.java

License:Open Source License

@Override
public void migrate(Document input) throws Exception {
    Element root = input.getRootElement();
    for (String prefix : listPrefixToMigrate) {
        Namespace newNamespace = new Namespace(prefix, EnumPrefixes.getPrefix(prefix).getNamespace());
        Namespace oldNamespace = root.getNamespaceForPrefix(prefix);
        if (oldNamespace != null) {
            root.remove(oldNamespace);//from  w w w . j a  v  a 2 s  .  c  o m
        }
        root.add(newNamespace);

        // Change the name of every elements with the prefix
        StringBuilder prefixXpath = new StringBuilder("//");
        prefixXpath.append(prefix);
        prefixXpath.append(":*");
        // Create a new XPath expression, with the old namespace in order
        // to
        // get the elements matching the expression
        XPath xpath = new Dom4jXPath(prefixXpath.toString());
        SimpleNamespaceContext nc = new SimpleNamespaceContext();
        nc.addNamespace(prefix, oldNamespace.getURI());
        xpath.setNamespaceContext(nc);

        @SuppressWarnings("unchecked")
        List<Element> elementsToMigrate = xpath.selectNodes(input);
        for (Element element : elementsToMigrate) {
            // The namespace to change is not hold by the element but the
            // QName
            QName qname = element.getQName();
            QName newQName = new QName(qname.getName(), newNamespace, qname.getQualifiedName());
            element.setQName(newQName);
        }
    }
}

From source file:org.nuxeo.ecm.platform.publisher.remoting.marshaling.DefaultMarshaler.java

License:Open Source License

protected Object unMarshalSingleObject(String xml, CoreSession coreSession)
        throws PublishingMarshalingException {
    Document document;/*from w  w w . jav a2s  .  c  om*/
    try {
        document = DocumentHelper.parseText(xml);
        org.dom4j.Element rootElem = document.getRootElement();

        QName qname = rootElem.getQName();
        String name = rootElem.getName();

        if (name.equals("publicationNode")) {
            return nodeMarshaler.unMarshalPublicationNode(xml);
        } else if (name.equals("publishedDocument")) {
            return publishedDocumentMarshaler.unMarshalPublishedDocument(xml);
        } else if (name.equals("document")) {
            return documentModelMarshaler.unMarshalDocument(xml, coreSession);
        } else if (name.equals("documentLocation")) {
            return docLocMarshaler.unMarshalDocumentLocation(xml);
        } else if (name.equals("list")) {
            List<Object> lst = new ArrayList<Object>();
            for (Iterator i = rootElem.elementIterator("listitem"); i.hasNext();) {
                org.dom4j.Element el = (org.dom4j.Element) i.next();
                if (el.elements().size() == 0) {
                    lst.add(el.getText());
                } else {
                    lst.add(unMarshalSingleObject(((org.dom4j.Element) el.elements().get(0)).asXML(),
                            coreSession));
                }
            }
            return lst;
        } else if (name.equals("map")) {
            Map map = new HashMap();
            for (Iterator i = rootElem.elementIterator("mapitem"); i.hasNext();) {
                org.dom4j.Element el = (org.dom4j.Element) i.next();

                Object value = null;
                if (el.elements().size() > 0) {
                    value = unMarshalSingleObject(((org.dom4j.Element) (el).elements().get(0)).asXML(),
                            coreSession);
                } else {
                    value = el.getText();
                }
                String key = el.attributeValue("name");
                map.put(key, value);
            }
            return map;
        }
    } catch (Throwable e) {
        throw new PublishingMarshalingException("Error during unmarshaling", e);
    }

    throw new PublishingMarshalingException("Unable to unmarshal data");

}

From source file:org.opencms.xml.CmsXmlContentDefinition.java

License:Open Source License

/**
 * Validates the given element as a complex type sequence.<p>
 * //  w  w  w . j  a v a  2  s .  c  o m
 * @param element the element to validate
 * @param includes the XML schema includes
 * 
 * @return a data structure containing the validated complex type sequence data 
 * 
 * @throws CmsXmlException if the validation fails
 */
protected static CmsXmlComplexTypeSequence validateComplexTypeSequence(Element element,
        Set<CmsXmlContentDefinition> includes) throws CmsXmlException {

    validateAttributesExists(element, new String[] { XSD_ATTRIBUTE_NAME }, new String[0]);

    String name = validateAttribute(element, XSD_ATTRIBUTE_NAME, null);

    // now check the type definition list
    List<Element> mainElements = CmsXmlGenericWrapper.elements(element);
    if ((mainElements.size() != 1) && (mainElements.size() != 2)) {
        throw new CmsXmlException(Messages.get().container(Messages.ERR_TS_SUBELEMENT_COUNT_2,
                element.getUniquePath(), new Integer(mainElements.size())));
    }

    boolean hasLanguageAttribute = false;
    if (mainElements.size() == 2) {
        // two elements in the master list: the second must be the "language" attribute definition

        Element typeAttribute = mainElements.get(1);
        if (!XSD_NODE_ATTRIBUTE.equals(typeAttribute.getQName())) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_ELEMENT_NAME_3,
                    typeAttribute.getUniquePath(), XSD_NODE_ATTRIBUTE.getQualifiedName(),
                    typeAttribute.getQName().getQualifiedName()));
        }
        validateAttribute(typeAttribute, XSD_ATTRIBUTE_NAME, XSD_ATTRIBUTE_VALUE_LANGUAGE);
        validateAttribute(typeAttribute, XSD_ATTRIBUTE_TYPE, CmsXmlLocaleValue.TYPE_NAME);
        try {
            validateAttribute(typeAttribute, XSD_ATTRIBUTE_USE, XSD_ATTRIBUTE_VALUE_REQUIRED);
        } catch (CmsXmlException e) {
            validateAttribute(typeAttribute, XSD_ATTRIBUTE_USE, XSD_ATTRIBUTE_VALUE_OPTIONAL);
        }
        // no error: then the language attribute is valid
        hasLanguageAttribute = true;
    }

    // the type of the sequence
    SequenceType sequenceType;
    int choiceMaxOccurs = 0;

    // check the main element type sequence
    Element typeSequenceElement = mainElements.get(0);
    if (!XSD_NODE_SEQUENCE.equals(typeSequenceElement.getQName())) {
        if (!XSD_NODE_CHOICE.equals(typeSequenceElement.getQName())) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_ELEMENT_NAME_4,
                    new Object[] { typeSequenceElement.getUniquePath(), XSD_NODE_SEQUENCE.getQualifiedName(),
                            XSD_NODE_CHOICE.getQualifiedName(),
                            typeSequenceElement.getQName().getQualifiedName() }));
        } else {
            // this is a xsd:choice, check if this is single or multiple choice
            String minOccursStr = typeSequenceElement.attributeValue(XSD_ATTRIBUTE_MIN_OCCURS);
            int minOccurs = 1;
            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(minOccursStr)) {
                try {
                    minOccurs = Integer.parseInt(minOccursStr.trim());
                } catch (NumberFormatException e) {
                    throw new CmsXmlException(
                            Messages.get().container(Messages.ERR_EL_BAD_ATTRIBUTE_3, element.getUniquePath(),
                                    XSD_ATTRIBUTE_MIN_OCCURS, minOccursStr == null ? "1" : minOccursStr));
                }
            }
            String maxOccursStr = typeSequenceElement.attributeValue(XSD_ATTRIBUTE_MAX_OCCURS);
            choiceMaxOccurs = 1;
            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(maxOccursStr)) {
                if (CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_UNBOUNDED.equals(maxOccursStr.trim())) {
                    choiceMaxOccurs = Integer.MAX_VALUE;
                } else {
                    try {
                        choiceMaxOccurs = Integer.parseInt(maxOccursStr.trim());
                    } catch (NumberFormatException e) {
                        throw new CmsXmlException(Messages.get().container(Messages.ERR_EL_BAD_ATTRIBUTE_3,
                                element.getUniquePath(), XSD_ATTRIBUTE_MAX_OCCURS, maxOccursStr));
                    }
                }
            }
            if ((minOccurs == 0) && (choiceMaxOccurs == 1)) {
                // minOccurs 0 and maxOccurs 1, this is a single choice sequence
                sequenceType = SequenceType.SINGLE_CHOICE;
            } else {
                // this is a multiple choice sequence
                if (minOccurs > choiceMaxOccurs) {
                    throw new CmsXmlException(
                            Messages.get().container(Messages.ERR_EL_BAD_ATTRIBUTE_3, element.getUniquePath(),
                                    XSD_ATTRIBUTE_MIN_OCCURS, minOccursStr == null ? "1" : minOccursStr));
                }
                sequenceType = SequenceType.MULTIPLE_CHOICE;
            }
        }
    } else {
        // this is a simple sequence
        sequenceType = SequenceType.SEQUENCE;
    }

    // check the type definition sequence
    List<Element> typeSequenceElements = CmsXmlGenericWrapper.elements(typeSequenceElement);
    if (typeSequenceElements.size() < 1) {
        throw new CmsXmlException(Messages.get().container(Messages.ERR_TS_SUBELEMENT_TOOFEW_3,
                typeSequenceElement.getUniquePath(), new Integer(1), new Integer(typeSequenceElements.size())));
    }

    // now add all type definitions from the schema
    List<I_CmsXmlSchemaType> sequence = new ArrayList<I_CmsXmlSchemaType>();

    if (hasLanguageAttribute) {
        // only generate types for sequence node with language attribute

        CmsXmlContentTypeManager typeManager = OpenCms.getXmlContentTypeManager();
        Iterator<Element> i = typeSequenceElements.iterator();
        while (i.hasNext()) {
            Element typeElement = i.next();
            if (sequenceType != SequenceType.SEQUENCE) {
                // in case of xsd:choice, need to make sure "minOccurs" for all type elements is 0
                String minOccursStr = typeElement.attributeValue(XSD_ATTRIBUTE_MIN_OCCURS);
                int minOccurs = 1;
                if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(minOccursStr)) {
                    try {
                        minOccurs = Integer.parseInt(minOccursStr.trim());
                    } catch (NumberFormatException e) {
                        // ignore
                    }
                }
                // minOccurs must be "0"
                if (minOccurs != 0) {
                    throw new CmsXmlException(Messages.get().container(Messages.ERR_EL_BAD_ATTRIBUTE_3,
                            typeElement.getUniquePath(), XSD_ATTRIBUTE_MIN_OCCURS,
                            minOccursStr == null ? "1" : minOccursStr));
                }
            }
            // create the type with the type manager
            I_CmsXmlSchemaType type = typeManager.getContentType(typeElement, includes);
            if (sequenceType == SequenceType.MULTIPLE_CHOICE) {
                // if this is a multiple choice sequence, 
                // all elements must have "minOccurs" 0 or 1 and "maxOccurs" of 1
                if ((type.getMinOccurs() < 0) || (type.getMinOccurs() > 1) || (type.getMaxOccurs() != 1)) {
                    throw new CmsXmlException(Messages.get().container(Messages.ERR_EL_BAD_ATTRIBUTE_3,
                            typeElement.getUniquePath(), XSD_ATTRIBUTE_MAX_OCCURS,
                            typeElement.attributeValue(XSD_ATTRIBUTE_MAX_OCCURS)));
                }
            }
            sequence.add(type);
        }
    } else {
        // generate a nested content definition for the main type sequence

        Element e = typeSequenceElements.get(0);
        String typeName = validateAttribute(e, XSD_ATTRIBUTE_NAME, null);
        String minOccurs = validateAttribute(e, XSD_ATTRIBUTE_MIN_OCCURS, XSD_ATTRIBUTE_VALUE_ZERO);
        String maxOccurs = validateAttribute(e, XSD_ATTRIBUTE_MAX_OCCURS, XSD_ATTRIBUTE_VALUE_UNBOUNDED);
        validateAttribute(e, XSD_ATTRIBUTE_TYPE, createTypeName(typeName));

        CmsXmlNestedContentDefinition cd = new CmsXmlNestedContentDefinition(null, typeName, minOccurs,
                maxOccurs);
        sequence.add(cd);
    }

    // return a data structure with the collected values
    return new CmsXmlComplexTypeSequence(name, sequence, hasLanguageAttribute, sequenceType, choiceMaxOccurs);
}

From source file:org.opencms.xml.CmsXmlContentDefinition.java

License:Open Source License

/**
 * Internal method to unmarshal (read) a XML content definition instance from a XML document.<p>
 * //from  w w  w . j  a  va 2  s  .c  o m
 * It is assumed that the XML content definition cache has already been tested and the document 
 * has not been found in the cache. After the XML content definition has been successfully created, 
 * it is placed in the cache.<p>
 * 
 * @param document the XML document to generate a XML content definition from
 * @param schemaLocation the location from which the XML schema was read (system id)
 * @param resolver the XML entity resolver used by the given XML document
 * 
 * @return a XML content definition instance unmarshalled from the XML document
 * 
 * @throws CmsXmlException if something goes wrong
 */
private static CmsXmlContentDefinition unmarshalInternal(Document document, String schemaLocation,
        EntityResolver resolver) throws CmsXmlException {

    // analyze the document and generate the XML content type definition        
    Element root = document.getRootElement();
    if (!XSD_NODE_SCHEMA.equals(root.getQName())) {
        // schema node is required
        throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_NO_SCHEMA_NODE_0));
    }

    List<Element> includes = CmsXmlGenericWrapper.elements(root, XSD_NODE_INCLUDE);
    if (includes.size() < 1) {
        // one include is required
        throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_ONE_INCLUDE_REQUIRED_0));
    }

    Element include = includes.get(0);
    String target = validateAttribute(include, XSD_ATTRIBUTE_SCHEMA_LOCATION, null);
    if (!XSD_INCLUDE_OPENCMS.equals(target)) {
        // the first include must point to the default OpenCms standard schema include
        throw new CmsXmlException(
                Messages.get().container(Messages.ERR_CD_FIRST_INCLUDE_2, XSD_INCLUDE_OPENCMS, target));
    }

    boolean recursive = false;
    Set<CmsXmlContentDefinition> nestedDefinitions = new HashSet<CmsXmlContentDefinition>();
    if (includes.size() > 1) {
        // resolve additional, nested include calls
        for (int i = 1; i < includes.size(); i++) {

            Element inc = includes.get(i);
            String schemaLoc = validateAttribute(inc, XSD_ATTRIBUTE_SCHEMA_LOCATION, null);
            if (!(schemaLoc.equals(schemaLocation))) {
                InputSource source = null;
                try {
                    source = resolver.resolveEntity(null, schemaLoc);
                } catch (Exception e) {
                    throw new CmsXmlException(
                            Messages.get().container(Messages.ERR_CD_BAD_INCLUDE_1, schemaLoc));
                }
                CmsXmlContentDefinition xmlContentDefinition = unmarshal(source, schemaLoc, resolver);
                nestedDefinitions.add(xmlContentDefinition);
            } else {
                // recursion
                recursive = true;
            }
        }
    }

    List<Element> elements = CmsXmlGenericWrapper.elements(root, XSD_NODE_ELEMENT);
    if (elements.size() != 1) {
        // only one root element is allowed
        throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_ROOT_ELEMENT_COUNT_1,
                XSD_INCLUDE_OPENCMS, new Integer(elements.size())));
    }

    // collect the data from the root element node
    Element main = elements.get(0);
    String name = validateAttribute(main, XSD_ATTRIBUTE_NAME, null);

    // now process the complex types
    List<Element> complexTypes = CmsXmlGenericWrapper.elements(root, XSD_NODE_COMPLEXTYPE);
    if (complexTypes.size() != 2) {
        // exactly two complex types are required
        throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_COMPLEX_TYPE_COUNT_1,
                new Integer(complexTypes.size())));
    }

    // get the outer element sequence, this must be the first element 
    CmsXmlComplexTypeSequence outerSequence = validateComplexTypeSequence(complexTypes.get(0),
            nestedDefinitions);
    CmsXmlNestedContentDefinition outer = (CmsXmlNestedContentDefinition) outerSequence.getSequence().get(0);

    // make sure the inner and outer element names are as required
    String outerTypeName = createTypeName(name);
    String innerTypeName = createTypeName(outer.getName());
    validateAttribute(complexTypes.get(0), XSD_ATTRIBUTE_NAME, outerTypeName);
    validateAttribute(complexTypes.get(1), XSD_ATTRIBUTE_NAME, innerTypeName);
    validateAttribute(main, XSD_ATTRIBUTE_TYPE, outerTypeName);

    // generate the result XML content definition
    CmsXmlContentDefinition result = new CmsXmlContentDefinition(name, null, schemaLocation);

    // set the nested definitions
    result.m_includes = nestedDefinitions;
    // set the schema document
    result.m_schemaDocument = document;

    // the inner name is the element name set in the outer sequence
    result.setInnerName(outer.getName());
    if (recursive) {
        nestedDefinitions.add(result);
    }

    // get the inner element sequence, this must be the second element 
    CmsXmlComplexTypeSequence innerSequence = validateComplexTypeSequence(complexTypes.get(1),
            nestedDefinitions);

    // add the types from the main sequence node
    Iterator<I_CmsXmlSchemaType> it = innerSequence.getSequence().iterator();
    while (it.hasNext()) {
        result.addType(it.next());
    }

    // store if this content definition contains a xsd:choice sequence
    result.m_sequenceType = innerSequence.getSequenceType();
    result.m_choiceMaxOccurs = innerSequence.getChoiceMaxOccurs();

    // resolve the XML content handler information
    List<Element> annotations = CmsXmlGenericWrapper.elements(root, XSD_NODE_ANNOTATION);
    I_CmsXmlContentHandler contentHandler = null;
    Element appInfoElement = null;

    if (annotations.size() > 0) {
        List<Element> appinfos = CmsXmlGenericWrapper.elements(annotations.get(0), XSD_NODE_APPINFO);

        if (appinfos.size() > 0) {
            // the first appinfo node contains the specific XML content data 
            appInfoElement = appinfos.get(0);

            // check for a special content handler in the appinfo node
            Element handlerElement = appInfoElement.element("handler");
            if (handlerElement != null) {
                String className = handlerElement.attributeValue("class");
                if (className != null) {
                    contentHandler = OpenCms.getXmlContentTypeManager().getFreshContentHandler(className);
                }
            }
        }
    }

    if (contentHandler == null) {
        // if no content handler is defined, the default handler is used
        contentHandler = OpenCms.getXmlContentTypeManager()
                .getFreshContentHandler(CmsDefaultXmlContentHandler.class.getName());
    }

    // analyze the app info node with the selected XML content handler
    contentHandler.initialize(appInfoElement, result);
    result.m_contentHandler = contentHandler;

    result.freeze();

    if (resolver instanceof CmsXmlEntityResolver) {
        // put the generated content definition in the cache
        ((CmsXmlEntityResolver) resolver).cacheContentDefinition(schemaLocation, result);
    }

    return result;
}

From source file:org.opencms.xml.CmsXmlContentTypeManager.java

License:Open Source License

/**
 * Generates an initialized instance of a XML content type definition
 * from the given XML schema element.<p>
 * //from  w  ww. ja  va  2s  . co m
 * @param typeElement the element to generate the XML content type definition from
 * @param nestedDefinitions the nested (included) XML content sub-definitions
 * 
 * @return an initialized instance of a XML content type definition
 * @throws CmsXmlException in case the element does not describe a valid XML content type definition
 */
public I_CmsXmlSchemaType getContentType(Element typeElement, Set<CmsXmlContentDefinition> nestedDefinitions)
        throws CmsXmlException {

    if (!CmsXmlContentDefinition.XSD_NODE_ELEMENT.equals(typeElement.getQName())) {
        throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0));
    }
    if (typeElement.elements().size() > 0) {
        throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0));
    }

    String elementName = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_NAME);
    String typeName = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_TYPE);
    String defaultValue = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_DEFAULT);
    String maxOccrs = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_MAX_OCCURS);
    String minOccrs = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_MIN_OCCURS);

    if (CmsStringUtil.isEmpty(elementName) || CmsStringUtil.isEmpty(typeName)) {
        throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0));
    }

    boolean simpleType = true;
    I_CmsXmlSchemaType schemaType = m_registeredTypes.get(typeName);
    if (schemaType == null) {

        // the name is not a simple type, try to resolve from the nested schemas
        Iterator<CmsXmlContentDefinition> i = nestedDefinitions.iterator();
        while (i.hasNext()) {

            CmsXmlContentDefinition cd = i.next();
            if (typeName.equals(cd.getTypeName())) {

                simpleType = false;
                return new CmsXmlNestedContentDefinition(cd, elementName, minOccrs, maxOccrs);
            }
        }

        if (simpleType) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_UNKNOWN_SCHEMA_1, typeName));
        }
    }

    if (simpleType && (schemaType != null)) {
        schemaType = schemaType.newInstance(elementName, minOccrs, maxOccrs);

        if (CmsStringUtil.isNotEmpty(defaultValue)) {
            schemaType.setDefault(defaultValue);
        }
    }

    return schemaType;
}

From source file:org.opencms.xml.types.CmsXmlHtmlValue.java

License:Open Source License

/**
 * @see org.opencms.xml.types.I_CmsXmlSchemaType#generateXml(org.opencms.file.CmsObject, org.opencms.xml.I_CmsXmlDocument, org.dom4j.Element, java.util.Locale)
 *//*w ww .ja v a 2s.  c  om*/
@Override
public Element generateXml(CmsObject cms, I_CmsXmlDocument document, Element root, Locale locale) {

    Element element = root.addElement(getName());
    int index = element.getParent().elements(element.getQName()).indexOf(element);
    element.addAttribute(CmsXmlPage.ATTRIBUTE_NAME, getName() + index);
    element.addElement(CmsXmlPage.NODE_LINKS);
    element.addElement(CmsXmlPage.NODE_CONTENT);

    // get the default value from the content handler
    String defaultValue = document.getHandler().getDefault(cms, this, locale);
    if (defaultValue != null) {
        try {
            I_CmsXmlContentValue value = createValue(document, element, locale);
            value.setStringValue(cms, defaultValue);
        } catch (CmsRuntimeException e) {
            // should not happen if default value is correct
            LOG.error(Messages.get().getBundle().key(Messages.ERR_XMLCONTENT_INVALID_ELEM_DEFAULT_1,
                    defaultValue), e);
            element.clearContent();
        }
    }
    return element;
}

From source file:org.orbeon.oxf.transformer.xupdate.TemplatesHandlerImpl.java

License:Open Source License

private Statement[] parseStatements(List nodes) {
    List statements = new ArrayList();
    for (Iterator i = nodes.iterator(); i.hasNext();) {
        Node node = (Node) i.next();
        if (node.getNodeType() == Node.TEXT_NODE) {
            if (!"".equals(node.getText().trim()))
                statements.add(new Text(node.getText().trim()));
        } else if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            NamespaceContext namespaceContext = new SimpleNamespaceContext(
                    Dom4jUtils.getNamespaceContext(element));
            if (XUpdateConstants.XUPDATE_NAMESPACE_URI.equals(element.getNamespaceURI())) {
                if (element.getName().equals("remove")) {
                    statements.add(new Remove((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("update")) {
                    statements/*w  w  w  . j ava2s .c  o  m*/
                            .add(new Update((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("append")) {
                    statements.add(new Append((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext, element.attributeValue("child"),
                            parseStatements(element.content())));
                } else if (element.getName().equals("insert-before")) {
                    statements.add(
                            new InsertBefore((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("insert-after")) {
                    statements.add(
                            new InsertAfter((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("for-each")) {
                    statements
                            .add(new ForEach((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("while")) {
                    statements.add(new While((LocationData) element.getData(), element.attributeValue("select"),
                            namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("value-of")) {
                    statements.add(new ValueOf((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("copy-of")) {
                    statements.add(new CopyOf((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("node-set")) {
                    statements.add(new NodeSet((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("attribute")) {
                    statements.add(new Attribute((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("namespace")) {
                    statements.add(new Namespace((LocationData) element.getData(),
                            element.attributeValue("name"), element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("element")) {
                    statements.add(new DynamicElement((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("if")) {
                    statements.add(new If((LocationData) element.getData(), element.attributeValue("test"),
                            namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("choose")) {
                    List whenTests = new ArrayList();
                    List whenNamespaceContext = new ArrayList();
                    List whenStatements = new ArrayList();
                    for (Iterator j = element.elements("when").iterator(); j.hasNext();) {
                        Element whenElement = (Element) j.next();
                        whenTests.add(whenElement.attributeValue("test"));
                        whenNamespaceContext
                                .add(new SimpleNamespaceContext(Dom4jUtils.getNamespaceContext(whenElement)));
                        whenStatements.add(parseStatements(whenElement.content()));
                    }
                    Element otherwiseElement = element.element("otherwise");
                    statements.add(new Choose((LocationData) element.getData(),
                            (String[]) whenTests.toArray(new String[whenTests.size()]),
                            (NamespaceContext[]) whenNamespaceContext
                                    .toArray(new NamespaceContext[whenNamespaceContext.size()]),
                            (Statement[][]) whenStatements.toArray(new Statement[whenStatements.size()][]),
                            otherwiseElement == null ? null : parseStatements(otherwiseElement.content())));
                } else if (element.getName().equals("variable")) {
                    statements.add(new Variable((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("assign")) {
                    statements.add(new Assign((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("function")) {
                    statements.add(new Function((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("param")) {
                    statements.add(new Param((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("message")) {
                    statements.add(
                            new Message((LocationData) element.getData(), parseStatements(element.content())));
                } else if (element.getName().equals("error")) {
                    statements.add(
                            new Error((LocationData) element.getData(), parseStatements(element.content())));
                } else {
                    throw new ValidationException(
                            "Unsupported XUpdate element '" + element.getQualifiedName() + "'",
                            (LocationData) element.getData());
                }
            } else {
                Element staticElement = new NonLazyUserDataElement(element.getQName());
                List childNodes = new ArrayList();
                for (Iterator j = element.attributes().iterator(); j.hasNext();)
                    staticElement.add((org.dom4j.Attribute) ((org.dom4j.Attribute) j.next()).clone());
                for (Iterator j = element.content().iterator(); j.hasNext();) {
                    Node child = (Node) j.next();
                    if (child instanceof org.dom4j.Namespace) {
                        staticElement.add((Node) child.clone());
                    } else {
                        childNodes.add(child);
                    }
                }
                statements.add(new StaticElement((LocationData) element.getData(), staticElement,
                        parseStatements(childNodes)));
            }
        } else if (node.getNodeType() == Node.NAMESPACE_NODE) {
            // Ignore namespace declarations
        } else {
            throw new OXFException("Unsupported node: " + node.getNodeTypeName());
        }
    }
    return (Statement[]) statements.toArray(new Statement[statements.size()]);
}

From source file:org.orbeon.oxf.xforms.action.XFormsActionInterpreter.java

License:Open Source License

/**
 * Execute an XForms action.//from   w w w . ja v a2s  .  c  o  m
 */
public void runAction(ElementAnalysis actionAnalysis) {

    final Element actionElement = actionAnalysis.element();
    final ActionTrait actionTrait = (ActionTrait) actionAnalysis;

    try {

        // Condition
        final String ifConditionAttribute = actionTrait.ifConditionJava();
        final String whileIterationAttribute = actionTrait.whileConditionJava();
        final String iterateIterationAttribute = actionTrait.iterateJava();

        // Push @iterate (if present) within the @model and @context context
        final NamespaceMapping namespaceMapping = actionAnalysis.namespaceMapping();
        // TODO: function context
        _actionXPathContext.pushBinding(iterateIterationAttribute, actionAnalysis.contextJava(), null,
                actionAnalysis.modelJava(), null, actionElement, namespaceMapping,
                getSourceEffectiveId(actionElement), actionAnalysis.scope(), false);

        // NOTE: At this point, the context has already been set to the current action element
        if (iterateIterationAttribute != null) {
            // Gotta iterate

            // NOTE: It's not 100% how @context and @iterate should interact here. Right now @iterate overrides @context,
            // i.e. @context is evaluated first, and @iterate sets a new context for each iteration
            {
                final List<Item> currentNodeset = _actionXPathContext.getCurrentNodeset();
                final int iterationCount = currentNodeset.size();
                for (int index = 1; index <= iterationCount; index++) {

                    // Push iteration
                    _actionXPathContext.pushIteration(index);

                    final Item overriddenContextNodeInfo = currentNodeset.get(index - 1);
                    runSingleIteration(actionAnalysis, actionElement.getQName(), ifConditionAttribute,
                            whileIterationAttribute, true, overriddenContextNodeInfo);

                    // Restore context
                    _actionXPathContext.popBinding();
                }
            }
        } else {
            // Do a single iteration run (but this may repeat over the @while condition!)
            runSingleIteration(actionAnalysis, actionElement.getQName(), ifConditionAttribute,
                    whileIterationAttribute, _actionXPathContext.hasOverriddenContext(),
                    _actionXPathContext.getContextItem());
        }

        // Restore
        _actionXPathContext.popBinding();
    } catch (Exception e) {
        throw OrbeonLocationException.wrapException(e,
                new ExtendedLocationData((LocationData) actionElement.getData(), "running XForms action",
                        actionElement,
                        new String[] { "action name", actionElement.getQName().getQualifiedName() }));
    }
}

From source file:org.orbeon.oxf.xforms.xbl.XBLTransformer.java

License:Open Source License

/**
 * Apply an XBL transformation, i.e. apply xbl:content, xbl:attr, etc.
 *
 * NOTE: This mutates shadowTreeDocument.
 *///w  ww  .j  av  a 2  s . c o m
public static Document transform(final Document shadowTreeDocument, final Element boundElement,
        final boolean excludeNestedHandlers, final boolean excludeNestedLHHA) {

    final DocumentWrapper documentWrapper = new DocumentWrapper(boundElement.getDocument(), null,
            XPathCache.getGlobalConfiguration());

    Dom4jUtils.visitSubtree(shadowTreeDocument.getRootElement(), new Dom4jUtils.VisitorListener() {

        boolean isNestedHandler(Element e) {
            return e.getParent() == boundElement && EventHandlerImpl.isEventHandler(e);
        }

        boolean isNestedLHHA(Element e) {
            return e.getParent() == boundElement && LHHA.isLHHA(e);
        }

        boolean mustFilterOut(Element e) {
            return excludeNestedHandlers && isNestedHandler(e) || excludeNestedLHHA && isNestedLHHA(e);
        }

        public void startElement(Element element) {

            // Handle xbl:content

            final boolean isXBLContent = element.getQName().equals(XBL_CONTENT_QNAME);
            final List<Node> resultingNodes;
            if (isXBLContent) {
                final String includesAttribute = element.attributeValue(XFormsConstants.INCLUDES_QNAME);
                final String scopeAttribute = element.attributeValue(XFormsConstants.XXBL_SCOPE_QNAME);
                final List<Node> contentToInsert;
                if (includesAttribute == null) {
                    // All bound node content must be copied over (except nested handlers if requested)
                    final List<Node> elementContent = Dom4jUtils.content(boundElement);
                    final List<Node> clonedContent = new ArrayList<Node>();
                    for (final Node node : elementContent) {
                        if (node instanceof Element) {
                            final Element currentElement = (Element) node;
                            if (!mustFilterOut(currentElement))
                                clonedContent.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement));
                        } else if (!(node instanceof Namespace)) {
                            clonedContent.add(Dom4jUtils.createCopy(node));
                        }
                    }

                    contentToInsert = clonedContent;
                } else {
                    // Apply CSS selector

                    // Convert CSS to XPath
                    final String xpathExpression = CSSParser.toXPath(includesAttribute);

                    final NodeInfo boundElementInfo = documentWrapper.wrap(boundElement);

                    // TODO: don't use getNamespaceContext() as this is already computed for the bound element
                    final List<Object> elements = XPathCache.evaluate(boundElementInfo, xpathExpression,
                            new NamespaceMapping(Dom4jUtils.getNamespaceContext(element)), null, null, null,
                            null, null, null);// TODO: locationData

                    if (elements.size() > 0) {
                        // Clone all the resulting elements
                        contentToInsert = new ArrayList<Node>(elements.size());
                        for (Object o : elements) {
                            final NodeInfo currentNodeInfo = (NodeInfo) o;
                            final Element currentElement = (Element) ((VirtualNode) currentNodeInfo)
                                    .getUnderlyingNode();

                            if (!mustFilterOut(currentElement))
                                contentToInsert.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement));
                        }
                    } else {
                        // Clone all the element's children if any
                        // See: http://www.w3.org/TR/xbl/#the-content
                        contentToInsert = new ArrayList<Node>(element.nodeCount());
                        for (Object o : element.elements()) {
                            final Element currentElement = (Element) o;
                            if (!mustFilterOut(currentElement))
                                contentToInsert.add(Dom4jUtils.copyElementCopyParentNamespaces(currentElement));
                        }
                    }
                }

                // Insert content if any
                if (contentToInsert != null && contentToInsert.size() > 0) {
                    final List<Node> parentContent = Dom4jUtils.content(element.getParent());
                    final int elementIndex = parentContent.indexOf(element);
                    parentContent.addAll(elementIndex, contentToInsert);
                }

                // Remove <xbl:content> from shadow tree
                element.detach();

                resultingNodes = contentToInsert;

                if (!StringUtils.isBlank(scopeAttribute)) {
                    // If author specified scope attribute, use it
                    setAttribute(resultingNodes, XFormsConstants.XXBL_SCOPE_QNAME, scopeAttribute, null);
                } else {
                    // By default, set xxbl:scope="outer" on resulting elements
                    setAttribute(resultingNodes, XFormsConstants.XXBL_SCOPE_QNAME, "outer", null);
                }
            } else {
                // Element is simply kept
                resultingNodes = Collections.singletonList((Node) element);
            }

            // Handle attribute forwarding
            final Attribute xblAttr = element.attribute(XBL_ATTR_QNAME); // standard xbl:attr (custom syntax)
            final Attribute xxblAttr = element.attribute(XXBL_ATTR_QNAME); // extension xxbl:attr (XPath expression)
            if (xblAttr != null) {
                // Detach attribute (not strictly necessary?)
                xblAttr.detach();
                // Get attribute value
                final String xblAttrString = xblAttr.getValue();
                final StringTokenizer st = new StringTokenizer(xblAttrString);
                while (st.hasMoreTokens()) {
                    final String currentValue = st.nextToken();

                    final int equalIndex = currentValue.indexOf('=');
                    if (equalIndex == -1) {
                        // No a=b pair, just a single QName
                        final QName valueQName = Dom4jUtils.extractTextValueQName(element, currentValue, true);
                        if (!valueQName.getNamespaceURI().equals(XFormsConstants.XBL_NAMESPACE_URI)) {
                            // This is not xbl:text, copy the attribute
                            setAttribute(resultingNodes, valueQName, boundElement.attributeValue(valueQName),
                                    boundElement);
                        } else {
                            // This is xbl:text
                            // "The xbl:text value cannot occur by itself in the list"
                        }

                    } else {
                        // a=b pair
                        final QName leftSideQName;
                        {
                            final String leftSide = currentValue.substring(0, equalIndex);
                            leftSideQName = Dom4jUtils.extractTextValueQName(element, leftSide, true);
                        }
                        final QName rightSideQName;
                        {
                            final String rightSide = currentValue.substring(equalIndex + 1);
                            rightSideQName = Dom4jUtils.extractTextValueQName(element, rightSide, true);
                        }

                        final boolean isLeftSideXBLText = leftSideQName.getNamespaceURI()
                                .equals(XFormsConstants.XBL_NAMESPACE_URI);
                        final boolean isRightSideXBLText = rightSideQName.getNamespaceURI()
                                .equals(XFormsConstants.XBL_NAMESPACE_URI);

                        final String rightSideValue;
                        final Element namespaceElement;
                        if (!isRightSideXBLText) {
                            // Get attribute value
                            rightSideValue = boundElement.attributeValue(rightSideQName);
                            namespaceElement = boundElement;
                        } else {
                            // Get text value

                            // "any text nodes (including CDATA nodes and whitespace text nodes) that are
                            // explicit children of the bound element must have their data concatenated"
                            rightSideValue = boundElement.getText();// must use getText() and not stringValue()
                            namespaceElement = null;
                        }

                        if (rightSideValue != null) {
                            // NOTE: XBL doesn't seem to says what should happen if the source attribute is not
                            // found! We assume the rule is ignored in this case.
                            if (!isLeftSideXBLText) {
                                // Set attribute value
                                setAttribute(resultingNodes, leftSideQName, rightSideValue, namespaceElement);
                            } else {
                                // Set text value

                                // "value of the attribute on the right-hand side are to be represented as text
                                // nodes underneath the shadow element"

                                // TODO: "If the element has any child nodes in the DOM (any nodes, including
                                // comment nodes, whitespace text nodes, or even empty CDATA nodes) then the pair
                                // is in error and UAs must ignore it, meaning the attribute value is not forwarded"

                                setText(resultingNodes, rightSideValue);
                            }
                        }
                    }
                    // TODO: handle xbl:lang?
                    // TODO: handle type specifiers?
                }
            } else if (xxblAttr != null) {
                // Detach attribute (not strictly necessary?)
                xxblAttr.detach();
                // Get attribute value
                final String xxblAttrString = xxblAttr.getValue();

                final NodeInfo boundElementInfo = documentWrapper.wrap(boundElement);

                // TODO: don't use getNamespaceContext() as this is already computed for the bound element
                final List<Object> nodeInfos = XPathCache.evaluate(boundElementInfo, xxblAttrString,
                        new NamespaceMapping(Dom4jUtils.getNamespaceContext(element)), null, null, null, null,
                        null, null);// TODO: locationData

                if (nodeInfos.size() > 0) {
                    for (Object nodeInfo : nodeInfos) {
                        final NodeInfo currentNodeInfo = (NodeInfo) nodeInfo;
                        if (currentNodeInfo.getNodeKind() == org.w3c.dom.Node.ATTRIBUTE_NODE) {
                            // This is an attribute
                            final Attribute currentAttribute = (Attribute) ((VirtualNode) currentNodeInfo)
                                    .getUnderlyingNode();
                            setAttribute(resultingNodes, currentAttribute.getQName(),
                                    currentAttribute.getValue(), currentAttribute.getParent());
                        }
                    }
                }
            }

            // Prefix resulting xhtml:*/(@id |@for)

            // NOTE: We could also do the prefixing in the handlers, when the page is output.
            //
            // * Benefit of prefixing here: done statically
            // * Drawback of prefixing here: in the future if we try to reuse simple shadow trees this won't work

            //                    {
            //                        if (resultingNodes != null && resultingNodes.size() > 0) {
            //                            for (Iterator i = resultingNodes.iterator(); i.hasNext();) {
            //                                final Node node = (Node) i.next();
            //                                if (node instanceof Element) {
            //                                    Dom4jUtils.visitSubtree((Element) node, new Dom4jUtils.VisitorListener() {
            //                                        public void startElement(Element element) {
            //                                            if (XMLConstants.XHTML_NAMESPACE_URI.equals(element.getNamespaceURI())) {
            //                                                // Found XHTML element
            //
            //                                                // Update @id and @for if any
            //                                                final Attribute idAttribute = element.attribute("id");
            //                                                if (idAttribute != null) {
            //                                                    idAttribute.setValue(prefix + idAttribute.getValue());
            //                                                }
            //                                                final Attribute forAttribute = element.attribute("for");
            //                                                if (forAttribute != null) {
            //                                                    forAttribute.setValue(prefix + forAttribute.getValue());
            //                                                }
            //                                            }
            //                                        }
            //
            //                                        public void endElement(Element element) {
            //                                        }
            //
            //                                        public void text(Text text) {
            //                                        }
            //                                    });
            //                                }
            //                            }
            //                        }
            //                    }
        }

        private void setAttribute(List<Node> nodes, QName attributeQName, String attributeValue,
                Element namespaceElement) {
            if (nodes != null && nodes.size() > 0) {
                for (final Node node : nodes) {
                    if (node instanceof Element) {
                        final Element element = ((Element) node);
                        // Copy missing namespaces, so that copying things like ref="foo:bar" work as expected
                        Dom4jUtils.copyMissingNamespaces(namespaceElement, element);
                        element.addAttribute(attributeQName, attributeValue);
                    }
                }
            }
        }

        private void setText(List<Node> nodes, String value) {
            if (nodes != null && nodes.size() > 0) {
                for (final Node node : nodes) {
                    if (node instanceof Element) {
                        node.setText(value);
                    }
                }
            }
        }

        public void endElement(Element element) {
        }

        public void text(Text text) {
        }
    }, true);

    return shadowTreeDocument;
}