Example usage for org.jdom2.xpath XPathHelper getRelativePath

List of usage examples for org.jdom2.xpath XPathHelper getRelativePath

Introduction

In this page you can find the example usage for org.jdom2.xpath XPathHelper getRelativePath.

Prototype

public static String getRelativePath(final Attribute from, final Content to) 

Source Link

Document

Returns the relative path from the given from Attribute to the specified to Content as an XPath expression.

Usage

From source file:org.jumpmind.metl.core.runtime.component.XmlFormatter.java

License:Open Source License

private void addModelAttributeXml(Stack<DocElement> parentStack, String attributeId, Object modelAttrValue,
        Document generatedXml, String entityId) {

    DocElement templateDocElement = entityAttributeDtls.get(attributeId);
    String value = modelAttrValue == null ? null : modelAttrValue.toString();
    Element newElement = null;// w  w w .  j a va 2s.c o m
    Element templateParentElement = null;
    String templateParentXPath = null;
    Attribute newAttribute = null;
    Map<Element, Namespace> generatedDocNamespaces = null;
    Map<Element, Namespace> templateNamespaces = null;
    Stack<Element> parentsToAdd = new Stack<Element>();
    DocElement entityDocElement = entityAttributeDtls.get(entityId);

    generatedDocNamespaces = removeNamespaces(generatedXml);
    templateNamespaces = removeNamespaces(templateDoc);

    // we can be passed elements in the model that don't reside in the
    // template. If so, just ignore the field and do nothing
    if (templateDocElement != null) {
        // at this point, our stack should always currently have the entity
        // for this attribute as the top level of the stack

        // set up our new element or attribute to add
        if (templateDocElement.xmlElement != null) {
            // we have to add an element
            newElement = templateDocElement.xmlElement.clone();
            newElement.removeContent();
            removeAllAttributes(newElement);

            if (StringUtils.isEmpty(value)) {
                if (nullHandling.equalsIgnoreCase(NULL_HANDLING_XML_NIL)) {
                    newElement.setAttribute("nil", "true", getXmlNamespace());
                }
            } else {
                newElement.setText(value);
            }
        } else {
            // we have to add an attribute
            newAttribute = templateDocElement.xmlAttribute.clone();
            if (value != null) {
                newAttribute.setValue(value);
            }
        }

        // in this case the attribute is one lower than the entity and
        // should simply be attached to the entity
        if (templateDocElement.level - 1 == parentStack.peek().level) {
            if (newElement != null) {
                applyAttributeXPath(generatedXml, templateDocElement.xpath, value);
            } else {
                parentStack.peek().xmlElement.setAttribute(newAttribute);
            }
        } else {
            // the attribute doesn't hang directly off the entity
            // we must find its parent in the existing doc or fill static
            // content as appropriate

            // first get the parent element for this model attribute, and
            // gets its xpath
            XPathExpression<Element> expression = XPathFactory.instance().compile(templateDocElement.xpath,
                    Filters.element());
            List<Element> matches = expression.evaluate(templateDoc.getRootElement());
            if (matches.size() != 0) {
                templateParentElement = matches.get(0).getParentElement();
            } else {
                // throw an exception, we should always find the element in
                // the template
            }

            // now look for parent elements in the generated xml until we
            // find one
            // or we hit the entity itself
            boolean parentFound = false;
            do {
                templateParentXPath = XPathHelper.getRelativePath(entityDocElement.xmlElement,
                        templateParentElement);
                expression = XPathFactory.instance().compile(templateParentXPath, Filters.element());
                matches = expression.evaluate(parentStack.peek().xmlElement);
                if (matches.size() == 0) {
                    Element elementToAdd = templateParentElement.clone();
                    elementToAdd.removeContent();
                    removeAllAttributes(elementToAdd);
                    parentsToAdd.push(elementToAdd);
                    templateParentElement = templateParentElement.getParentElement();
                } else {
                    parentFound = true;
                }
            } while (parentFound == false);

            // add every parent we couldn't find up to the entity level
            Element elementToAddTo = matches.get(0);
            while (!parentsToAdd.isEmpty()) {
                elementToAddTo.addContent(0, parentsToAdd.peek());
                elementToAddTo = parentsToAdd.pop();
            }

            // add our model attribute to the latest level
            if (newElement != null) {
                applyAttributeXPath(generatedXml, templateDocElement.xpath, value);
            } else {
                elementToAddTo.setAttribute(newAttribute);
            }
        }
    }
    restoreNamespaces(templateDoc, templateNamespaces);
    restoreNamespaces(generatedXml, generatedDocNamespaces);
}