Example usage for org.dom4j Node clone

List of usage examples for org.dom4j Node clone

Introduction

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

Prototype

Object clone();

Source Link

Document

clone will return a deep clone or if this node is read-only then clone will return the same instance.

Usage

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

License:Open Source License

/**
 * Updates the given doc inserting the given node corresponding to the given xpath.<p>
 * /*  w w  w  .  ja v  a2s.c  o  m*/
 * @param document the original document to update
 * @param newDoc the document to update
 * @param xpath the corresponding xpath
 */
protected void updateDoc(Document document, Document newDoc, String xpath) {

    Node node = document.selectSingleNode(xpath);
    if (node != null) {
        CmsSetupXmlHelper.setValue(newDoc, CmsXmlUtils.removeLastComplexXpathElement(xpath), " ");
        node = (Node) node.clone();
        node.setParent(null);
        ((Branch) newDoc.selectSingleNode(CmsXmlUtils.removeLastComplexXpathElement(xpath))).add(node);
    }
}

From source file:org.opencms.setup.xml.v7.CmsXmlUpdateLocalizationKeys.java

License:Open Source License

/**
 * @see org.opencms.setup.xml.A_CmsSetupXmlUpdate#prepareDoc(org.dom4j.Document)
 */// ww  w .j  a  v  a2  s . co  m
@Override
protected Document prepareDoc(Document doc) {

    Document newDoc = super.prepareDoc(doc);
    String xpath = getCommonPath();
    Node node = doc.selectSingleNode(xpath);
    CmsSetupXmlHelper.setValue(newDoc, CmsXmlUtils.removeLastComplexXpathElement(xpath), "");
    node = (Node) node.clone();
    node.setParent(null);
    ((Branch) newDoc.selectSingleNode(CmsXmlUtils.removeLastComplexXpathElement(xpath))).add(node);
    return newDoc;
}

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  .j  a  v  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;
    {//from   w  ww  .  j  a v a2 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.xml.dom4j.Dom4jUtils.java

License:Open Source License

/**
 * Create a copy of a dom4j Node./*from w ww .java 2 s .c o m*/
 *
 * @param source    source Node
 * @return          copy of Node
 */
public static Node createCopy(Node source) {
    return (source instanceof Element) ? ((Element) source).createCopy() : (Node) source.clone();
}

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 {/*from w w  w . j  a  va 2s .  com*/
            cln = (org.dom4j.Node) node.clone();
        }
        add(cln);
    }
}

From source file:org.pentaho.platform.repository.solution.filebased.FileBasedSolutionRepository.java

License:Open Source License

private Document getActionSequences(final String solution, final String path, final boolean subDirectories,
        final boolean visibleOnly, final int actionOperation) {
    List nodes;//from ww  w . jav  a  2s. c  om
    if (solution == null) {
        nodes = getSolutionNames(solution, path, actionOperation, visibleOnly);
    } else {
        nodes = getFileListIterator(solution, path, subDirectories, visibleOnly);
    }
    Document document = DocumentHelper.createDocument();
    Element root = document.addElement("files"); //$NON-NLS-1$
    Element pathNames = root.addElement("location"); //$NON-NLS-1$

    pathNames.setText(getPathNames(solution, path));

    Iterator nodeIterator = nodes.iterator();
    while (nodeIterator.hasNext()) {
        Node node = (Node) nodeIterator.next();
        root.add((Node) node.clone());
    }
    return document;
}

From source file:revaligner.service.FileAligner.java

