Example usage for org.dom4j Node getNodeType

List of usage examples for org.dom4j Node getNodeType

Introduction

In this page you can find the example usage for org.dom4j Node getNodeType.

Prototype

short getNodeType();

Source Link

Document

Returns the code according to the type of node.

Usage

From source file:org.openadaptor.auxil.convertor.map.Dom4JDocumentMapFacade.java

License:Open Source License

/** 
 * Extract value from a single node/*from   w  ww  .j  a  v a  2s  . co  m*/
 * <br>
 * <UL>
 *  <LI>If an Element return the element reference.
 *  <LI>If an Attribute return the attribute value
 *  <LI>If text (or CDATA) return it.
 *  <LI>If null return null.
 * @param node Node from which to extract a value
 * @return Reference to Element, or String representation of value.
 */
private Object getSingleValuedResult(Node node) {
    Object result = null;
    switch (node.getNodeType()) {
    case Node.ELEMENT_NODE:
        result = (Element) node;
        break;
    case Node.ATTRIBUTE_NODE:
        result = ((Attribute) node).getValue();
        break;
    case Node.TEXT_NODE:
    case Node.CDATA_SECTION_NODE: //Not sure about this one!
        result = node.getText();
        break;
    }
    return result;
}

From source file:org.opencms.importexport.CmsXmlPageConverter.java

License:Open Source License

/**
 * Converts the contents of a page into an xml page.<p>
 * /*from   ww w. j a  va 2s  . c o m*/
 * @param cms the cms object
 * @param content the content used with xml templates
 * @param locale the locale of the body element(s)
 * @param encoding the encoding to the xml page
 * @return the xml page content or null if conversion failed
 * @throws CmsImportExportException if the body content or the XMLTEMPLATE element were not found
 * @throws CmsXmlException if there is an error reading xml contents from the byte array into a document
 */
public static CmsXmlPage convertToXmlPage(CmsObject cms, byte[] content, Locale locale, String encoding)
        throws CmsImportExportException, CmsXmlException {

    CmsXmlPage xmlPage = null;

    Document page = CmsXmlUtils.unmarshalHelper(content, null);

    Element xmltemplate = page.getRootElement();
    if ((xmltemplate == null) || !"XMLTEMPLATE".equals(xmltemplate.getName())) {
        throw new CmsImportExportException(Messages.get().container(Messages.ERR_NOT_FOUND_ELEM_XMLTEMPLATE_0));
    }

    // get all edittemplate nodes
    Iterator i = xmltemplate.elementIterator("edittemplate");
    boolean useEditTemplates = true;
    if (!i.hasNext()) {
        // no edittemplate nodes found, get the template nodes
        i = xmltemplate.elementIterator("TEMPLATE");
        useEditTemplates = false;
    }

    // now create the XML page
    xmlPage = new CmsXmlPage(locale, encoding);

    while (i.hasNext()) {
        Element currentTemplate = (Element) i.next();
        String bodyName = currentTemplate.attributeValue("name");
        if (CmsStringUtil.isEmpty(bodyName)) {
            // no template name found, use the parameter body name
            bodyName = "body";
        }
        String bodyContent = null;

        if (useEditTemplates) {
            // no content manipulation needed for edittemplates
            bodyContent = currentTemplate.getText();
        } else {
            // parse content for TEMPLATEs
            StringBuffer contentBuffer = new StringBuffer();
            for (Iterator k = currentTemplate.nodeIterator(); k.hasNext();) {
                Node n = (Node) k.next();
                if (n.getNodeType() == Node.CDATA_SECTION_NODE) {
                    contentBuffer.append(n.getText());
                    continue;
                } else if (n.getNodeType() == Node.ELEMENT_NODE) {
                    if ("LINK".equals(n.getName())) {
                        contentBuffer.append(OpenCms.getSystemInfo().getOpenCmsContext());
                        contentBuffer.append(n.getText());
                        continue;
                    }
                }
            }
            bodyContent = contentBuffer.toString();
        }

        if (bodyContent == null) {
            throw new CmsImportExportException(Messages.get().container(Messages.ERR_BODY_CONTENT_NOT_FOUND_0));
        }

        bodyContent = CmsStringUtil.substitute(bodyContent, CmsStringUtil.MACRO_OPENCMS_CONTEXT,
                OpenCms.getSystemInfo().getOpenCmsContext());

        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(bodyContent)) {
            xmlPage.addValue(bodyName, locale);
            xmlPage.setStringValue(cms, bodyName, locale, bodyContent);
        }
    }

    return xmlPage;

}

From source file:org.opencms.setup.xml.CmsSetupXmlHelper.java

License:Open Source License

