AbstractXMLDiff.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.utils.xml;
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.io.Reader;
- import java.util.List;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import org.apache.commons.io.input.ReaderInputStream;
- import org.slf4j.Logger;
- import org.custommonkey.xmlunit.DetailedDiff;
- import org.custommonkey.xmlunit.Difference;
- import org.custommonkey.xmlunit.XMLUnit;
- import org.openspcoop2.utils.LoggerWrapperFactory;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.xml.sax.InputSource;
- /**
- * Classe utilizzabile per ricerche effettuate tramite espressioni XQuery
- *
- * @author Andrea Poli (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public abstract class AbstractXMLDiff {
-
- @SuppressWarnings("unused")
- private static Logger logger = LoggerWrapperFactory.getLogger(AbstractXMLDiff.class);
- public static void setLogger(Logger logger) {
- AbstractXMLDiff.logger = logger;
- }
-
- // Static options, la libreria XMLUnit permette di definire queste proprietà staticamente.
- private static XMLDiffOptions xmlDiffOptions = new XMLDiffOptions();
- private static XMLDiffImplType implType = XMLDiffImplType.XML_UNIT;
- private static DocumentBuilderFactory dbf_org_w3c_dom_document_impl = null;
- public static XMLDiffImplType getImplType() {
- return AbstractXMLDiff.implType;
- }
- public static void setImplType(XMLDiffImplType implType) {
- AbstractXMLDiff.implType = implType;
- }
- public static XMLDiffOptions getXmlDiffOptions() {
- return AbstractXMLDiff.xmlDiffOptions;
- }
- public static void setXmlDiffOptions(XMLDiffOptions xmlDiffOptions) {
- AbstractXMLDiff.xmlDiffOptions = xmlDiffOptions;
- }
- private static boolean initialized = false;
- private static synchronized void initialize(AbstractXMLUtils instance) throws XMLException{
- if(AbstractXMLDiff.initialized==false){
-
- AbstractXMLDiff.dbf_org_w3c_dom_document_impl = instance.newDocumentBuilderFactory();
- AbstractXMLDiff.dbf_org_w3c_dom_document_impl.setNamespaceAware(true);
- AbstractXMLDiff.dbf_org_w3c_dom_document_impl.setCoalescing(AbstractXMLDiff.xmlDiffOptions.isIgnoreDiffBetweenTextAndCDATA());
- AbstractXMLDiff.dbf_org_w3c_dom_document_impl.setIgnoringElementContentWhitespace(AbstractXMLDiff.xmlDiffOptions.isIgnoreWhitespace());
- AbstractXMLDiff.dbf_org_w3c_dom_document_impl.setIgnoringComments(AbstractXMLDiff.xmlDiffOptions.isIgnoreComments());
-
- if(XMLDiffImplType.XML_UNIT.equals(AbstractXMLDiff.implType)){
- XMLUnit.setIgnoreAttributeOrder(true);
- XMLUnit.setExpandEntityReferences(true);
- XMLUnit.setIgnoreComments(AbstractXMLDiff.xmlDiffOptions.isIgnoreComments());
- XMLUnit.setIgnoreDiffBetweenTextAndCDATA(AbstractXMLDiff.xmlDiffOptions.isIgnoreDiffBetweenTextAndCDATA());
- XMLUnit.setIgnoreWhitespace(AbstractXMLDiff.xmlDiffOptions.isIgnoreWhitespace());
- XMLUnit.setNormalize(AbstractXMLDiff.xmlDiffOptions.isNormalize());
- XMLUnit.setNormalizeWhitespace(AbstractXMLDiff.xmlDiffOptions.isNormalize());
- }
-
- AbstractXMLDiff.initialized = true;
- }
- }
- private static synchronized void _initialize(XMLDiffImplType implType,XMLDiffOptions xmlDiffOptions,AbstractXMLUtils instance) throws XMLException{
- AbstractXMLDiff.implType = implType;
- AbstractXMLDiff.xmlDiffOptions = xmlDiffOptions;
- AbstractXMLDiff.initialize(instance);
- }
-
- /* ***** INIT METHOD (ha bisogno degli abstract method) ***** */
-
- public void initialize(XMLDiffImplType implType,XMLDiffOptions xmlDiffOptions) throws XMLException{
- AbstractXMLDiff._initialize(implType,xmlDiffOptions,this.getXMLUtils());
- }
-
-
- /* ***** ABSTRACT METHOD ***** */
-
- public abstract AbstractXMLUtils getXMLUtils();
- public abstract Element readXPathElement(Element contenutoAsElement);
- public abstract void normalizeDocument(Document document);
-
- /* ***** EXCEPTION METHOD ***** */
- private String difference;
-
- public String getDifferenceDetails() throws XMLException {
- if(!XMLDiffImplType.XML_UNIT.equals(AbstractXMLDiff.implType)){
- throw new XMLException("Difference details permit only on implementation: "+XMLDiffImplType.XML_UNIT);
- }
- return this.difference;
- }
-
-
-
-
-
- /* ***** ENGINE ***** */
-
- private boolean _diff(Object original, Object compare) throws XMLException{
-
- if(AbstractXMLDiff.initialized==false){
- throw new XMLException("Library not initialized. Invoke initialize method");
- }
-
- if(XMLDiffImplType.XML_UNIT.equals(AbstractXMLDiff.implType)){
- return this._diffXmlUnit(original, compare);
- }
- else if(XMLDiffImplType.ORG_W3C_DOM_DOCUMENT.equals(AbstractXMLDiff.implType)){
- return this._diffW3cDomDocument(original, compare);
- }
- else{
- throw new XMLException("Implementation ["+AbstractXMLDiff.implType+"] not supported");
- }
- }
-
- private boolean _diffXmlUnit(Object original, Object compare) throws XMLException{
-
- DetailedDiff diff = null;
-
- if( (original instanceof Document) || (original instanceof Element) || (original instanceof Node) ){
- // Ottengo anche il compare come Document e li confronto
- Document docOriginal = this._getDiffW3cDomDocument(original, "original");
- Document docCompare = this._getDiffW3cDomDocument(compare, "compare");
- if(AbstractXMLDiff.xmlDiffOptions.isNormalize()){
- normalizeDocument(docOriginal);
- normalizeDocument(docCompare);
- }
- diff = new DetailedDiff(XMLUnit.compareXML(docOriginal,docCompare));
- }
- else if( (original instanceof Reader) && (compare instanceof Reader) ){
- Reader rOriginal = (Reader) original;
- Reader rCompare = (Reader) compare;
- try{
- diff = new DetailedDiff(XMLUnit.compareXML(rOriginal,rCompare));
- }catch(Exception e){
- throw new XMLException(e.getMessage(),e);
- }
- }
- else if( (original instanceof Reader) && (compare instanceof String) ){
- Reader rOriginal = (Reader) original;
- String sCompare = (String) compare;
- try{
- diff = new DetailedDiff(XMLUnit.compareXML(rOriginal,sCompare));
- }catch(Exception e){
- throw new XMLException(e.getMessage(),e);
- }
- }
- else if( (original instanceof String) && (compare instanceof Reader) ){
- String sOriginal = (String) original;
- Reader rCompare = (Reader) compare;
- try{
- diff = new DetailedDiff(XMLUnit.compareXML(sOriginal,rCompare));
- }catch(Exception e){
- throw new XMLException(e.getMessage(),e);
- }
- }
- else if( (original instanceof String) && (compare instanceof String) ){
- String sOriginal = (String) original;
- String sCompare = (String) compare;
- try{
- diff = new DetailedDiff(XMLUnit.compareXML(sOriginal,sCompare));
- }catch(Exception e){
- throw new XMLException(e.getMessage(),e);
- }
- }
- else if(
- ( (original instanceof InputStream) || (original instanceof File) )
- &&
- ( (compare instanceof InputStream) || (compare instanceof File) )
- ){
- InputSource isOriginal = null;
- InputSource isCompare = null;
- FileInputStream finOriginal = null;
- FileInputStream finCompare = null;
- try{
-
- if(original instanceof InputStream){
- isOriginal = new InputSource((InputStream)original);
- }
- else if(original instanceof File){
- finOriginal = new FileInputStream((File)original);
- isOriginal = new InputSource(finOriginal);
- }
-
- if(compare instanceof InputStream){
- isCompare = new InputSource((InputStream)compare);
- }
- else if(compare instanceof File){
- finCompare = new FileInputStream((File)compare);
- isCompare = new InputSource(finCompare);
- }
-
- diff = new DetailedDiff(XMLUnit.compareXML(isOriginal,isCompare));
-
- }catch(Exception e){
- throw new XMLException(e.getMessage(),e);
- }finally{
- try{
- if(finOriginal!=null){
- finOriginal.close();
- }
- }catch(Exception eClose){}
- try{
- if(finCompare!=null){
- finCompare.close();
- }
- }catch(Exception eClose){
- // close
- }
- }
- }
- else{
- // Ottengo anche il compare come Document e li confronto
- Document docOriginal = this._getDiffW3cDomDocument(original, "original");
- Document docCompare = this._getDiffW3cDomDocument(compare, "compare");
- if(AbstractXMLDiff.xmlDiffOptions.isNormalize()){
- normalizeDocument(docOriginal);
- normalizeDocument(docCompare);
- }
- diff = new DetailedDiff(XMLUnit.compareXML(docOriginal,docCompare));
- }
-
-
- if(diff!=null && diff.identical()==false){
- StringBuilder bfDifferences = new StringBuilder();
- List<?> allDifferences = diff.getAllDifferences();
- bfDifferences.append("allDifferences: "+ allDifferences.size());
- bfDifferences.append("\n");
- int index = 1;
- for (Object object : allDifferences) {
- if(object instanceof Difference){
- Difference d = (Difference) object;
- bfDifferences.append("Diff-"+index+": "+d.toString());
- bfDifferences.append("\n");
- }
- index++;
- }
- this.difference = bfDifferences.toString();
- }
- return diff!=null ? diff.identical() : false;
-
- }
-
- private boolean _diffW3cDomDocument(Object original, Object compare) throws XMLException{
-
- Document docOriginal = this._getDiffW3cDomDocument(original, "original");
- Document docCompare = this._getDiffW3cDomDocument(compare, "compare");
- if(AbstractXMLDiff.xmlDiffOptions.isNormalize()){
- normalizeDocument(docOriginal);
- normalizeDocument(docCompare);
- }
- return docOriginal.isEqualNode(docCompare);
- }
-
- private Document _getDiffW3cDomDocument(Object o,String parameterName) throws XMLException{
-
- if(o==null){
- throw new XMLException("Object is null for parameter ["+parameterName+"]");
- }
-
- if(o instanceof Document){
- return (Document) o;
- }
- else if(o instanceof Element){
- return ((Element) o).getOwnerDocument();
- }
- else if(o instanceof Node){
- return ((Node) o).getOwnerDocument();
- }
- else if(
- (o instanceof String) ||
- (o instanceof File) ||
- (o instanceof InputStream) ||
- (o instanceof Reader)
- ){
- ReaderInputStream ris = null;
- try{
- DocumentBuilder db = AbstractXMLDiff.dbf_org_w3c_dom_document_impl.newDocumentBuilder();
- if(o instanceof String){
- byte [] b = ((String)o).getBytes();
- return db.parse(new ByteArrayInputStream(b));
- }
- else if(o instanceof File){
- return db.parse((File)o);
- }
- else if(o instanceof InputStream){
- return db.parse((InputStream)o);
- }
- else if(o instanceof Reader){
- Reader r = (Reader) o;
- ris = ReaderInputStream.builder()
- .setReader(r)
- .setCharset(org.openspcoop2.utils.resources.Charset.UTF_8.getValue())
- .get();
- return db.parse( ris );
- }
- else{
- throw new XMLException("Object type ["+o.getClass().getName()+"] not supported ?? for parameter ["+parameterName+"]");
- }
- }catch(Exception e){
- throw new XMLException("Object type ["+o.getClass().getName()+"] parser error for parameter ["+parameterName+"]: "+e.getMessage(),e);
- }finally{
- try{
- if(ris!=null){
- ris.close();
- }
- }catch(Exception eClose){
- // close
- }
- }
- }
- else{
- throw new XMLException("Object type ["+o.getClass().getName()+"] not supported for parameter ["+parameterName+"]");
- }
- }
-
-
- /* ***** PUBLIC METHOD (SRC as Node) ***** */
-
- public boolean diff(String original, String compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(File original, File compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(InputStream original, InputStream compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(Reader original, Reader compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(Document original, Document compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(Element original, Element compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(Node original, Node compare)throws XMLException{
- return this._diff(original, compare);
- }
- public boolean diff(Object original, Object compare)throws XMLException{
- return this._diff(original, compare);
- }
- }