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

org.cyclades.xml.comparitor.XMLComparitor Maven / Gradle / Ivy

There is a newer version: 1.0.0.31
Show newest version
/*******************************************************************************
 * Copyright (c) 2012, THE BOARD OF TRUSTEES OF THE LELAND STANFORD JUNIOR UNIVERSITY
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *    Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *    Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *    Neither the name of the STANFORD UNIVERSITY nor the names of its contributors
 *    may be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/
package org.cyclades.xml.comparitor;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.io.StringWriter;
import org.cyclades.xml.parser.XMLParserException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import java.io.File;
import java.util.Vector;

/**
 * This class will compare two XML Strings to see if they are similar.
 * We need to include special logic, so it is not as straight forward as
 * simply comparing the dom for matching elements. You create this class
 * using the "template" XML you want to compare other XML documents with.
 * As long as the "compared" XML contains an exact subset of the "template" XML
 * then it is a considered match. We need to take into consideration the
 * logic of specifying a node that is not to exist in the compared node.
 * For our purposes we will have a reserved attribute that will flag a
 * leaf node as one we will not want to see in the compared node.
 *
 * RULES FOR ADDING AN OMIT ENTRY:
 *  The "omit" attribute needs to be defined on it's own...meaning one leaf defined
 *  all the way from the root. Here is an example of what it would look like:
 *  
 *      
     * @throws XMLParserException
     */
    public static Vector getMatchingChildNodes (Node node, String name) throws XMLParserException {
        final String eLabel = "XMLComparitor.getMatchingChildNodes: ";
        Vector nodeVector = new Vector();
        try {
            NodeList nl = node.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                if (nl.item(i).getNodeName().equals(name)) {
                    nodeVector.add(nl.item(i));
                }
            }
        } catch (Exception e) {
            throw new XMLParserException(eLabel + e);
        }
        return nodeVector;
    }

    /**
     * Return the highest node of a list, based on its long value
     *
     * @param list              The list to search
     * @param attributeName     The attribute to parse as a long
     * @return Node
     * @throws Exception
     */
    public static Node getLargestChildNodeLong (NodeList list, String attributeName) throws Exception {
        final String eLabel = "XMLComparitor.getLargestChildNodeLong: ";
        try {
            Node highestNode = null;
            for (int i = 0; i < list.getLength(); i++) {
                if (highestNode == null || Long.parseLong(getAttribute(list.item(i), attributeName)) >
                    Long.parseLong(getAttribute(highestNode, attributeName))) {
                    highestNode = list.item(i);
                }
            }
            return highestNode;
        } catch (Exception e) {
            throw new Exception(eLabel + e);
        }
    }

    /**
     * Return the highest node of a list, based on its float value
     *
     * @param list              The list to search
     * @param attributeName     The attribute to parse as a float
     * @return Node
     * @throws Exception
     */
    public static Node getLargestChildNodeFloat (NodeList list, String attributeName) throws Exception {
        final String eLabel = "XMLComparitor.getLargestChildNodeFloat: ";
        try {
            Node highestNode = null;
            for (int i = 0; i < list.getLength(); i++) {
                if (highestNode == null || Float.parseFloat(getAttribute(list.item(i), attributeName)) >
                    Float.parseFloat(getAttribute(highestNode, attributeName))) {
                    highestNode = list.item(i);
                }
            }
            return highestNode;
        } catch (Exception e) {
            throw new Exception(eLabel + e);
        }
    }

    /**
     * Get matching child node, allow a create if none exist...
     *
     * @param doc               The document object to traverse
     * @param parentNode        The parent node of the document
     * @param tagValue          The value to search for
     * @param create            If true, create a node if not found
     * @param attributeName     The name of the attribute to use for a value
     * @return Node
     * @throws Exception
     */
    public static Node getChildNode (Document doc, Node parentNode, String tagValue, boolean create, String attributeName) throws Exception {
        final String eLabel = "XMLComparitor.getChildNode: ";
        try {
            Node child = null;
            NodeList list = parentNode.getChildNodes();
            for (int i = 0; i < list.getLength(); i++) {
                if (tagValue.equals(XMLComparitor.getAttribute(list.item(i), attributeName))) {
                    return list.item(i);
                }
            }
            if (create) {
                child = addNewChildNode(doc, parentNode, tagValue, attributeName);
            }
            return child;
        } catch (Exception e) {
            throw new Exception (eLabel + e);
        }
    }

    /**
     * Add a new child node with the given attribute value for the "tag" attribute
     *
     * @param doc               The document object to traverse
     * @param parentNode        The parent node of the document
     * @param tagValue          The value to search for
     * @param attributeName     The name of the attribute to use for a value
     * @return Node
     * @throws Exception
     */
    public static Node addNewChildNode (Document doc, Node parentNode, String tagValue, String attributeName) throws Exception {
        final String eLabel = "XMLComparitor.addNewChildNode: ";
        try {
            Node newChildNode = doc.createElement("node");
            NamedNodeMap childAtts = newChildNode.getAttributes();
            Attr tag = doc.createAttribute(attributeName);
            tag.setValue(tagValue);
            childAtts.setNamedItem(tag);
            parentNode.appendChild(newChildNode);
            return newChildNode;
        } catch (Exception e) {
            throw new Exception (eLabel + e);
        }
    }

    /**
     * Main to run as example for implementation. Typically, no files will be
     * accessed. We will use only Strings, but can use files. Also, make sure the
     * files and the strings have no new lines or white space around tags. This
     * breaks the logic of this class because of parser inconsistencies.
     *
     * @param args
     */
    public static void main (String[] args) {
        try {
            if (args.length != 2) {
                System.out.println("useage: cmd comparator compared");
                return;
            }

            File file1 = new File(args[0]);
            File file2 = new File(args[1]);

            XMLComparitor xmlc = new XMLComparitor(parseXML(file1));
            if (xmlc.isMatch(parseXML(file2))) {
                System.out.println("MATCH");
            } else {
                System.out.println("NON_MATCH");
            }
        } catch (Exception e) {
            System.out.println("" + e);
        }
    }
    
    /**
     * Return a String represenation of the Node passed in
     * 
     * @param node The Node object to convert to a String
     * @return String represenation of the Node passed in
     * @throws TransformerFactoryConfigurationError
     * @throws TransformerException
     */
    public static String nodeToString (Node node, boolean XMLDeclaration, boolean indent) 
            throws TransformerFactoryConfigurationError, TransformerException {
        StringWriter sw = new StringWriter();
        Transformer t = TransformerFactory.newInstance().newTransformer();
        t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, (XMLDeclaration) ? "no" : "yes");
        t.setOutputProperty(OutputKeys.INDENT, (indent) ? "yes" : "no");
        t.transform(new DOMSource(node), new StreamResult(sw));
        return sw.toString();
    }

    public Element getDomRootElement () {
        return templateRootElement;
    }

    private Element templateRootElement;
    private boolean mOmit;
    private final static String OMIT_FLAG = "omit";

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy