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

deepdiff.unitprocessor.XMLCompareDiffUnitProcessor Maven / Gradle / Ivy

There is a newer version: 1.0.2
Show newest version
/*
 * Copyright 2011 DeepDiff Contributors
 *
 * 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 deepdiff.unitprocessor;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import deepdiff.core.DiffPoint;
import deepdiff.core.DiffPointProcessor;
import deepdiff.core.DiffScope;
import deepdiff.core.DiffUnit;
import deepdiff.core.ScopedDiffUnitProcessor;
import deepdiff.scope.XMLAttributeDiffUnit;
import deepdiff.scope.XMLDiffScope;
import deepdiff.scope.XMLDocumentDiffUnit;
import deepdiff.scope.XMLNodeDiffUnit;

/**
 * A DiffUnitProcessor that performs deep comparisons on XML document DiffUnit.
 */
public class XMLCompareDiffUnitProcessor implements ScopedDiffUnitProcessor {
    private static final Logger log = Logger.getLogger(XMLCompareDiffUnitProcessor.class);

    /**
     * Performs a deep XML comparison on diffUnit. If 
     * diffUnit represents part of a DOM, compares the unit and passes any {@link DiffPoint}s
     * found to processor. Otherwise, returns a new {@link DiffScope} to process the
     * XML document.
     * 
     * @param diffUnit the unit to process
     * @param processor the processor to pass differences to
     * 
     * @return either a {@link DiffScope} to process an XML document or null (if the unit was
     *         already part of an XML document)
     */
    public DiffScope processDiffUnit(DiffUnit diffUnit, DiffPointProcessor processor) {
        DiffScope scope = null;
        if (diffUnit instanceof XMLDocumentDiffUnit) {
            XMLDocumentDiffUnit du = (XMLDocumentDiffUnit) diffUnit;
            DocumentType dt1 = du.getLeftDoctype();
            DocumentType dt2 = du.getRightDoctype();
            process(diffUnit, dt1, dt2, processor);
        } else if (diffUnit instanceof XMLNodeDiffUnit) {
            XMLNodeDiffUnit du = (XMLNodeDiffUnit) diffUnit;
            Node n1 = du.getLeftNode();
            Node n2 = du.getRightNode();
            if (n1 != null && n2 != null) {
                String v1 = n1.getNodeValue();
                String v2 = n2.getNodeValue();
                if (v1 != null && v2 != null) {
                    if (!v1.equals(v2)) {
                        DiffPoint diffPoint = new DiffPoint(diffUnit, "Node value mismatch: " + v1
                                + ", " + v2);
                        processor.processDiffPoint(diffPoint);
                    }
                } else if (v1 == null && v2 != null) {
                    DiffPoint diffPoint = new DiffPoint(diffUnit,
                            "Node value present in right only");
                    processor.processDiffPoint(diffPoint);
                } else if (v1 != null && v2 == null) {
                    DiffPoint diffPoint = new DiffPoint(diffUnit, "Node value present in left only");
                    processor.processDiffPoint(diffPoint);
                }
            } else if (n1 == null && n2 != null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "Node present in right only");
                processor.processDiffPoint(diffPoint);
            } else if (n1 != null && n2 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "Node present in left only");
                processor.processDiffPoint(diffPoint);
            }
        } else if (diffUnit instanceof XMLAttributeDiffUnit) {
            XMLAttributeDiffUnit du = (XMLAttributeDiffUnit) diffUnit;
            String name = du.getAttributeName();
            if (!du.leftExists()) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "Attribute present in right only: "
                        + name);
                processor.processDiffPoint(diffPoint);
            } else if (!du.rightExists()) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "Attribute present in left only: "
                        + name);
                processor.processDiffPoint(diffPoint);
            } else {
                Node n1 = du.getLeftAttributeNode();
                Node n2 = du.getRightAttributeNode();
                String v1 = n1.getNodeValue();
                String v2 = n2.getNodeValue();
                if (!v1.equals(v2)) {
                    DiffPoint diffPoint = new DiffPoint(diffUnit, "Attribute value mismatch for "
                            + name + ":" + v1 + ", " + v2);
                    processor.processDiffPoint(diffPoint);
                }
            }
        } else {
            try {
                InputStream is1 = diffUnit.getLeftInputStream();
                InputStream is2 = diffUnit.getRightInputStream();
                String scopedPath = diffUnit.getScopedPath();
                scope = createScope(scopedPath, is1, is2);
            } catch (IOException ioe) {
                log.error("Failure processing " + diffUnit, ioe);
            }
        }
        return scope;
    }

    /**
     * Compares two document types
     * 
     * @param diffUnit the unit that the document types belong to
     * @param dt1 the document type on the left
     * @param dt2 the document type on the right
     * @param processor the processor to pass differences to
     */
    private void process(DiffUnit diffUnit, DocumentType dt1, DocumentType dt2,
            DiffPointProcessor processor) {
        if (dt1 == null && dt2 == null) {
            return;
        }
        if (dt1 == null) {
            DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType in right only");
            processor.processDiffPoint(diffPoint);
        } else if (dt2 == null) {
            DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType in left only");
            processor.processDiffPoint(diffPoint);
        } else {
            String name1 = dt1.getName();
            String name2 = dt2.getName();
            if (!name1.equals(name2)) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType name mismatch: " + name1
                        + ", " + name2);
                processor.processDiffPoint(diffPoint);
            }
            String pid1 = dt1.getPublicId();
            String pid2 = dt2.getPublicId();
            if (pid1 != null && pid2 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType public ID in left only");
                processor.processDiffPoint(diffPoint);
            } else if (pid1 == null && pid2 != null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType public ID in right only");
                processor.processDiffPoint(diffPoint);
            } else if (pid1 != null && pid2 != null && !pid1.equals(pid2)) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType public ID mismatch: " + pid1
                        + ", " + pid2);
                processor.processDiffPoint(diffPoint);
            }
            String sid1 = dt1.getSystemId();
            String sid2 = dt2.getSystemId();
            if (sid1 != null && sid2 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType system ID in left only");
                processor.processDiffPoint(diffPoint);
            } else if (sid1 == null && sid2 != null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType system ID in right only");
                processor.processDiffPoint(diffPoint);
            } else if (sid1 != null && sid2 != null && !sid1.equals(sid2)) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType system ID mismatch: " + sid1
                        + ", " + sid2);
                processor.processDiffPoint(diffPoint);
            }
            String subset1 = dt1.getInternalSubset();
            String subset2 = dt2.getInternalSubset();
            if (subset1 != null && subset2 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit,
                        "DocType internal subset in left only");
                processor.processDiffPoint(diffPoint);
            } else if (subset1 == null && subset2 != null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit,
                        "DocType internal subset in right only");
                processor.processDiffPoint(diffPoint);
            } else if (subset1 != null && subset2 != null && !subset1.equals(subset2)) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType internal subset mismatch: "
                        + subset1 + ", " + subset2);
                processor.processDiffPoint(diffPoint);
            }
            NamedNodeMap ent1 = dt1.getEntities();
            NamedNodeMap ent2 = dt2.getEntities();
            process(diffUnit, "entity", ent1, ent2, processor);
            NamedNodeMap notations1 = dt1.getNotations();
            NamedNodeMap notations2 = dt2.getNotations();
            process(diffUnit, "notation", notations1, notations2, processor);
        }
    }

    /**
     * Compares two {@link NamesNodeMap}s.
     * 
     * @param diffUnit the unit that the maps belong to
     * @param type a description of the type of map
     * @param nnm1 the map on the left
     * @param nnm2 the map on the right
     * @param processor the processor to pass differences to
     */
    private void process(DiffUnit diffUnit, String type, NamedNodeMap nnm1, NamedNodeMap nnm2,
            DiffPointProcessor processor) {
        if (nnm1 == null && nnm2 == null) {
            // Nothing to process
            return;
        }
        SortedSet names = new TreeSet();
        if (nnm1 != null) {
            for (int i = 0; i < nnm1.getLength(); i++) {
                names.add(nnm1.item(i).getNodeName());
            }
        }
        if (nnm2 != null) {
            for (int i = 0; i < nnm2.getLength(); i++) {
                names.add(nnm2.item(i).getNodeName());
            }
        }
        for (Iterator it = names.iterator(); it.hasNext();) {
            String name = it.next();
            Node n1 = null;
            Node n2 = null;
            if (nnm1 != null) {
                n1 = nnm1.getNamedItem(name);
            }
            if (nnm2 != null) {
                n2 = nnm2.getNamedItem(name);
            }
            if (n1 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType " + type
                        + " in right only: " + name);
                processor.processDiffPoint(diffPoint);
            } else if (n2 == null) {
                DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType " + type + " in left only: "
                        + name);
                processor.processDiffPoint(diffPoint);
            } else {
                String v1 = n1.getNodeValue();
                String v2 = n2.getNodeValue();
                if (!v1.equals(v2)) {
                    DiffPoint diffPoint = new DiffPoint(diffUnit, "DocType " + type
                            + " mismatch for " + name + ": " + v1 + ", " + v2);
                    processor.processDiffPoint(diffPoint);
                }
            }
        }
    }

    @Override
    public DiffScope createScope(String path, InputStream is1, InputStream is2) {
        return new XMLDiffScope(path, is1, is2);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy