All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlasmap.xml.inspect.InstanceInspector Maven / Gradle / Ivy

/**
 * Copyright (C) 2017 Red Hat, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.atlasmap.xml.inspect;

import io.atlasmap.v2.CollectionType;
import io.atlasmap.v2.FieldStatus;
import io.atlasmap.v2.FieldType;
import io.atlasmap.v2.Fields;
import io.atlasmap.xml.v2.AtlasXmlModelFactory;
import io.atlasmap.xml.v2.XmlComplexType;
import io.atlasmap.xml.v2.XmlDocument;
import io.atlasmap.xml.v2.XmlField;
import io.atlasmap.xml.v2.XmlFields;
import io.atlasmap.xml.v2.XmlNamespace;
import io.atlasmap.xml.v2.XmlNamespaces;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.XMLConstants;

public class InstanceInspector {

    private XmlDocument xmlDocument = AtlasXmlModelFactory.createXmlDocument();

    public InstanceInspector() {
    }

    public void inspect(Document document) {
        xmlDocument.setFields(new Fields());
        parseDocument(document.getDocumentElement());
    }

    public XmlDocument getXmlDocument() {
        return xmlDocument;
    }

    private void parseDocument(Node rootNode) {
        if (rootNode.getParentNode() != null && rootNode.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
            XmlComplexType rootComplexType = getXmlComplexType(rootNode);
            xmlDocument.getFields().getField().add(rootComplexType);
            mapAttributes(rootNode, rootComplexType);
            if (rootNode.hasChildNodes()) {
                mapChildNodes(rootNode.getChildNodes(), rootComplexType);
            }
        }
    }

    private void mapChildNodes(NodeList nodes, XmlComplexType rootComplexType) {
        for (int i = 0; i < nodes.getLength(); i++) {
            Node childNode = nodes.item(i);
            if (childNode.getNodeType() == Node.ELEMENT_NODE || childNode.getNodeType() == Node.ATTRIBUTE_NODE) {
                if (childNode.hasAttributes()) {
                    mapAttributes(childNode, rootComplexType);
                }
                if (((Element) childNode).getElementsByTagName("*").getLength() > 0) {
                    mapParentNode(childNode, rootComplexType);
                } else {
                    mapNodeToXmlField(childNode, rootComplexType);
                }
                if (childNode.getNamespaceURI() != null) {
                    mapNamespace(childNode);
                }
            }
        }
    }

    private void mapNamespace(Node node) {
        if (xmlDocument.getXmlNamespaces() == null) {
            XmlNamespaces namespaces = new XmlNamespaces();
            xmlDocument.setXmlNamespaces(namespaces);
        }
        XmlNamespace namespace = new XmlNamespace();
        namespace.setAlias(node.getPrefix());
        namespace.setUri(node.getNamespaceURI());
        if (!xmlDocument.getXmlNamespaces().getXmlNamespace().contains(namespace)) {
            xmlDocument.getXmlNamespaces().getXmlNamespace().add(namespace);
        }
    }

    private void mapParentNode(Node node, XmlComplexType parent) {
        if (node.hasChildNodes()) {
            NodeList childNodes = node.getChildNodes();
            XmlComplexType childParent = getXmlComplexType(node);

            StringBuffer stringBuffer = new StringBuffer();
            getXmlPath(node, stringBuffer);

            if (node.hasAttributes()) {
                mapAttributes(node, childParent);
            }
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node e = childNodes.item(i);
                if (e.getNodeType() == Node.ELEMENT_NODE) {
                    // do we have child elements?
                    NodeList childElements = ((Element) e).getElementsByTagName("*");
                    if (childElements.getLength() > 0) {
                        mapParentNode(e, childParent);
                    } else {
                        mapNodeToXmlField(e, childParent);
                        if (e.hasAttributes()) {
                            mapAttributes(e, childParent);
                        }
                    }
                }
            }
            mapCollectionType(childParent, (Element) node);
            parent.getXmlFields().getXmlField().add(childParent);
        }
    }

    private void mapAttributes(Node node, XmlComplexType xmlComplexType) {
        NamedNodeMap attrs = node.getAttributes();
        if (attrs != null) {
            for (int i = 0; i < attrs.getLength(); i++) {
                Node attrNode = attrs.item(i);
                // don't map default namespace attribute ...
                if (attrNode.getNamespaceURI() != null
                        && attrNode.getNamespaceURI().equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
                    continue;
                } else if (attrNode.getNamespaceURI() != null
                        && attrNode.getNamespaceURI().equals(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)) {
                    mapNamespace(attrNode);
                    xmlComplexType.setTypeName(attrNode.getTextContent());
                    continue;
                } else if (attrNode.getNamespaceURI() != null) {
                    mapNamespace(attrNode);
                }
                mapNodeToXmlField(attrNode, xmlComplexType);
            }
        }
    }

    private void mapNodeToXmlField(Node node, XmlComplexType parentComplexType) {
        XmlField xmlField = AtlasXmlModelFactory.createXmlField();
        StringBuffer sb = new StringBuffer(1024);
        getXmlPath(node, sb);
        xmlField.setPath(sb.toString());
        xmlField.setValue(node.getTextContent());
        xmlField.setFieldType(FieldType.STRING);
        xmlField.setName(node.getNodeName());
        xmlField.setStatus(FieldStatus.SUPPORTED);
        parentComplexType.getXmlFields().getXmlField().add(xmlField);
    }

    private void mapCollectionType(XmlComplexType childParent, Element e) {
        if (e.hasChildNodes()) {
            NodeList children = e.getChildNodes();
            // immediate child element
            for (int i = 0; i < children.getLength(); i++) {
                Node child = children.item(i);
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    NodeList childElements = e.getElementsByTagName(child.getNodeName());
                    if (childElements.getLength() > 1) {
                        childParent.setCollectionType(CollectionType.LIST);
                    }
                    break;
                }
            }
        }
    }

    private void getXmlPath(Node node, StringBuffer sb) {
        int index;
        if (node.getParentNode() != null && node.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
            getXmlPath(node.getParentNode(), sb);
        }
        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
            Node owner = ((Attr) node).getOwnerElement();
            if (owner.getParentNode() != null && owner.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
                getXmlPath(owner.getParentNode(), sb);
            }
            index = getNodeIndex(owner);
            sb.append("/").append(owner.getNodeName());
            if (index > 0) {
                sb.append("[").append(index).append("]");
            }
            sb.append("/");
            if (node.getPrefix() != null) {
                sb.append(node.getPrefix()).append(":");
            }
            sb.append("@").append(node.getLocalName());
        } else {
            index = getNodeIndex(node);
            sb.append("/").append(node.getNodeName());
            if (index > 0) {
                sb.append("[").append(index).append("]");
            }
        }
    }

    private int getNodeIndex(Node node) {
        if (node.getParentNode().getNodeType() == Node.ELEMENT_NODE) {
            Element parent = (Element) node.getParentNode();
            // find my index
            NodeList siblings = parent.getElementsByTagName(node.getNodeName());
            if (siblings != null) {
                for (int i = 0; i < siblings.getLength(); i++) {
                    Node nextSibling = siblings.item(i);
                    if (nextSibling.isSameNode(node)) {
                        return i;
                    }
                }
            }
        }
        return 0;
    }

    private XmlComplexType getXmlComplexType(Node childNode) {
        XmlComplexType childComplexType = new XmlComplexType();
        childComplexType.setFieldType(FieldType.COMPLEX);
        childComplexType.setXmlFields(new XmlFields());
        childComplexType.setName(childNode.getNodeName());
        StringBuffer stringBuffer = new StringBuffer();
        getXmlPath(childNode, stringBuffer);
        childComplexType.setPath(stringBuffer.toString());
        return childComplexType;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy