Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.scope;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
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 org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import deepdiff.core.DiffPointProcessor;
import deepdiff.core.DiffScope;
import deepdiff.core.DiffUnit;
import deepdiff.core.DiffUnitProcessor;
/**
* An implementation of DiffScope that takes an XML file and expands it into
* DiffUnits for each node using DOM.
*/
public class XMLDiffScope implements DiffScope {
private static final Logger log = Logger.getLogger(XMLDiffScope.class);
private DocumentBuilderFactory dbf;
private InputStream is1;
private InputStream is2;
private String path;
/**
* Initializes a new XMLDiffScope object.
*
* @param path the scoped path to the XML file
* @param is1 the input stream for the XML file on the left
* @param is2 the input stream for the XML file on the right
*/
public XMLDiffScope(String path, InputStream is1, InputStream is2) {
this.path = path;
this.is1 = is1;
this.is2 = is2;
dbf = DocumentBuilderFactory.newInstance();
dbf.setCoalescing(true);
dbf.setExpandEntityReferences(false);
dbf.setNamespaceAware(true);
dbf.setValidating(false);
}
/**
* Scans the XML files for DiffUnits and processes them
*
* @param unitProcessor the unit processor to process the DiffUnits found in
* the scan
* @param pointProcessor the point processor to pass to the unit processor
* when processing units
*/
public void scan(DiffUnitProcessor unitProcessor,
DiffPointProcessor pointProcessor) {
log.debug("Starting to scan scope " + path);
try {
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId,
String systemId)
throws SAXException, IOException {
return new InputSource(
new ByteArrayInputStream(
new byte[0]));
}
});
Document d1 = db.parse(is1);
Document d2 = db.parse(is2);
scan(d1, d2, unitProcessor, pointProcessor);
} catch (ParserConfigurationException pce) {
log.error("Failure scanning scope " + path, pce);
} catch (SAXException saxe) {
log.error("Malformed XML file: " + path, saxe);
} catch (IOException ioe) {
log.error("Failure scanning scope " + path, ioe);
} finally {
if (is1 != null) {
try {
is1.close();
} catch (Exception ex) {
//Ignore exception on close
}
}
if (is2 != null) {
try {
is2.close();
} catch (Exception ex) {
//Ignore exception on close
}
}
}
log.debug("Completed scan of scope " + path);
}
/**
* Scans the XML Documents for DiffUnits and processes them
*
* @param d1 the Document on the left
* @param d2 the Document on the right
* @param unitProcessor the unit processor to process the DiffUnits found in
* the scan
* @param pointProcessor the point processor to pass to the unit processor
* when processing units
*/
private void scan(Document d1, Document d2, DiffUnitProcessor unitProcessor,
DiffPointProcessor pointProcessor) {
XMLDocumentDiffUnit diffUnit = new XMLDocumentDiffUnit(this, d1, d2);
String scopedPath = diffUnit.getScopedPath();
log.debug("Processing " + scopedPath);
unitProcessor.processDiffUnit(diffUnit, pointProcessor);
Element de1 = d1.getDocumentElement();
Element de2 = d2.getDocumentElement();
scan(diffUnit, 0, de1, de2, unitProcessor, pointProcessor);
}
/**
* Scans the Nodes for DiffUnits and processes them
*
* @param parentUnit the parent unit, used for assembling the scoped path
* @param index the index of the node among its siblings, used for
* assembling the scoped path
* @param n1 the Node on the left
* @param n2 the Node on the right
* @param unitProcessor the unit processor to process the DiffUnits found in
* the scan
* @param pointProcessor the point processor to pass to the unit processor
* when processing units
*/
private void scan(DiffUnit parentUnit, int index, Node n1, Node n2,
DiffUnitProcessor unitProcessor,
DiffPointProcessor pointProcessor) {
XMLNodeDiffUnit diffUnit =
new XMLNodeDiffUnit(parentUnit, index, n1, n2);
log.debug("Processing " + diffUnit.getScopedPath());
unitProcessor.processDiffUnit(diffUnit, pointProcessor);
scanAttributes(diffUnit, n1, n2, unitProcessor, pointProcessor);
NodeList children1 = n1.getChildNodes();
NodeList children2 = n2.getChildNodes();
int len1 = children1.getLength();
int len2 = children2.getLength();
// TODO: support comparison of nodes with mismatched child lengths
if (len1 != len2) {
log.error(diffUnit.getScopedPath() + ": Mismatch child length: "
+ len1 + ", " + len2
+ "; detailed processing not yet supported");
} else {
for (int i = 0; i < len1; i++) {
Node child1 = children1.item(i);
Node child2 = children2.item(i);
scan(diffUnit, i, child1, child2, unitProcessor,
pointProcessor);
}
}
}
/**
* Scans the attributes for the specified Nodes for DiffUnits and processes
* them
*
* @param elementUnit the DiffUnit for the element that contains the
* attributes
* @param n1 the Node on the left
* @param n2 the Node on the right
* @param unitProcessor the unit processor to process the DiffUnits found in
* the scan
* @param pointProcessor the point processor to pass to the unit processor
* when processing units
*/
private void scanAttributes(XMLNodeDiffUnit elementUnit, Node n1, Node n2,
DiffUnitProcessor unitProcessor,
DiffPointProcessor pointProcessor) {
NamedNodeMap a1 = n1.getAttributes();
NamedNodeMap a2 = n2.getAttributes();
if (a1 == null && a2 == null) {
// No attributes for this node
return;
}
SortedSet names = new TreeSet();
if (a1 != null) {
for (int i = 0; i < a1.getLength(); i++) {
names.add(a1.item(i).getNodeName());
}
}
if (a2 != null) {
for (int i = 0; i < a2.getLength(); i++) {
names.add(a2.item(i).getNodeName());
}
}
for (Iterator it = names.iterator(); it.hasNext();) {
String name = (String) it.next();
Node an1 = null;
Node an2 = null;
if (a1 != null) {
an1 = a1.getNamedItem(name);
}
if (a2 != null) {
an2 = a2.getNamedItem(name);
}
DiffUnit diffUnit =
new XMLAttributeDiffUnit(elementUnit, name, an1, an2);
log.debug("Processing " + diffUnit.getScopedPath());
unitProcessor.processDiffUnit(diffUnit, pointProcessor);
}
}
/**
* Returns the path of the scope
*
* @return the path of the scope
*/
public String getPath() {
return path;
}
}