List of usage examples for org.dom4j Node getNodeType
short getNodeType();
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); } }