public void fixTxlfTrgTags(org.dom4j.Document doc) throws Exception {
    org.dom4j.Element root = doc.getRootElement();
    List<org.dom4j.Element> list_transunit = root.selectNodes("//*[name() = 'trans-unit']");
    for (org.dom4j.Element e : list_transunit) {
        org.dom4j.Element source = e.element("source");
        org.dom4j.Element target = e.element("target");
        if ((target != null) && (!target.getText().equals(""))) {
            HashMap<String, List<Object>> src_map = new HashMap();
            boolean tagnodeappear = false;
            boolean textnodeappear = false;
            boolean sourcetagsurroundtext = true;
            int maxid = 1;
            for (int i = 0; i < source.content().size(); i++) {
                org.dom4j.Node node = (org.dom4j.Node) source.content().get(i);
                if (node.getNodeType() == 1) {
                    org.dom4j.Element tag = (org.dom4j.Element) node;
                    maxid = Math.max(maxid, Integer.parseInt(tag.attributeValue("id")));
                }//w  ww . j a  va 2 s  .c om
            }
            maxid++;
            for (int i = 0; i < source.content().size(); i++) {
                org.dom4j.Node node = (org.dom4j.Node) source.content().get(i);
                if (node.getNodeType() == 1) {
                    if (textnodeappear) {
                        tagnodeappear = true;
                    }
                    org.dom4j.Element tag = (org.dom4j.Element) node;
                    String key = "";
                    if ((tag.getName().equals("ex")) || (tag.getName().equals("ept"))) {
                        key = tag.getName() + "#" + tag.attributeValue("rid");
                    } else if (tag.getName().equals("x")) {
                        key = tag.getName() + "#" + tag.attributeValue("ctype");
                    } else {
                        key = tag.getName();
                    }
                    if (src_map.containsKey(key)) {
                        ((List) src_map.get(key)).add(node.clone());
                    } else {
                        List<Object> list = new ArrayList();
                        list.add(node.clone());
                        src_map.put(key, list);
                    }
                } else {
                    if (tagnodeappear) {
                        sourcetagsurroundtext = false;
                    }
                    textnodeappear = true;
                }
            }
            HashMap<String, String> rid_map = new HashMap();
            List trg_contents = new ArrayList();
            boolean targetnotag = true;
            for (int i = 0; i < target.content().size(); i++) {
                org.dom4j.Node node = (org.dom4j.Node) target.content().get(i);
                if (node.getNodeType() == 1) {
                    org.dom4j.Element tag = (org.dom4j.Element) node;
                    String rid = tag.attributeValue("rid");
                    String key = "";
                    if ((tag.getName().equals("ph")) || (tag.getName().equals("bpt"))
                            || (tag.getName().equals("bx"))) {
                        key = tag.getName();
                        if (src_map.containsKey(key)) {
                            List list = (List) src_map.get(key);
                            trg_contents.add(list.get(0));
                            targetnotag = false;
                            rid_map.put(rid, ((org.dom4j.Element) list.get(0)).attributeValue("rid"));
                            list.remove(0);
                            if (list.size() == 0) {
                                src_map.remove(key);
                            }
                        }
                    } else if (tag.getName().equals("x")) {
                        key = tag.getName() + "#" + tag.attributeValue("ctype");
                        if (src_map.containsKey(key)) {
                            List list = (List) src_map.get(key);
                            trg_contents.add(list.get(0));
                            targetnotag = false;
                            list.remove(0);
                            if (list.size() == 0) {
                                src_map.remove(key);
                            }
                        } else if ((tag.getName().equals("x"))
                                && (tag.attributeValue("ctype").equals("x-tab"))) {
                            org.dom4j.Element tab = DocumentHelper.createElement("x");
                            tab.addAttribute("ctype", "x-tab");
                            tab.addAttribute("id", Integer.toString(maxid));
                            maxid++;
                            tab.addAttribute("equiv-text", " ");
                            trg_contents.add(tab);
                        } else if ((tag.getName().equals("x")) && (tag.attributeValue("ctype").equals("lb"))) {
                            org.dom4j.Element lb = DocumentHelper.createElement("x");
                            lb.addAttribute("ctype", "lb");
                            lb.addAttribute("id", Integer.toString(maxid));
                            maxid++;
                            lb.addAttribute("equiv-text", " ");
                            trg_contents.add(lb);
                        }
                    } else if ((tag.getName().equals("ex")) || (tag.getName().equals("ept"))) {
                        String mapped_rid = (String) rid_map.get(tag.attributeValue("rid"));
                        key = tag.getName() + "#" + mapped_rid;
                        if (src_map.containsKey(key)) {
                            List list = (List) src_map.get(key);
                            trg_contents.add(list.get(0));
                            rid_map.put(rid, ((org.dom4j.Element) list.get(0)).attributeValue("rid"));
                            list.remove(0);
                            if (list.size() == 0) {
                                src_map.remove(key);
                            }
                        }
                    }
                } else if (node.getNodeType() == 3) {
                    String text = node.getText();
                    if (text.contains("<br> ")) {
                        String key = "x#lb";
                        String[] ss = text.split("<br> ");
                        for (int s = 0; s < ss.length; s++) {
                            trg_contents.add(DocumentHelper.createText(ss[s]));
                            if (s < ss.length - 1) {
                                if (src_map.containsKey(key)) {
                                    List list = (List) src_map.get(key);
                                    trg_contents.add(list.get(0));
                                    targetnotag = false;
                                    list.remove(0);
                                    if (list.size() == 0) {
                                        src_map.remove(key);
                                    }
                                } else {
                                    org.dom4j.Element lb = DocumentHelper.createElement("x");
                                    lb.addAttribute("ctype", "lb");
                                    lb.addAttribute("id", Integer.toString(maxid));
                                    maxid++;
                                    lb.addAttribute("equiv-text", " ");
                                    trg_contents.add(lb);
                                }
                            }
                        }
                    } else if (text.contains("<br>")) {
                        String key = "x#lb";
                        String[] ss = text.split("<br> ");
                        for (int s = 0; s < ss.length; s++) {
                            trg_contents.add(DocumentHelper.createText(ss[s]));
                            if (s < ss.length - 1) {
                                if (src_map.containsKey(key)) {
                                    List list = (List) src_map.get(key);
                                    trg_contents.add(list.get(0));
                                    targetnotag = false;
                                    list.remove(0);
                                    if (list.size() == 0) {
                                        src_map.remove(key);
                                    }
                                } else {
                                    org.dom4j.Element lb = DocumentHelper.createElement("x");
                                    lb.addAttribute("ctype", "lb");
                                    lb.addAttribute("id", Integer.toString(maxid));
                                    maxid++;
                                    lb.addAttribute("equiv-text", " ");
                                    trg_contents.add(lb);
                                }
                            }
                        }
                    } else {
                        trg_contents.add(node);
                    }
                } else {
                    trg_contents.add(node);
                }
            }
            while (trg_contents.size() > 0) {
                org.dom4j.Node nd = (org.dom4j.Node) trg_contents.get(0);
                if (nd.getNodeType() == 3) {
                    if (nd.getText().trim().equals("")) {
                        trg_contents.remove(0);
                    } else {
                        nd.setText(nd.getText().replaceAll("^(\\s)+", ""));
                        break;
                    }
                } else if ((nd.getNodeType() == 1) && (nd.getName().equals("x"))
                        && (((org.dom4j.Element) nd).attributeValue("ctype").equals("lb"))) {
                    trg_contents.remove(0);
                } else {
                    if ((nd.getNodeType() != 1) || (!nd.getName().equals("x"))
                            || (!((org.dom4j.Element) nd).attributeValue("ctype").equals("x-tab"))) {
                        break;
                    }
                    trg_contents.remove(0);
                }
            }
            while (trg_contents.size() > 0) {
                org.dom4j.Node nd = (org.dom4j.Node) trg_contents.get(trg_contents.size() - 1);
                if (nd.getNodeType() == 3) {
                    if (nd.getText().trim().equals("")) {
                        trg_contents.remove(trg_contents.size() - 1);
                    } else {
                        nd.setText(nd.getText().replaceAll("(\\s)+$", ""));
                        break;
                    }
                } else if ((nd.getNodeType() == 1) && (nd.getName().equals("x"))
                        && (((org.dom4j.Element) nd).attributeValue("ctype").equals("lb"))) {
                    trg_contents.remove(trg_contents.size() - 1);
                } else {
                    if ((nd.getNodeType() != 1) || (!nd.getName().equals("x"))
                            || (!((org.dom4j.Element) nd).attributeValue("ctype").equals("x-tab"))) {
                        break;
                    }
                    trg_contents.remove(trg_contents.size() - 1);
                }
            }
            boolean isnotignoredsegment = true;
            if (trg_contents.size() == 1) {
                org.dom4j.Node node = (org.dom4j.Node) trg_contents.get(0);
                if ((node.getNodeType() == 3) && (node.getText().replaceFirst("", "").equals(""))) {
                    isnotignoredsegment = false;
                }
            }
            if ((targetnotag) && (sourcetagsurroundtext) && (isnotignoredsegment)) {
                boolean isleadingtag = true;
                int index = 0;
                for (int i = 0; i < source.content().size(); i++) {
                    org.dom4j.Node node = (org.dom4j.Node) source.content().get(i);
                    if (node.getNodeType() == 1) {
                        if (isleadingtag) {
                            trg_contents.add(index, node);
                            index++;
                        } else {
                            trg_contents.add(node);
                        }
                    } else {
                        isleadingtag = false;
                        index++;
                    }
                }
            }
            target.setContent(trg_contents);
        }
    }
}