/**
 * Sets the given value in all nodes identified by the given xpath of the given xml file.<p>
 * //from   w w  w  .  j  a  v  a 2s . c o m
 * If value is <code>null</code>, all nodes identified by the given xpath will be deleted.<p>
 * 
 * If the node identified by the given xpath does not exists, the missing nodes will be created
 * (if <code>value</code> not <code>null</code>).<p>
 * 
 * @param document the xml document
 * @param xPath the xpath to set
 * @param value the value to set (can be <code>null</code> for deletion)
 * @param nodeToInsert optional, if given it will be inserted after xPath with the given value
 * 
 * @return the number of successful changed or deleted nodes
 */
public static int setValue(Document document, String xPath, String value, String nodeToInsert) {

    int changes = 0;
    // be naive and try to find the node
    Iterator<Node> itNodes = CmsCollectionsGenericWrapper.<Node>list(document.selectNodes(xPath)).iterator();

    // if not found
    if (!itNodes.hasNext()) {
        if (value == null) {
            // if no node found for deletion
            return 0;
        }
        // find the node creating missing nodes in the way
        Iterator<String> it = CmsStringUtil.splitAsList(xPath, "/", false).iterator();
        Node currentNode = document;
        while (it.hasNext()) {
            String nodeName = it.next();
            // if a string condition contains '/'
            while ((nodeName.indexOf("='") > 0) && (nodeName.indexOf("']") < 0)) {
                nodeName += "/" + it.next();
            }
            Node node = currentNode.selectSingleNode(nodeName);
            if (node != null) {
                // node found
                currentNode = node;
                if (!it.hasNext()) {
                    currentNode.setText(value);
                }
            } else if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                Element elem = (Element) currentNode;
                if (!nodeName.startsWith("@")) {
                    elem = handleNode(elem, nodeName);
                    if (!it.hasNext() && CmsStringUtil.isNotEmptyOrWhitespaceOnly(value)) {
                        elem.setText(value);
                    }
                } else {
                    // if node is attribute create it with given value
                    elem.addAttribute(nodeName.substring(1), value);
                }
                currentNode = elem;
            } else {
                // should never happen
                if (LOG.isDebugEnabled()) {
                    LOG.debug(Messages.get().getBundle().key(Messages.ERR_XML_SET_VALUE_2, xPath, value));
                }
                break;
            }
        }
        if (nodeToInsert == null) {
            // if not inserting we are done
            return 1;
        }
        // if inserting, we just created the insertion point, so continue
        itNodes = CmsCollectionsGenericWrapper.<Node>list(document.selectNodes(xPath)).iterator();
    }

    // if found 
    while (itNodes.hasNext()) {
        Node node = itNodes.next();
        if (nodeToInsert == null) {
            // if not inserting
            if (value != null) {
                // if found, change the value
                node.setText(value);
            } else {
                // if node for deletion is found
                node.getParent().remove(node);
            }
        } else {
            // first create the node to insert
            Element parent = node.getParent();
            Element elem = handleNode(parent, nodeToInsert);
            if (value != null) {
                elem.setText(value);
            }
            // get the parent element list
            List<Node> list = CmsCollectionsGenericWrapper.<Node>list(parent.content());
            // remove the just created element
            list.remove(list.size() - 1);
            // insert it back to the right position
            int pos = list.indexOf(node);
            list.add(pos + 1, elem); // insert after
        }
        changes++;
    }
    return changes;
}

From source file:org.opencms.util.ant.CmsSetupXmlHelper.java

License:Open Source License

/**
 * Sets the given value in all nodes identified by the given xpath of the given xml file.<p>
 * //from   w w  w  .  ja va  2  s  .com
 * If value is <code>null</code>, all nodes identified by the given xpath will be deleted.<p>
 * 
 * If the node identified by the given xpath does not exists, the missing nodes will be created
 * (if <code>value</code> not <code>null</code>).<p>
 * 
 * @param document the xml document
 * @param xPath the xpath to set
 * @param value the value to set (can be <code>null</code> for deletion)
 * @param nodeToInsert optional, if given it will be inserted after xPath with the given value
 * 
 * @return the number of successful changed or deleted nodes
 */
