List of usage examples for org.dom4j Node getParent
Element getParent();
getParent
returns the parent Element
if this node supports the parent relationship or null if it is the root element or does not support the parent relationship.
From source file:org.openadaptor.auxil.convertor.map.DocumentMapFacade.java
License:Open Source License
/** * Remove and return an Element or value from the document, given its key. * <p>/*from w ww . j av a2 s .c om*/ * If the node isn't found, then no action is taken. * @param key corresponding to the object being searched for. * @return The Object which has been removed, or null if not found. * @throws RecordException if the operation cannot be completed. */ public Object remove(Object key) throws RecordException { if (key == null) { throw new IllegalArgumentException("null is not a legal argument for remove()"); } Object value = get(key); //Retrieve it all. List nodeList = document.selectNodes(key.toString()); Iterator it = nodeList.iterator(); while (it.hasNext()) { Node node = (Node) it.next(); node.getParent().remove(node); } return value; }
From source file:org.openadaptor.auxil.convertor.map.Dom4JDocumentMapFacade.java
License:Open Source License
private Object modifyExisting(Node existing, Object value) { Object old = null;/*from w ww. j ava 2s . c om*/ if (value instanceof Element) { old = modify(existing, (Element) value); } else if (value instanceof Attribute) { old = modify(existing, (Attribute) value); } else if (value != null) { old = modify(existing, value.toString()); } else { old = existing; existing.getParent().remove(existing); } return old; }
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> * // 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.setup.xml.v8.CmsXmlAddADESearch.java
License:Open Source License
/** * Initializes the map of XML update actions.<p> *//* w ww . j av a 2s . c o m*/ private void initActions() { m_actions = new LinkedHashMap<String, CmsXmlUpdateAction>(); StringBuffer xp; CmsXmlUpdateAction action0 = new CmsXmlUpdateAction() { @SuppressWarnings("unchecked") @Override public boolean executeUpdate(Document doc, String xpath, boolean forReal) { Node node = doc.selectSingleNode(xpath); org.dom4j.Element parent = node.getParent(); int position = parent.indexOf(node); parent.remove(node); try { parent.elements().add(position, createElementFromXml(" <documenttypes> \n" + " <documenttype>\n" + " <name>generic</name>\n" + " <class>org.opencms.search.documents.CmsDocumentGeneric</class>\n" + " <mimetypes/>\n" + " <resourcetypes>\n" + " <resourcetype>*</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>html</name>\n" + " <class>org.opencms.search.documents.CmsDocumentHtml</class>\n" + " <mimetypes>\n" + " <mimetype>text/html</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype>\n" + " <documenttype>\n" + " <name>image</name>\n" + " <class>org.opencms.search.documents.CmsDocumentGeneric</class>\n" + " <mimetypes/>\n" + " <resourcetypes>\n" + " <resourcetype>image</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>jsp</name>\n" + " <class>org.opencms.search.documents.CmsDocumentPlainText</class>\n" + " <mimetypes/>\n" + " <resourcetypes>\n" + " <resourcetype>jsp</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>pdf</name>\n" + " <class>org.opencms.search.documents.CmsDocumentPdf</class>\n" + " <mimetypes>\n" + " <mimetype>application/pdf</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>binary</resourcetype>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype>\n" + " <documenttype>\n" + " <name>rtf</name>\n" + " <class>org.opencms.search.documents.CmsDocumentRtf</class>\n" + " <mimetypes>\n" + " <mimetype>text/rtf</mimetype>\n" + " <mimetype>application/rtf</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>binary</resourcetype>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>text</name>\n" + " <class>org.opencms.search.documents.CmsDocumentPlainText</class>\n" + " <mimetypes>\n" + " <mimetype>text/html</mimetype>\n" + " <mimetype>text/plain</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>xmlcontent</name>\n" + " <class>org.opencms.search.documents.CmsDocumentXmlContent</class>\n" + " <mimetypes/>\n" + " <resourcetypes>\n" + " <resourcetype>*</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype>\n" + " <documenttype>\n" + " <name>containerpage</name>\n" + " <class>org.opencms.search.documents.CmsDocumentContainerPage</class>\n" + " <mimetypes>\n" + " <mimetype>text/html</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>containerpage</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>xmlpage</name>\n" + " <class>org.opencms.search.documents.CmsDocumentXmlPage</class>\n" + " <mimetypes>\n" + " <mimetype>text/html</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>xmlpage</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype>\n" + " <documenttype>\n" + " <name>xmlcontent-galleries</name>\n" + " <class>org.opencms.search.galleries.CmsGalleryDocumentXmlContent</class>\n" + " <mimetypes/>\n" + " <resourcetypes>\n" + " <resourcetype>xmlcontent-galleries</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>xmlpage-galleries</name>\n" + " <class>org.opencms.search.galleries.CmsGalleryDocumentXmlPage</class>\n" + " <mimetypes />\n" + " <resourcetypes>\n" + " <resourcetype>xmlpage-galleries</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>msoffice-ole2</name>\n" + " <class>org.opencms.search.documents.CmsDocumentMsOfficeOLE2</class>\n" + " <mimetypes>\n" + " <mimetype>application/vnd.ms-powerpoint</mimetype>\n" + " <mimetype>application/msword</mimetype> \n" + " <mimetype>application/vnd.ms-excel</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>binary</resourcetype>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>msoffice-ooxml</name>\n" + " <class>org.opencms.search.documents.CmsDocumentMsOfficeOOXML</class>\n" + " <mimetypes> \n" + " <mimetype>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mimetype>\n" + " <mimetype>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mimetype>\n" + " <mimetype>application/vnd.openxmlformats-officedocument.presentationml.presentation</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>binary</resourcetype>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype> \n" + " <documenttype>\n" + " <name>openoffice</name>\n" + " <class>org.opencms.search.documents.CmsDocumentOpenOffice</class>\n" + " <mimetypes>\n" + " <mimetype>application/vnd.oasis.opendocument.text</mimetype>\n" + " <mimetype>application/vnd.oasis.opendocument.spreadsheet</mimetype>\n" + " </mimetypes>\n" + " <resourcetypes>\n" + " <resourcetype>binary</resourcetype>\n" + " <resourcetype>plain</resourcetype>\n" + " </resourcetypes>\n" + " </documenttype>\n" + " </documenttypes>\n")); } catch (DocumentException e) { System.out.println("failed to update document types."); } return true; } }; m_actions.put(buildXpathForDoctypes(), action0); // //============================================================================================================= // CmsXmlUpdateAction action1 = new CmsXmlUpdateAction() { @SuppressWarnings("synthetic-access") @Override public boolean executeUpdate(Document doc, String xpath, boolean forReal) { Node node = doc.selectSingleNode(xpath); if (node == null) { createAnalyzer(doc, xpath, CmsGallerySearchAnalyzer.class, "all"); return true; } return false; } }; xp = new StringBuffer(256); xp.append(getCommonPath()); xp.append("/"); xp.append(CmsSearchConfiguration.N_ANALYZERS); xp.append("/"); xp.append(CmsSearchConfiguration.N_ANALYZER); xp.append("["); xp.append(CmsSearchConfiguration.N_CLASS); xp.append("='").append(CmsGallerySearchAnalyzer.class.getName()).append("']"); m_actions.put(xp.toString(), action1); // //============================================================================================================= // CmsXmlUpdateAction action2 = new CmsXmlUpdateAction() { @SuppressWarnings("synthetic-access") @Override public boolean executeUpdate(Document doc, String xpath, boolean forReal) { Node node = doc.selectSingleNode(xpath); if (node != null) { node.detach(); } createIndex(doc, xpath, CmsGallerySearchIndex.class, CmsGallerySearchIndex.GALLERY_INDEX_NAME, "offline", "Offline", "all", "gallery_fields", new String[] { "gallery_source", "gallery_modules_source" }); return true; } }; xp = new StringBuffer(256); xp.append(getCommonPath()); xp.append("/"); xp.append(CmsSearchConfiguration.N_INDEXES); xp.append("/"); xp.append(CmsSearchConfiguration.N_INDEX); xp.append("["); xp.append(I_CmsXmlConfiguration.N_NAME); xp.append("='").append(CmsGallerySearchIndex.GALLERY_INDEX_NAME).append("']"); m_actions.put(xp.toString(), action2); // //============================================================================================================= // CmsXmlUpdateAction action3 = new CmsXmlUpdateAction() { @SuppressWarnings("synthetic-access") @Override public boolean executeUpdate(Document doc, String xpath, boolean forReal) { Node node = doc.selectSingleNode(xpath); if (node != null) { return false; } // create doc type createIndexSource(doc, xpath, "gallery_source", CmsVfsIndexer.class, new String[] { "/sites/", "/shared/", "/system/galleries/" }, new String[] { "xmlpage-galleries", "xmlcontent-galleries", "jsp", "text", "pdf", "rtf", "html", "image", "generic", "openoffice", "msoffice-ole2", "msoffice-ooxml" }); return true; } }; xp = new StringBuffer(256); xp.append(getCommonPath()); xp.append("/"); xp.append(CmsSearchConfiguration.N_INDEXSOURCES); xp.append("/"); xp.append(CmsSearchConfiguration.N_INDEXSOURCE); xp.append("["); xp.append(I_CmsXmlConfiguration.N_NAME); xp.append("='gallery_source']"); m_actions.put(xp.toString(), action3); // //============================================================================================================= // CmsXmlUpdateAction action4 = new CmsXmlUpdateAction() { @Override public boolean executeUpdate(Document document, String xpath, boolean forReal) { Node node = document.selectSingleNode(xpath); if (node != null) { node.detach(); } // create field config CmsSearchFieldConfiguration fieldConf = new CmsSearchFieldConfiguration(); fieldConf.setName("gallery_fields"); fieldConf.setDescription("The standard OpenCms search index field configuration."); CmsSearchField field = new CmsSearchField(); // <field name="content" store="compress" index="true" excerpt="true"> field.setName("content"); field.setStored("compress"); field.setIndexed("true"); field.setInExcerpt("true"); field.setDisplayNameForConfiguration("%(key.field.content)"); // <mapping type="content" /> CmsSearchFieldMapping mapping = new CmsSearchFieldMapping(); mapping.setType("content"); field.addMapping(mapping); fieldConf.addField(field); // <field name="title-key" store="true" index="untokenized" boost="0.0"> field = new CmsSearchField(); field.setName("title-key"); field.setStored("true"); field.setIndexed("untokenized"); field.setBoost("0.0"); // <mapping type="property">Title</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("property"); mapping.setParam("Title"); field.addMapping(mapping); fieldConf.addField(field); // <field name="title" store="false" index="true"> field = new CmsSearchField(); field.setName("title"); field.setStored("false"); field.setIndexed("true"); field.setDisplayNameForConfiguration("%(key.field.title)"); // <mapping type="property">Title</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("property"); mapping.setParam("Title"); field.addMapping(mapping); fieldConf.addField(field); // <field name="description" store="true" index="true"> field = new CmsSearchField(); field.setName("description"); field.setStored("true"); field.setIndexed("true"); field.setDisplayNameForConfiguration("%(key.field.description)"); // <mapping type="property">Description</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("property"); mapping.setParam("Description"); field.addMapping(mapping); fieldConf.addField(field); // <field name="meta" store="false" index="true"> field = new CmsSearchField(); field.setName("meta"); field.setStored("false"); field.setIndexed("true"); // <mapping type="property">Title</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("property"); mapping.setParam("Title"); field.addMapping(mapping); // <mapping type="property">Description</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("property"); mapping.setParam("Description"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_dateExpired" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_dateExpired"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">dateExpired</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("dateExpired"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_dateReleased" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_dateReleased"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">dateReleased</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("dateReleased"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_length" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_length"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">length</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("length"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_state" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_state"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">state</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("state"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_structureId" store="true" index="false"> field = new CmsSearchField(); field.setName("res_structureId"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">structureId</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("structureId"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_userCreated" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_userCreated"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">userCreated</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("userCreated"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_userLastModified" store="true" index="untokenized"> field = new CmsSearchField(); field.setName("res_userLastModified"); field.setStored("true"); field.setIndexed("untokenized"); // <mapping type="attribute">userLastModified</mapping> mapping = new CmsSearchFieldMapping(); mapping.setType("attribute"); mapping.setParam("userLastModified"); field.addMapping(mapping); fieldConf.addField(field); // <field name="res_locales" store="true" index="true" analyzer="WhitespaceAnalyzer"> field = new CmsSearchField(); field.setName("res_locales"); field.setStored("true"); field.setIndexed("true"); try { field.setAnalyzer("WhitespaceAnalyzer"); } catch (Exception e) { // ignore e.printStackTrace(); } // <mapping type="dynamic" class="org.opencms.search.galleries.CmsGallerySearchFieldMapping">res_locales</mapping> mapping = new CmsGallerySearchFieldMapping(); mapping.setType("dynamic"); mapping.setParam("res_locales"); field.addMapping(mapping); fieldConf.addField(field); // <field name="additional_info" store="true" index="false"> field = new CmsSearchField(); field.setName("additional_info"); field.setStored("true"); field.setIndexed("false"); // <mapping type="dynamic" class="org.opencms.search.galleries.CmsGallerySearchFieldMapping">additional_info</mapping> mapping = new CmsGallerySearchFieldMapping(); mapping.setType("dynamic"); mapping.setParam("additional_info"); field.addMapping(mapping); fieldConf.addField(field); // <field name="container_types" store="true" index="true" analyzer="WhitespaceAnalyzer"> field = new CmsSearchField(); field.setName("container_types"); field.setStored("true"); field.setIndexed("true"); try { field.setAnalyzer("WhitespaceAnalyzer"); } catch (Exception e) { // ignore e.printStackTrace(); } // <mapping type="dynamic" class="org.opencms.search.galleries.CmsGallerySearchFieldMapping">container_types</mapping> mapping = new CmsGallerySearchFieldMapping(); mapping.setType("dynamic"); mapping.setParam("container_types"); field.addMapping(mapping); fieldConf.addField(field); createFieldConfig(document, xpath, fieldConf, CmsGallerySearchFieldConfiguration.class); return true; } }; xp = new StringBuffer(256); xp.append(getCommonPath()); xp.append("/"); xp.append(CmsSearchConfiguration.N_FIELDCONFIGURATIONS); xp.append("/"); xp.append(CmsSearchConfiguration.N_FIELDCONFIGURATION); xp.append("["); xp.append(I_CmsXmlConfiguration.N_NAME); xp.append("='gallery_fields']"); m_actions.put(xp.toString(), action4); // //============================================================================================================= // m_actions.put("/opencms/search/indexsources", new CmsIndexSourceTypeUpdateAction()); // use dummy check [1=1] to make the xpaths unique m_actions.put("/opencms/search/indexsources[1=1]", new CmsAddGalleryModuleIndexSourceAction()); m_actions.put(buildXpathForIndexedDocumentType("source1", "containerpage"), createIndexedTypeAction("containerpage")); //============================================================================================================= String analyzerEnPath = "/opencms/search/analyzers/analyzer[class='org.apache.lucene.analysis.standard.StandardAnalyzer'][locale='en']"; m_actions.put(analyzerEnPath, new ElementReplaceAction(analyzerEnPath, "<analyzer>\n" + " <class>org.apache.lucene.analysis.en.EnglishAnalyzer</class>\n" + " <locale>en</locale>\n" + " </analyzer>")); String analyzerItPath = "/opencms/search/analyzers/analyzer[class='org.apache.lucene.analysis.snowball.SnowballAnalyzer'][stemmer='Italian']"; m_actions.put(analyzerItPath, new ElementReplaceAction(analyzerItPath, "<analyzer>\n" + " <class>org.apache.lucene.analysis.it.ItalianAnalyzer</class>\n" + " <locale>it</locale>\n" + " </analyzer>")); m_actions.put( "/opencms/search/indexsources/indexsource[name='gallery_source']/resources['systemgalleries'='systemgalleries']", new CmsAddIndexSourceResourceAction()); }
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> * /* 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 */ @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.xforms.action.actions.XFormsDeleteAction.java
License:Open Source License
private static DeleteInfo doDeleteOne(IndentedLogger indentedLogger, List collectionToUpdate, int deleteIndex) { final NodeInfo nodeInfoToRemove = (NodeInfo) collectionToUpdate.get(deleteIndex - 1); final NodeInfo parentNodeInfo = nodeInfoToRemove.getParent(); final Node nodeToRemove = XFormsUtils.getNodeFromNodeInfo(nodeInfoToRemove, CANNOT_DELETE_READONLY_MESSAGE); final List contentToUpdate; final int indexInContentToUpdate; final Element parentElement = nodeToRemove.getParent(); if (parentElement != null) { // Regular case if (nodeToRemove instanceof Attribute) { contentToUpdate = parentElement.attributes(); } else {/* www .ja v a 2 s. c o m*/ contentToUpdate = parentElement.content(); } indexInContentToUpdate = contentToUpdate.indexOf(nodeToRemove); } else if (nodeToRemove.getDocument() != null && nodeToRemove == nodeToRemove.getDocument().getRootElement()) { // Case of root element where parent is Document contentToUpdate = nodeToRemove.getDocument().content(); indexInContentToUpdate = contentToUpdate.indexOf(nodeToRemove); } else if (nodeToRemove instanceof Document) { // Case where node to remove is Document // "except if the node is the root document element of an instance then the delete action // is terminated with no effect." if (indentedLogger.isDebugEnabled()) indentedLogger.logDebug("xf:delete", "ignoring attempt to delete document node"); return null; } else { // Node to remove doesn't have a parent so we can't delete it // This can happen for nodes already detached, or nodes newly created with e.g. xf:element() return null; } // Actually perform the deletion // "The node at the delete location in the Node Set Binding node-set is deleted" contentToUpdate.remove(indexInContentToUpdate); return new DeleteInfo(parentNodeInfo, nodeInfoToRemove, indexInContentToUpdate); }
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; {// ww w. ja v a 2 s . c om 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.xforms.function.xxforms.XXFormsCallXPL.java
License:Open Source License
public SequenceIterator iterate(XPathContext xpathContext) throws XPathException { try {// w ww .j a va2s . co m // Get XPL URL final URL xplURL; { Expression xplURIExpression = argument[0]; //xplURL = new URL(((AnyURIValue) xplURIExpression.evaluateItem(xpathContext)).getStringValue()); if (getSystemId() == null) xplURL = URLFactory.createURL(xplURIExpression.evaluateAsString(xpathContext).toString()); else xplURL = URLFactory.createURL(getSystemId(), xplURIExpression.evaluateAsString(xpathContext).toString()); } // Get list of input names final List<String> inputNames = new ArrayList<String>(); { final Expression inputNamesExpression = argument[1]; final SequenceIterator i = inputNamesExpression.iterate(xpathContext); Item currentItem; while ((currentItem = i.next()) != null) { inputNames.add(currentItem.getStringValue()); } } // Get list of input documents final List<Item> inputNodeInfos = new ArrayList<Item>(); { final Expression inputDocumentsExpression = argument[2]; final SequenceIterator i = inputDocumentsExpression.iterate(xpathContext); Item currentItem; while ((currentItem = i.next()) != null) { inputNodeInfos.add(currentItem); } } if (inputNames.size() != inputNodeInfos.size()) throw new OXFException("The length of sequence of input names (" + inputNames.size() + ") must be equal to the length of the sequence of input nodes (" + inputNodeInfos.size() + ").");//getDisplayName() // Get list of output names final List<String> outputNames = new ArrayList<String>(); { final Expression inputNamesExpression = argument[3]; final SequenceIterator i = inputNamesExpression.iterate(xpathContext); Item currentItem; while ((currentItem = i.next()) != null) { outputNames.add(currentItem.getStringValue()); } } // Create processor definition and processor Processor processor; { ProcessorDefinition processorDefinition = new ProcessorDefinition(); { processorDefinition.setName(new QName("pipeline", XMLConstants.OXF_PROCESSORS_NAMESPACE)); processorDefinition.addInput("config", xplURL.toExternalForm()); Iterator inputNodesIterator = inputNodeInfos.iterator(); for (final String inputName : inputNames) { final NodeInfo inputNodeInfo = (NodeInfo) inputNodesIterator.next(); if (!(inputNodeInfo.getNodeKind() == org.w3c.dom.Node.ELEMENT_NODE || inputNodeInfo.getNodeKind() == org.w3c.dom.Node.DOCUMENT_NODE)) throw new OXFException( "Input node must be a document or element for input name: " + inputName); // TODO: We should be able to just pass inputNodeInfo to addInput() and avoid the conversions, but that doesn't work! if (inputNodeInfo instanceof VirtualNode) { // Get reference to dom4j node final Element inputElement; final Node inputNode = (Node) ((VirtualNode) inputNodeInfo).getUnderlyingNode(); if (inputNode instanceof Document) inputElement = ((Document) inputNode).getRootElement(); else if (inputNode instanceof Element && inputNode.getParent() == null) inputElement = (Element) inputNode; else if (inputNode instanceof Element) inputElement = Dom4jUtils.createDocumentCopyParentNamespaces((Element) inputNode) .getRootElement(); else throw new OXFException( "Input node must be a document or element for input name: " + inputName); processorDefinition.addInput(inputName, inputElement); } else { // Copy to dom4j // final DocumentInfo inputDocumentInfo = TransformerUtils.readTinyTree(inputNodeInfo); // processorDefinition.addInput(inputName, inputDocumentInfo); final Document inputDocument = TransformerUtils.tinyTreeToDom4j(inputNodeInfo); processorDefinition.addInput(inputName, inputDocument.getRootElement()); } } } processor = InitUtils.createProcessor(processorDefinition); } final PipelineContext pipelineContext = PipelineContext.get(); processor.reset(pipelineContext); if (outputNames.size() == 0) { // Just run the processor processor.start(pipelineContext); return EmptyIterator.getInstance(); } else { // Create all outputs to read List<ProcessorOutput> outputs = new ArrayList<ProcessorOutput>(outputNames.size()); for (String outputName : outputNames) { ProcessorOutput output = processor.createOutput(outputName); outputs.add(output); } // Connect all DOM serializers List<DOMSerializer> domSerializers = new ArrayList<DOMSerializer>(outputNames.size()); for (ProcessorOutput output : outputs) { DOMSerializer domSerializer = new DOMSerializer(); PipelineUtils.connect(processor, output.getName(), domSerializer, "data"); domSerializers.add(domSerializer); } // Read all outputs in sequence List<DocumentWrapper> results = new ArrayList<DocumentWrapper>(outputNames.size()); for (DOMSerializer domSerializer : domSerializers) { results.add(new DocumentWrapper( (Document) Dom4jUtils.normalizeTextNodes(domSerializer.runGetDocument(pipelineContext)), null, xpathContext.getConfiguration())); } return new ListIterator(results); } } catch (XPathException e) { throw e; } catch (Exception e) { throw new OXFException(e); } }
From source file:org.withinsea.izayoi.commons.dom.DOMUtils.java
License:Mozilla Public License
public static Branch parent(Node node) { Branch parent = node.getParent(); if (parent == null) parent = node.getDocument();//from w w w . jav a 2 s. c om return parent; }
From source file:org.withinsea.izayoi.cortile.core.compile.dom.DOMCompiler.java
License:Mozilla Public License
protected boolean isDetached(Node node) { return (node.getParent() == null && node.getDocument() == null); }