/*******************************************************************************
* Copyright (c) 2010-2014 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.skalli.core.persistence;
import java.util.Arrays;
import org.custommonkey.xmlunit.ComparisonController;
import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.DifferenceConstants;
import org.custommonkey.xmlunit.DifferenceEngine;
import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.ElementNameQualifier;
import org.eclipse.skalli.commons.CollectionUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XMLDiff implements ComparisonController, DifferenceListener {
private static final int[] IGNORED_DIFFERENCES = CollectionUtils.asSortedArray(new int[] {
// ignore all namespace, doctype etc stuff
DifferenceConstants.HAS_DOCTYPE_DECLARATION_ID,
DifferenceConstants.DOCTYPE_NAME_ID,
DifferenceConstants.DOCTYPE_PUBLIC_ID_ID,
DifferenceConstants.DOCTYPE_SYSTEM_ID_ID,
DifferenceConstants.NODE_TYPE_ID,
DifferenceConstants.NAMESPACE_PREFIX_ID,
DifferenceConstants.NAMESPACE_URI_ID,
DifferenceConstants.SCHEMA_LOCATION_ID,
DifferenceConstants.NO_NAMESPACE_SCHEMA_LOCATION_ID,
// ignore ordering of tags
DifferenceConstants.CHILD_NODELIST_SEQUENCE_ID,
// ignore all attribute related differences
DifferenceConstants.ATTR_VALUE_ID,
DifferenceConstants.ATTR_NAME_NOT_FOUND_ID,
DifferenceConstants.ATTR_SEQUENCE_ID,
DifferenceConstants.ATTR_VALUE_EXPLICITLY_SPECIFIED_ID,
DifferenceConstants.ELEMENT_NUM_ATTRIBUTES_ID,
// ignpre comments, CDATA sections etc.
DifferenceConstants.COMMENT_VALUE_ID,
DifferenceConstants.PROCESSING_INSTRUCTION_TARGET_ID,
DifferenceConstants.PROCESSING_INSTRUCTION_DATA_ID,
DifferenceConstants.CDATA_VALUE_ID });
private boolean identical = true;
@Override
public int differenceFound(Difference difference) {
int result = RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
if (Arrays.binarySearch(IGNORED_DIFFERENCES, difference.getId()) < 0) {
identical = false;
result = RETURN_ACCEPT_DIFFERENCE;
}
return result;
}
@Override
public void skippedComparison(Node node, Node node1) {
}
@Override
public boolean haltComparison(Difference difference) {
return !identical;
}
public boolean identical() {
return identical;
}
public static boolean identical(Element newElement, Element oldElement) {
if (newElement != null && oldElement == null || newElement == null && oldElement != null) {
return false;
}
XMLDiff diff = new XMLDiff();
DifferenceEngine engine = new DifferenceEngine(diff);
engine.compare(newElement, oldElement, diff, new ElementNameQualifier());
return diff.identical();
}
}