@SuppressWarnings("unchecked")
public static int setValue(Document document, String xPath, String value, String nodeToInsert) {

    int changes = 0;
    // be naive and try to find the node
    Iterator<Node> itNodes = document.selectNodes(xPath).iterator();

    // if not found
    if (!itNodes.hasNext()) {
        if (value == null) {
            // if no node found for deletion
            return 0;
        }
        // find the node creating missing nodes in the way
        Iterator<String> it = CmsStringUtil.splitAsList(xPath, "/", false).iterator();
        Node currentNode = document;
        while (it.hasNext()) {
            String nodeName = it.next();
            // if a string condition contains '/'
            while ((nodeName.indexOf("='") > 0) && (nodeName.indexOf("']") < 0)) {
                nodeName += "/" + it.next();
            }
            Node node = currentNode.selectSingleNode(nodeName);
            if (node != null) {
                // node found
                currentNode = node;
                if (!it.hasNext()) {
                    currentNode.setText(value);
                }
            } else if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
                Element elem = (Element) currentNode;
                if (!nodeName.startsWith("@")) {
                    elem = handleNode(elem, nodeName);
                    if (!it.hasNext() && !CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
                        elem.setText(value);
                    }
                } else {
                    // if node is attribute create it with given value
                    elem.addAttribute(nodeName.substring(1), value);
                }
                currentNode = elem;
            } else {
                // should never happen
                break;
            }
        }
        if (nodeToInsert == null) {
            // if not inserting we are done
            return 1;
        }
        // if inserting, we just created the insertion point, so continue
        itNodes = document.selectNodes(xPath).iterator();
    }

    // if found 
    while (itNodes.hasNext()) {
        Node node = itNodes.next();
        if (nodeToInsert == null) {
            // if not inserting
            if (value != null) {
                // if found, change the value
                node.setText(value);
            } else {
                // if node for deletion is found
                node.getParent().remove(node);
            }
        } else {
            // first create the node to insert
            Element parent = node.getParent();
            Element elem = handleNode(parent, nodeToInsert);
            if (value != null) {
                elem.setText(value);
            }
            // get the parent element list
            List<Node> list = parent.content();
            // remove the just created element
            list.remove(list.size() - 1);
            // insert it back to the right position
            int pos = list.indexOf(node);
            list.add(pos + 1, elem); // insert after
        }
        changes++;
    }
    return changes;
}

From source file:org.orbeon.oxf.processor.pipeline.PipelineProcessor.java

License:Open Source License

public static PipelineConfig createConfigFromAST(ASTPipeline astPipeline) {

    // Perform sanity check on the connection in the pipeline
    astPipeline.getIdInfo();//from   ww w  .ja v  a 2  s. c om

    // Create new configuration object
    final PipelineConfig config = new PipelineConfig();
    final PipelineBlock block = new PipelineBlock();

    // Create socket info for each param
    for (Iterator i = astPipeline.getParams().iterator(); i.hasNext();) {
        ASTParam param = (ASTParam) i.next();

        // Create internal top output/bottom input for this param
        if (param.getType() == ASTParam.INPUT) {
            final InternalTopOutput internalTopOutput = new InternalTopOutput(param.getName(),
                    param.getLocationData());
            block.declareOutput(param.getNode(), param.getName(), internalTopOutput);
            config.declareTopOutput(param.getName(), internalTopOutput);
            setDebugAndSchema(internalTopOutput, param);
        } else {
            final ProcessorInput internalBottomInput = new InternalBottomInput(param.getName());
            block.declareBottomInput(param.getNode(), param.getName(), internalBottomInput);
            config.declareBottomInput(param.getName(), internalBottomInput);
            setDebugAndSchema(internalBottomInput, param);
        }

        // Create socket
        // FIXME: when we implement the full delegation model, we'll have
        // here to create of pass the input/output information.
    }

    // Internally connect all processors / choose / for-each
    for (Iterator i = astPipeline.getStatements().iterator(); i.hasNext();) {
        Object statement = i.next();
        Processor processor = null;
        boolean foundOutput = false;

        if (statement instanceof ASTProcessorCall) {
            ASTProcessorCall processorCall = (ASTProcessorCall) statement;

            final LocationData processorLocationData = processorCall.getLocationData();
            final String processorNameOrURI = Dom4jUtils.qNameToExplodedQName(processorCall.getName());

            // Direct call
            if (processorCall.getProcessor() == null) {
                ProcessorFactory processorFactory = ProcessorFactoryRegistry.lookup(processorCall.getName());
                if (processorFactory == null) {
                    throw new ValidationException(
                            "Cannot find processor factory with name \"" + processorNameOrURI + "\"",
                            processorLocationData);
                }
                processor = processorFactory.createInstance();
            } else {
                processor = processorCall.getProcessor();
            }

            // Set info on processor
            processor.setId(processorCall.getId());
            processor.setLocationData(new ExtendedLocationData(processorLocationData, "executing processor",
                    (Element) processorCall.getNode(), new String[] { "name", processorNameOrURI }));

            // Process outputs
            for (Iterator j = processorCall.getOutputs().iterator(); j.hasNext();) {
                foundOutput = true;
                ASTOutput output = (ASTOutput) j.next();
                final String nm = output.getName();
                if (nm == null)
                    throw new OXFException("Name attribute is mandatory on output");
                final String id = output.getId();
                final String ref = output.getRef();
                if (id == null && ref == null)
                    throw new OXFException("Either one of id or ref must be specified on output " + nm);

                ProcessorOutput pout = processor.createOutput(nm);
                if (id != null)
                    block.declareOutput(output.getNode(), id, pout);
                if (ref != null)
                    block.connectProcessorToBottomInput(output.getNode(), nm, ref, pout);
                setDebugAndSchema(pout, output);
            }

            // Make sure at least one of the outputs is connected
            if (!foundOutput && processor.getOutputsInfo().size() > 0)
                throw new ValidationException("The processor output must be connected", processorLocationData);

            // Process inputs
            for (Iterator j = processorCall.getInputs().iterator(); j.hasNext();) {
                ASTInput input = (ASTInput) j.next();

                final ProcessorInput pin;
                LocationData inputLocationData = input.getLocationData();
                if (input.getHref() != null && input.getTransform() == null) {
                    // We just reference a URI
                    pin = block.connectProcessorToHref(input.getNode(), processor, input.getName(),
                            input.getHref());
                } else {
                    // We have some inline XML in the <input> tag
                    final Node inlineNode = input.getContent();

                    // Create inline document
                    final Document inlineDocument;
                    {
                        final int nodeType = inlineNode.getNodeType();
                        if (nodeType == Node.ELEMENT_NODE) {
                            final Element element = (Element) inlineNode;
                            inlineDocument = Dom4jUtils.createDocumentCopyParentNamespaces(element);
                        } else if (nodeType == Node.DOCUMENT_NODE) {
                            inlineDocument = (Document) inlineNode;
                        } else {
                            throw new OXFException(
                                    "Invalid type for inline document: " + inlineNode.getClass().getName());
                        }
                    }

                    // Create generator for the inline document
                    final DOMGenerator domGenerator;
                    {
                        final Object validity = astPipeline.getValidity();
                        final LocationData pipelineLocationData = astPipeline.getLocationData();
                        String systemId = (pipelineLocationData == null) ? DOMGenerator.DefaultContext
                                : pipelineLocationData.getSystemID();
                        if (systemId == null)
                            systemId = DOMGenerator.DefaultContext;
                        domGenerator = PipelineUtils.createDOMGenerator(inlineDocument, "inline input",
                                validity, systemId);
                    }

                    final ProcessorOutput domProcessorDataOutput = domGenerator.createOutput(OUTPUT_DATA);

                    // Check if there is an inline transformation
                    final QName transform = input.getTransform();
                    if (transform != null) {
                        //XPathUtils.selectBooleanValue(inlineDocument, "/*/@*[local-name() = 'version' and namespace-uri() = 'http://www.w3.org/1999/XSL/Transform'] = '2.0'").booleanValue()
                        // Instanciate processor
                        final Processor transformProcessor;
                        {
                            final ProcessorFactory processorFactory = ProcessorFactoryRegistry
                                    .lookup(transform);
                            if (processorFactory == null) {
                                throw new ValidationException("Cannot find processor factory with JNDI name \""
                                        + transform.getQualifiedName() + "\"", inputLocationData);
                            }
                            transformProcessor = processorFactory.createInstance();
                        }

                        // Add transformation to this pipeline/block, so it is appropriately reset if the block runs multiple times
                        config.addProcessor(transformProcessor);

                        // Set info on processor
                        //processor.setId(processorCall.getId()); // what id, if any?
                        transformProcessor.setLocationData(inputLocationData);

                        // Connect config input
                        final ProcessorInput transformConfigInput = transformProcessor
                                .createInput(INPUT_CONFIG);
                        domProcessorDataOutput.setInput(transformConfigInput);
                        transformConfigInput.setOutput(domProcessorDataOutput);

                        // Connect transform processor data input
                        pin = block.connectProcessorToHref(input.getNode(), transformProcessor, INPUT_DATA,
                                input.getHref());

                        // Connect transform processor data output
                        final ProcessorOutput transformDataOutput = transformProcessor
                                .createOutput(OUTPUT_DATA);
                        final ProcessorInput processorDataInput = processor.createInput(input.getName());
                        transformDataOutput.setInput(processorDataInput);
                        processorDataInput.setOutput(transformDataOutput);
                    } else {
                        // It is regular static text: connect directly
                        pin = processor.createInput(input.getName());
                        domProcessorDataOutput.setInput(pin);
                        pin.setOutput(domProcessorDataOutput);
                    }
                }
                setDebugAndSchema(pin, input);
            }

        } else if (statement instanceof ASTChoose) {

            // Instantiate processor
            ASTChoose choose = (ASTChoose) statement;
            AbstractProcessor chooseAbstractProcessor = new AbstractChooseProcessor(choose,
                    astPipeline.getValidity());
            ConcreteChooseProcessor chooseProcessor = (ConcreteChooseProcessor) chooseAbstractProcessor
                    .createInstance();
            processor = chooseProcessor;

            // Connect special $data input (document on which the decision is made, or iterated on)
            ProcessorInput pin = block.connectProcessorToHref(choose.getNode(), processor,
                    AbstractChooseProcessor.CHOOSE_DATA_INPUT, choose.getHref());
            setDebugAndSchema(pin, choose);

            // Go through inputs/outputs and connect to the rest of the pipeline
            for (Iterator j = processor.getInputsInfo().iterator(); j.hasNext();) {
                // We reference a previously declared output
                String inputName = ((ProcessorInputOutputInfo) j.next()).getName();
                if (!inputName.equals(AbstractChooseProcessor.CHOOSE_DATA_INPUT)) {
                    ASTHrefId hrefId = new ASTHrefId();
                    hrefId.setId(inputName);
                    block.connectProcessorToHref(choose.getNode(), processor, inputName, hrefId);
                }
            }
            for (Iterator j = processor.getOutputsInfo().iterator(); j.hasNext();) {
                String outputName = ((ProcessorInputOutputInfo) j.next()).getName();
                foundOutput = true;
                ProcessorOutput pout = processor.createOutput(outputName);
                if (chooseProcessor.getOutputsById().contains(outputName))
                    block.declareOutput(choose.getNode(), outputName, pout);
                if (chooseProcessor.getOutputsByParamRef().contains(outputName))
                    block.connectProcessorToBottomInput(choose.getNode(), outputName, outputName, pout);
            }

        } else if (statement instanceof ASTForEach) {

            // Instantiate processor
            final ASTForEach forEach = (ASTForEach) statement;
            final LocationData forEachLocationData = forEach.getLocationData();
            final AbstractProcessor forEachAbstractProcessor = new AbstractForEachProcessor(forEach,
                    astPipeline.getValidity());

            processor = (ConcreteForEachProcessor) forEachAbstractProcessor.createInstance();

            // Connect special $data input (document on which the decision is made, or iterated on)
            final ProcessorInput pin = block.connectProcessorToHref(forEach.getNode(), processor,
                    AbstractForEachProcessor.FOR_EACH_DATA_INPUT, forEach.getHref());
            setDebugAndSchema(pin, forEach, forEachLocationData, forEach.getInputSchemaUri(),
                    forEach.getInputSchemaHref(), forEach.getInputDebug());

            // Go through inputs and connect to the rest of the pipeline
            for (Iterator j = processor.getInputsInfo().iterator(); j.hasNext();) {
                // We reference a previously declared output
                final String inputName = ((ProcessorInputOutputInfo) j.next()).getName();
                if (!inputName.equals(AbstractForEachProcessor.FOR_EACH_DATA_INPUT)) {
                    final ASTHrefId hrefId = new ASTHrefId();
                    hrefId.setId(inputName);
                    // NOTE: Force creation of a tee so that inputs of p:for-each are not read multiple times
                    block.connectProcessorToHref(forEach.getNode(), processor, inputName, hrefId, true);
                }
            }

            // Connect output
            final String outputName = forEach.getId() != null ? forEach.getId() : forEach.getRef();
            if (outputName != null) {
                foundOutput = true;
                final ProcessorOutput forEachOutput = processor.createOutput(outputName);
                if (forEach.getId() != null)
                    block.declareOutput(forEach.getNode(), forEach.getId(), forEachOutput);
                if (forEach.getRef() != null)
                    block.connectProcessorToBottomInput(forEach.getNode(), forEach.getId(), forEach.getRef(),
                            forEachOutput);
                setDebugAndSchema(processor.getOutputByName(outputName), forEach, forEachLocationData,
                        forEach.getOutputSchemaUri(), forEach.getOutputSchemaHref(), forEach.getOutputDebug());
            }
        }

        // Remember all processors and processor with no output (need to be started)
        if (processor != null) {
            config.addProcessor(processor);
            if (!foundOutput) {
                config.addProcessorToStart(processor);
            }
        }
    }

    // Check that all bottom inputs are connected
    for (Iterator i = astPipeline.getParams().iterator(); i.hasNext();) {
        ASTParam param = (ASTParam) i.next();
        if (param.getType() == ASTParam.OUTPUT) {
            if (!block.isBottomInputConnected(param.getName()))
                throw new ValidationException(
                        "No processor in pipeline is connected to pipeline output '" + param.getName() + "'",
                        param.getLocationData());
        }
    }

    // Add processors created for connection reasons
    for (Iterator i = block.getCreatedProcessors().iterator(); i.hasNext();)
        config.addProcessor((Processor) i.next());

    return config;
}

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/*from  w ww.  jav a  2  s .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.actions.XFormsInsertAction.java

License:Open Source License

public static List<NodeInfo> doInsert(XFormsContainingDocument containingDocument,
        IndentedLogger indentedLogger, String positionAttribute, List collectionToBeUpdated,
        NodeInfo insertContextNodeInfo, List<Item> originItems, int insertionIndex, boolean doClone,
        boolean doDispatch) {

    final boolean isEmptyNodesetBinding = collectionToBeUpdated == null || collectionToBeUpdated.size() == 0;

    // "3. The origin node-set is determined."
    // "5. Each node in the origin node-set is cloned in the order it appears in the origin node-set."
    final List<Node> sourceNodes;
    final List<Node> clonedNodes;
    {//w  ww .j  a  v  a  2 s . c  o m
        final List<Node> clonedNodesTemp;
        if (originItems == null) {
            // There are no explicitly specified origin objects, use node from Node Set Binding node-set

            // "If the origin attribute is not given and the Node Set Binding node-set is empty, then the origin
            // node-set is the empty node-set. [...] The insert action is terminated with no effect if the
            // origin node-set is the empty node-set."

            if (isEmptyNodesetBinding) {
                if (indentedLogger != null && indentedLogger.isDebugEnabled())
                    indentedLogger.logDebug("xf:insert",
                            "origin node-set from node-set binding is empty, terminating");
                return Collections.EMPTY_LIST;
            }

            // "Otherwise, if the origin attribute is not given, then the origin node-set consists of the last
            // node of the Node Set Binding node-set."
            final Node singleSourceNode = XFormsUtils.getNodeFromNodeInfoConvert(
                    (NodeInfo) collectionToBeUpdated.get(collectionToBeUpdated.size() - 1));
            // TODO: check namespace handling might be incorrect. Should use copyElementCopyParentNamespaces() instead?
            final Node singleClonedNode = Dom4jUtils.createCopy(singleSourceNode);

            sourceNodes = Collections.singletonList(singleSourceNode);
            clonedNodesTemp = Collections.singletonList(singleClonedNode);
        } else {
            // There are explicitly specified origin objects

            // "The insert action is terminated with no effect if the origin node-set is the empty node-set."
            if (originItems.size() == 0) {
                if (indentedLogger != null && indentedLogger.isDebugEnabled())
                    indentedLogger.logDebug("xf:insert", "origin node-set is empty, terminating");
                return Collections.EMPTY_LIST;
            }

            // "Each node in the origin node-set is cloned in the order it appears in the origin node-set."

            sourceNodes = new ArrayList<Node>(originItems.size()); // set to max possible size
            clonedNodesTemp = new ArrayList<Node>(originItems.size());

            for (final Object currentObject : originItems) {
                if (currentObject instanceof NodeInfo) {
                    // This is the regular case covered by XForms 1.1 / XPath 1.0

                    // NOTE: Don't clone nodes if doClone == false
                    final Node sourceNode = XFormsUtils.getNodeFromNodeInfoConvert((NodeInfo) currentObject);
                    final Node clonedNode = doClone
                            ? (sourceNode instanceof Element) ? ((Element) sourceNode).createCopy()
                                    : (Node) sourceNode.clone()
                            : sourceNode;

                    sourceNodes.add(sourceNode);
                    clonedNodesTemp.add(clonedNode);

                } else if (currentObject instanceof AtomicValue) {
                    // This is an extension: support sequences containing atomic values

                    // Convert the result to a text node
                    final String stringValue = ((Item) currentObject).getStringValue();
                    final Text textNode = Dom4jUtils.createText(stringValue);

                    sourceNodes.add(null); // there is no source node for this cloned node, it's a source item
                    clonedNodesTemp.add(textNode);
                } else
                    throw new IllegalStateException();
            }
        }

        // Remove instance data from cloned nodes and perform Document node adjustment
        for (int i = 0; i < clonedNodesTemp.size(); i++) {
            final Node clonedNodeTemp = clonedNodesTemp.get(i);

            if (clonedNodeTemp instanceof Element) {
                // Element node
                InstanceData.remove(clonedNodeTemp);
                clonedNodeTemp.detach();
            } else if (clonedNodeTemp instanceof Attribute) {
                // Attribute node
                InstanceData.remove(clonedNodeTemp);
                clonedNodeTemp.detach();
            } else if (clonedNodeTemp instanceof Document) {
                // Document node
                final Element clonedNodeTempRootElement = clonedNodeTemp.getDocument().getRootElement();

                if (clonedNodeTempRootElement == null) {
                    // Can be null in rare cases of documents without root element
                    clonedNodesTemp.set(i, null); // we support having a null node further below, so set this to null
                } else {
                    InstanceData.remove(clonedNodeTempRootElement);
                    // We can never really insert a document into anything at this point, but we assume that this means the root element
                    clonedNodesTemp.set(i, clonedNodeTempRootElement.detach());
                }
            } else {
                // Other nodes
                clonedNodeTemp.detach();
            }
        }
        clonedNodes = clonedNodesTemp;
    }

    // "6. The target location of each cloned node or nodes is determined"
    // "7. The cloned node or nodes are inserted in the order they were cloned at their target location
    // depending on their node type."

    // Identify the instance that actually changes
    final XFormsInstance modifiedInstance;
    // Find actual insertion point and insert
    final NodeInfo insertLocationNodeInfo;
    final List<Node> insertedNodes;
    final String beforeAfterInto;
    if (isEmptyNodesetBinding) {
        // Insert INTO a node

        // "If the Node Set Binding node-set is not specified or empty, the insert location node is the insert
        // context node."

        // "a. If the Node Set Binding node-set is not specified or empty, the target location depends on the
        // node type of the cloned node. If the cloned node is an attribute, then the target location is before
        // the first attribute of the insert location node. If the cloned node is not an attribute, then the
        // target location is before the first child of the insert location node."

        modifiedInstance = (containingDocument != null)
                ? containingDocument.getInstanceForNode(insertContextNodeInfo)
                : null;
        insertLocationNodeInfo = insertContextNodeInfo;
        final Node insertLocationNode = XFormsUtils.getNodeFromNodeInfo(insertContextNodeInfo,
                CANNOT_INSERT_READONLY_MESSAGE);
        insertedNodes = doInsert(insertLocationNode, clonedNodes, modifiedInstance, doDispatch);
        beforeAfterInto = "into";

        // Normalize text nodes if needed to respect XPath 1.0 constraint
        {
            boolean hasTextNode = false;
            for (Node clonedNode : clonedNodes) {
                hasTextNode |= clonedNode != null && clonedNode.getNodeType() == Node.TEXT_NODE;
            }
            if (hasTextNode)
                Dom4jUtils.normalizeTextNodes(insertLocationNode);
        }
    } else {
        // Insert BEFORE or AFTER a node
        insertLocationNodeInfo = (NodeInfo) collectionToBeUpdated.get(insertionIndex - 1);
        final Node insertLocationNode = XFormsUtils.getNodeFromNodeInfo(insertLocationNodeInfo,
                CANNOT_INSERT_READONLY_MESSAGE);
        modifiedInstance = (containingDocument != null)
                ? containingDocument.getInstanceForNode(insertLocationNodeInfo)
                : null;

        final Document insertLocationNodeDocument = insertLocationNode.getDocument();
        if (insertLocationNodeDocument != null
                && insertLocationNodeDocument.getRootElement() == insertLocationNode) {

            // "c. if insert location node is the root element of an instance, then that instance root element
            // location is the target location. If there is more than one cloned node to insert, only the
            // first node that does not cause a conflict is considered."

            insertedNodes = doInsert(insertLocationNode.getDocument(), clonedNodes, modifiedInstance,
                    doDispatch);
            beforeAfterInto = positionAttribute; // TODO: ideally normalize to "into document node"?

            // NOTE: Don't need to normalize text nodes in this case, as no new text node is inserted
        } else {
            // "d. Otherwise, the target location is immediately before or after the insert location
            // node, based on the position attribute setting or its default."

            if (insertLocationNode.getNodeType() == Node.ATTRIBUTE_NODE) {
                // Special case for "next to an attribute"

                // NOTE: In XML, attributes are unordered. dom4j handles them as a list so has order, but
                // the XForms spec shouldn't rely on attribute order. We could try to keep the order, but it
                // is harder as we have to deal with removing duplicate attributes and find a reasonable
                // insertion strategy.

                // TODO: Don't think we should even do this now in XForms 1.1
                insertedNodes = doInsert(insertLocationNode.getParent(), clonedNodes, modifiedInstance,
                        doDispatch);

            } else {
                // Other node types
                final Element parentNode = insertLocationNode.getParent();
                final List<Node> siblingElements = Dom4jUtils.content(parentNode);
                final int actualIndex = siblingElements.indexOf(insertLocationNode);

                // Prepare insertion of new element
                final int actualInsertionIndex;
                if ("before".equals(positionAttribute)) {
                    actualInsertionIndex = actualIndex;
                } else {
                    // "after"
                    actualInsertionIndex = actualIndex + 1;
                }

                // "7. The cloned node or nodes are inserted in the order they were cloned at their target
                // location depending on their node type."

                boolean hasTextNode = false;
                int addIndex = 0;
                insertedNodes = new ArrayList<Node>(clonedNodes.size());
                for (Node clonedNode : clonedNodes) {

                    if (clonedNode != null) {// NOTE: we allow passing some null nodes so we check on null
                        if (!(clonedNode instanceof Attribute || clonedNode instanceof Namespace)) {
                            // Element, text, comment, processing instruction node
                            siblingElements.add(actualInsertionIndex + addIndex, clonedNode);
                            insertedNodes.add(clonedNode);
                            hasTextNode |= clonedNode.getNodeType() == Node.TEXT_NODE;
                            addIndex++;
                        } else {
                            // We never insert attributes or namespace nodes as siblings
                            if (indentedLogger != null && indentedLogger.isDebugEnabled())
                                indentedLogger.logDebug("xf:insert",
                                        "skipping insertion of node as sibling in element content", "type",
                                        clonedNode.getNodeTypeName(), "node",
                                        clonedNode instanceof Attribute
                                                ? Dom4jUtils.attributeToDebugString((Attribute) clonedNode)
                                                : clonedNode.toString());
                        }
                    }
                }

                // Normalize text nodes if needed to respect XPath 1.0 constraint
                if (hasTextNode)
                    Dom4jUtils.normalizeTextNodes(parentNode);
            }

            beforeAfterInto = positionAttribute;
        }
    }

    // Whether some nodes were inserted
    final boolean didInsertNodes = insertedNodes != null && insertedNodes.size() > 0;

    // Log stuff
    if (indentedLogger != null && indentedLogger.isDebugEnabled()) {
        if (didInsertNodes)
            indentedLogger.logDebug("xf:insert", "inserted nodes", "count",
                    Integer.toString(insertedNodes.size()), "instance",
                    (modifiedInstance != null) ? modifiedInstance.getEffectiveId() : null);
        else
            indentedLogger.logDebug("xf:insert", "no node inserted");
    }

    // "XForms Actions that change the tree structure of instance data result in setting all four flags to true"
    if (didInsertNodes && modifiedInstance != null) {
        // NOTE: Can be null if document into which delete is performed is not in an instance, e.g. in a variable
        modifiedInstance.markModified();
        modifiedInstance.model().markStructuralChange(modifiedInstance);
    }

    // Gather list of modified nodes
    final List<NodeInfo> insertedNodeInfos;
    if (didInsertNodes && modifiedInstance != null) {
        // Can be null if document into which delete is performed is not in an instance, e.g. in a variable
        final DocumentWrapper documentWrapper = (DocumentWrapper) modifiedInstance.documentInfo();
        insertedNodeInfos = new ArrayList<NodeInfo>(insertedNodes.size());
        for (Object insertedNode : insertedNodes)
            insertedNodeInfos.add(documentWrapper.wrap(insertedNode));
    } else {
        insertedNodeInfos = Collections.emptyList();
    }

    // "4. If the insert is successful, the event xforms-insert is dispatched."
    // XFormsInstance handles index and repeat items updates 
    if (doDispatch && didInsertNodes && modifiedInstance != null) {

        // Adjust insert location node and before/after/into in case the root element was replaced
        final NodeInfo adjustedInsertLocationNodeInfo;
        final String adjustedBeforeAfterInto;

        final NodeInfo parent = insertedNodeInfos.get(0).getNodeKind() == org.w3c.dom.Node.ELEMENT_NODE
                ? insertedNodeInfos.get(0).getParent()
                : null;
        if (parent != null && parent.equals(parent.getDocumentRoot())) {
            // Node was inserted under document node
            adjustedInsertLocationNodeInfo = parent.getDocumentRoot();
            adjustedBeforeAfterInto = "into";
        } else {
            adjustedInsertLocationNodeInfo = insertLocationNodeInfo;
            adjustedBeforeAfterInto = beforeAfterInto;
        }

        Dispatch.dispatchEvent(new XFormsInsertEvent(modifiedInstance, insertedNodeInfos, originItems,
                adjustedInsertLocationNodeInfo, adjustedBeforeAfterInto));
    }

    return insertedNodeInfos;
}

From source file:org.orbeon.oxf.xml.dom4j.Dom4jUtils.java

License:Open Source License

/**
 * Convert a dom4j node to a string./* w  ww.jav a2 s. c  om*/
 *
 * @param node  node to convert
 * @return      resulting string
 */
public static String nodeToString(final Node node) {
    final String ret;
    switch (node.getNodeType()) {
    case Node.DOCUMENT_NODE: {
        ret = domToString((Branch) ((Document) node).getRootElement());
        break;
    }
    case Node.ELEMENT_NODE: {
        ret = domToString((Branch) node);
        break;
    }
    case Node.TEXT_NODE: {
        ret = node.getText();
        break;
    }
    default:
        ret = domToString(node, null);
        break;
    }
    return ret;
}

From source file:org.orbeon.oxf.xml.dom4j.Dom4jUtils.java

License:Open Source License

/**
 * Removes the elements and text inside the given element, but not the attributes or namespace
 * declarations on the element.//  ww w .  j  a  v a 2 s .  c o  m
 */
public static void clearElementContent(final Element elt) {
    final java.util.List cntnt = elt.content();
    for (final java.util.ListIterator j = cntnt.listIterator(); j.hasNext();) {
        final Node chld = (Node) j.next();
        if (chld.getNodeType() == Node.TEXT_NODE || chld.getNodeType() == Node.ELEMENT_NODE) {
            j.remove();
        }
    }
}

From source file:org.orbeon.oxf.xml.dom4j.NonLazyUserDataElement.java

License:Open Source License

public void appendContent(final org.dom4j.Branch branch) {
    final int size = branch.nodeCount();
    for (int i = 0; i < size; i++) {
        final org.dom4j.Node node = branch.node(i);
        final org.dom4j.Node cln;
        if (node.getNodeType() == org.dom4j.Node.ELEMENT_NODE) {
            cln = ((NonLazyUserDataElement) node).cloneInternal();
        } else {/*  w w  w.  j  a  v  a 2s.c om*/
            cln = (org.dom4j.Node) node.clone();
        }
        add(cln);
    }
}