新疆交投路损赔补偿系统 v1.0.2版本的 MD5 值为:5e336668c8c96e65d739f00d1fa2a3b9

以下内容为反编译后的 CompareTool.java 源代码,内容仅作参考


package com.itextpdf.testutils;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Meta;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PRIndirectReference;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfBoolean;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfIndirectReference;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.RefKey;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfContentStreamProcessor;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TaggedPdfReaderTool;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
import com.itextpdf.text.xml.XMLUtil;
import com.itextpdf.text.xml.xmp.PdfProperties;
import com.itextpdf.text.xml.xmp.XmpBasicProperties;
import com.itextpdf.xmp.XMPException;
import com.itextpdf.xmp.XMPMeta;
import com.itextpdf.xmp.XMPMetaFactory;
import com.itextpdf.xmp.XMPUtils;
import com.itextpdf.xmp.options.SerializeOptions;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class CompareTool {
    private static final String cannotOpenTargetDirectory = "Cannot open target directory for <filename>.";
    private static final String differentPages = "File <filename> differs on page <pagenumber>.";
    private static final String gsFailed = "GhostScript failed for <filename>.";
    private static final String ignoredAreasPrefix = "ignored_areas_";
    private static final String undefinedGsPath = "Path to GhostScript is not specified. Please use -DgsExec=<path_to_ghostscript> (e.g. -DgsExec=\"C:/Program Files/gs/gs9.14/bin/gswin32c.exe\")";
    private static final String unexpectedNumberOfPages = "Unexpected number of pages for <filename>.";
    private String cmpImage;
    List<PdfDictionary> cmpPages;
    List<RefKey> cmpPagesRef;
    private String cmpPdf;
    private String cmpPdfName;
    private String compareExec;
    private String gsExec;
    private String outImage;
    List<PdfDictionary> outPages;
    List<RefKey> outPagesRef;
    private String outPdf;
    private String outPdfName;
    private final String gsParams = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>";
    private final String compareParams = " <image1> <image2> <difference>";

    public CompareTool(String outPdf, String cmpPdf) {
        init(outPdf, cmpPdf);
        this.gsExec = System.getProperty("gsExec");
        this.compareExec = System.getProperty("compareExec");
    }

    public String compare(String outPath, String differenceImagePrefix) throws IOException, InterruptedException, DocumentException {
        return compare(outPath, differenceImagePrefix, null);
    }

    public String compare(String outPath, String differenceImagePrefix, Map<Integer, List<Rectangle>> ignoredAreas) throws IOException, InterruptedException, DocumentException {
        return compare(outPath, differenceImagePrefix, ignoredAreas, (List<Integer>) null);
    }

    protected String compare(String outPath, String differenceImagePrefix, Map<Integer, List<Rectangle>> ignoredAreas, List<Integer> equalPages) throws IOException, InterruptedException, DocumentException {
        File[] imageFiles;
        File[] cmpImageFiles;
        if (this.gsExec == null) {
            return undefinedGsPath;
        }
        if (!new File(this.gsExec).exists()) {
            return new File(this.gsExec).getAbsolutePath() + " does not exist";
        }
        if (!outPath.endsWith("/")) {
            outPath = outPath + "/";
        }
        File targetDir = new File(outPath);
        if (!targetDir.exists()) {
            targetDir.mkdir();
        } else {
            for (File file : targetDir.listFiles(new PngFileFilter())) {
                file.delete();
            }
            for (File file2 : targetDir.listFiles(new CmpPngFileFilter())) {
                file2.delete();
            }
        }
        File diffFile = new File(outPath + differenceImagePrefix);
        if (diffFile.exists()) {
            diffFile.delete();
        }
        if (ignoredAreas != null && !ignoredAreas.isEmpty()) {
            PdfReader cmpReader = new PdfReader(this.cmpPdf);
            PdfReader outReader = new PdfReader(this.outPdf);
            PdfStamper outStamper = new PdfStamper(outReader, new FileOutputStream(outPath + ignoredAreasPrefix + this.outPdfName));
            PdfStamper cmpStamper = new PdfStamper(cmpReader, new FileOutputStream(outPath + ignoredAreasPrefix + this.cmpPdfName));
            for (Map.Entry<Integer, List<Rectangle>> entry : ignoredAreas.entrySet()) {
                int pageNumber = entry.getKey().intValue();
                List<Rectangle> rectangles = entry.getValue();
                if (rectangles != null && !rectangles.isEmpty()) {
                    PdfContentByte outCB = outStamper.getOverContent(pageNumber);
                    PdfContentByte cmpCB = cmpStamper.getOverContent(pageNumber);
                    for (Rectangle rect : rectangles) {
                        rect.setBackgroundColor(BaseColor.BLACK);
                        outCB.rectangle(rect);
                        cmpCB.rectangle(rect);
                    }
                }
            }
            outStamper.close();
            cmpStamper.close();
            outReader.close();
            cmpReader.close();
            init(outPath + ignoredAreasPrefix + this.outPdfName, outPath + ignoredAreasPrefix + this.cmpPdfName);
        }
        if (targetDir.exists()) {
            getClass();
            String gsParams = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>".replace("<outputfile>", outPath + this.cmpImage).replace("<inputfile>", this.cmpPdf);
            Process p = Runtime.getRuntime().exec(this.gsExec + gsParams);
            BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
            BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            while (true) {
                String line = bri.readLine();
                if (line == null) {
                    break;
                }
                System.out.println(line);
            }
            bri.close();
            while (true) {
                String line2 = bre.readLine();
                if (line2 == null) {
                    break;
                }
                System.out.println(line2);
            }
            bre.close();
            if (p.waitFor() == 0) {
                getClass();
                String gsParams2 = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>".replace("<outputfile>", outPath + this.outImage).replace("<inputfile>", this.outPdf);
                Process p2 = Runtime.getRuntime().exec(this.gsExec + gsParams2);
                BufferedReader bri2 = new BufferedReader(new InputStreamReader(p2.getInputStream()));
                BufferedReader bre2 = new BufferedReader(new InputStreamReader(p2.getErrorStream()));
                while (true) {
                    String line3 = bri2.readLine();
                    if (line3 == null) {
                        break;
                    }
                    System.out.println(line3);
                }
                bri2.close();
                while (true) {
                    String line4 = bre2.readLine();
                    if (line4 == null) {
                        break;
                    }
                    System.out.println(line4);
                }
                bre2.close();
                int exitValue = p2.waitFor();
                if (exitValue == 0) {
                    File[] imageFiles2 = targetDir.listFiles(new PngFileFilter());
                    File[] cmpImageFiles2 = targetDir.listFiles(new CmpPngFileFilter());
                    boolean bUnexpectedNumberOfPages = false;
                    if (imageFiles2.length != cmpImageFiles2.length) {
                        bUnexpectedNumberOfPages = true;
                    }
                    int cnt = Math.min(imageFiles2.length, cmpImageFiles2.length);
                    if (cnt < 1) {
                        return "No files for comparing!!!\nThe result or sample pdf file is not processed by GhostScript.";
                    }
                    Arrays.sort(imageFiles2, new ImageNameComparator());
                    Arrays.sort(cmpImageFiles2, new ImageNameComparator());
                    String differentPagesFail = null;
                    for (int i = 0; i < cnt; i++) {
                        if (equalPages == null || !equalPages.contains(Integer.valueOf(i))) {
                            System.out.print("Comparing page " + Integer.toString(i + 1) + " (" + imageFiles2[i].getAbsolutePath() + ")...");
                            FileInputStream is1 = new FileInputStream(imageFiles2[i]);
                            FileInputStream is2 = new FileInputStream(cmpImageFiles2[i]);
                            boolean cmpResult = compareStreams(is1, is2);
                            is1.close();
                            is2.close();
                            if (!cmpResult) {
                                if (this.compareExec != null && new File(this.compareExec).exists()) {
                                    getClass();
                                    String compareParams = " <image1> <image2> <difference>".replace("<image1>", imageFiles2[i].getAbsolutePath()).replace("<image2>", cmpImageFiles2[i].getAbsolutePath()).replace("<difference>", outPath + differenceImagePrefix + Integer.toString(i + 1) + ".png");
                                    Process p3 = Runtime.getRuntime().exec(this.compareExec + compareParams);
                                    BufferedReader bre3 = new BufferedReader(new InputStreamReader(p3.getErrorStream()));
                                    while (true) {
                                        String line5 = bre3.readLine();
                                        if (line5 == null) {
                                            break;
                                        }
                                        System.out.println(line5);
                                    }
                                    bre3.close();
                                    int cmpExitValue = p3.waitFor();
                                    if (cmpExitValue == 0) {
                                        if (differentPagesFail == null) {
                                            String differentPagesFail2 = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i + 1));
                                            differentPagesFail = differentPagesFail2 + "\nPlease, examine " + outPath + differenceImagePrefix + Integer.toString(i + 1) + ".png for more details.";
                                        } else {
                                            differentPagesFail = "File " + this.outPdf + " differs.\nPlease, examine difference images for more details.";
                                        }
                                    } else {
                                        differentPagesFail = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i + 1));
                                    }
                                    System.out.println(differentPagesFail);
                                } else {
                                    String differentPagesFail3 = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i + 1));
                                    differentPagesFail = differentPagesFail3 + "\nYou can optionally specify path to ImageMagick compare tool (e.g. -DcompareExec=\"C:/Program Files/ImageMagick-6.5.4-2/compare.exe\") to visualize differences.";
                                    break;
                                }
                            } else {
                                System.out.println("done.");
                            }
                        }
                    }
                    if (differentPagesFail == null) {
                        if (bUnexpectedNumberOfPages) {
                            String differentPagesFail4 = unexpectedNumberOfPages.replace("<filename>", this.outPdf);
                            return differentPagesFail4;
                        }
                        return null;
                    }
                    return differentPagesFail;
                }
                return gsFailed.replace("<filename>", this.outPdf);
            }
            return gsFailed.replace("<filename>", this.cmpPdf);
        }
        return cannotOpenTargetDirectory.replace("<filename>", this.outPdf);
    }

    public String compare(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix, Map<Integer, List<Rectangle>> ignoredAreas) throws IOException, InterruptedException, DocumentException {
        init(outPdf, cmpPdf);
        return compare(outPath, differenceImagePrefix, ignoredAreas);
    }

    public String compare(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix) throws IOException, InterruptedException, DocumentException {
        return compare(outPdf, cmpPdf, outPath, differenceImagePrefix, null);
    }

    public String compareByContent(String outPath, String differenceImagePrefix, Map<Integer, List<Rectangle>> ignoredAreas) throws DocumentException, InterruptedException, IOException {
        PdfReader outReader = new PdfReader(this.outPdf);
        this.outPages = new ArrayList();
        this.outPagesRef = new ArrayList();
        loadPagesFromReader(outReader, this.outPages, this.outPagesRef);
        PdfReader cmpReader = new PdfReader(this.cmpPdf);
        this.cmpPages = new ArrayList();
        this.cmpPagesRef = new ArrayList();
        loadPagesFromReader(cmpReader, this.cmpPages, this.cmpPagesRef);
        if (this.outPages.size() != this.cmpPages.size()) {
            return compare(outPath, differenceImagePrefix, ignoredAreas);
        }
        List<Integer> equalPages = new ArrayList<>(this.cmpPages.size());
        for (int i = 0; i < this.cmpPages.size(); i++) {
            if (objectsIsEquals(this.outPages.get(i), this.cmpPages.get(i))) {
                equalPages.add(Integer.valueOf(i));
            }
        }
        outReader.close();
        cmpReader.close();
        if (equalPages.size() == this.cmpPages.size()) {
            return null;
        }
        String message = compare(outPath, differenceImagePrefix, ignoredAreas, equalPages);
        if (message == null || message.length() == 0) {
            return "Compare by content fails. No visual differences";
        }
        return message;
    }

    public String compareByContent(String outPath, String differenceImagePrefix) throws DocumentException, InterruptedException, IOException {
        return compareByContent(outPath, differenceImagePrefix, null);
    }

    public String compareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix, Map<Integer, List<Rectangle>> ignoredAreas) throws DocumentException, InterruptedException, IOException {
        init(outPdf, cmpPdf);
        return compareByContent(outPath, differenceImagePrefix, ignoredAreas);
    }

    public String compareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix) throws DocumentException, InterruptedException, IOException {
        return compareByContent(outPdf, cmpPdf, outPath, differenceImagePrefix, null);
    }

    private void loadPagesFromReader(PdfReader reader, List<PdfDictionary> pages, List<RefKey> pagesRef) {
        PdfObject pagesDict = reader.getCatalog().get(PdfName.PAGES);
        addPagesFromDict(pagesDict, pages, pagesRef);
    }

    private void addPagesFromDict(PdfObject dictRef, List<PdfDictionary> pages, List<RefKey> pagesRef) {
        PdfDictionary dict = (PdfDictionary) PdfReader.getPdfObject(dictRef);
        if (dict.isPages()) {
            PdfArray kids = dict.getAsArray(PdfName.KIDS);
            if (kids != null) {
                Iterator i$ = kids.iterator();
                while (i$.hasNext()) {
                    PdfObject kid = i$.next();
                    addPagesFromDict(kid, pages, pagesRef);
                }
            }
        } else if (dict.isPage()) {
            pages.add(dict);
            pagesRef.add(new RefKey((PdfIndirectReference) ((PRIndirectReference) dictRef)));
        }
    }

    private boolean objectsIsEquals(PdfDictionary outDict, PdfDictionary cmpDict) throws IOException {
        for (PdfName key : cmpDict.getKeys()) {
            if (key.compareTo(PdfName.PARENT) != 0) {
                if (key.compareTo(PdfName.BASEFONT) == 0 || key.compareTo(PdfName.FONTNAME) == 0) {
                    PdfObject cmpObj = cmpDict.getDirectObject(key);
                    if (cmpObj.isName() && cmpObj.toString().indexOf(43) > 0) {
                        PdfObject outObj = outDict.getDirectObject(key);
                        if (!outObj.isName()) {
                            return false;
                        }
                        String cmpName = cmpObj.toString().substring(cmpObj.toString().indexOf(43));
                        String outName = outObj.toString().substring(outObj.toString().indexOf(43));
                        if (!cmpName.equals(outName)) {
                            return false;
                        }
                    }
                }
                if (!objectsIsEquals(outDict.get(key), cmpDict.get(key))) {
                    return false;
                }
            }
        }
        return true;
    }

    private boolean objectsIsEquals(PdfObject outObj, PdfObject cmpObj) throws IOException {
        PdfObject outDirectObj = PdfReader.getPdfObject(outObj);
        PdfObject cmpDirectObj = PdfReader.getPdfObject(cmpObj);
        if (outDirectObj == null || cmpDirectObj.type() != outDirectObj.type()) {
            return false;
        }
        if (cmpDirectObj.isDictionary()) {
            PdfDictionary cmpDict = (PdfDictionary) cmpDirectObj;
            PdfDictionary outDict = (PdfDictionary) outDirectObj;
            if (cmpDict.isPage()) {
                if (outDict.isPage()) {
                    RefKey cmpRefKey = new RefKey((PdfIndirectReference) ((PRIndirectReference) cmpObj));
                    RefKey outRefKey = new RefKey((PdfIndirectReference) ((PRIndirectReference) outObj));
                    return this.cmpPagesRef.contains(cmpRefKey) && this.cmpPagesRef.indexOf(cmpRefKey) == this.outPagesRef.indexOf(outRefKey);
                }
                return false;
            } else if (!objectsIsEquals(outDict, cmpDict)) {
                return false;
            }
        } else if (cmpDirectObj.isStream()) {
            if (!objectsIsEquals((PRStream) outDirectObj, (PRStream) cmpDirectObj)) {
                return false;
            }
        } else if (cmpDirectObj.isArray()) {
            if (!objectsIsEquals((PdfArray) outDirectObj, (PdfArray) cmpDirectObj)) {
                return false;
            }
        } else if (cmpDirectObj.isName()) {
            if (!objectsIsEquals((PdfName) outDirectObj, (PdfName) cmpDirectObj)) {
                return false;
            }
        } else if (cmpDirectObj.isNumber()) {
            if (!objectsIsEquals((PdfNumber) outDirectObj, (PdfNumber) cmpDirectObj)) {
                return false;
            }
        } else if (cmpDirectObj.isString()) {
            if (!objectsIsEquals((PdfString) outDirectObj, (PdfString) cmpDirectObj)) {
                return false;
            }
        } else if (cmpDirectObj.isBoolean()) {
            if (!objectsIsEquals((PdfBoolean) outDirectObj, (PdfBoolean) cmpDirectObj)) {
                return false;
            }
        } else {
            throw new UnsupportedOperationException();
        }
        return true;
    }

    private boolean objectsIsEquals(PRStream outStream, PRStream cmpStream) throws IOException {
        return Arrays.equals(PdfReader.getStreamBytesRaw(outStream), PdfReader.getStreamBytesRaw(cmpStream));
    }

    private boolean objectsIsEquals(PdfArray outArray, PdfArray cmpArray) throws IOException {
        if (outArray == null || outArray.size() != cmpArray.size()) {
            return false;
        }
        for (int i = 0; i < cmpArray.size(); i++) {
            if (!objectsIsEquals(outArray.getPdfObject(i), cmpArray.getPdfObject(i))) {
                return false;
            }
        }
        return true;
    }

    private boolean objectsIsEquals(PdfName outName, PdfName cmpName) {
        return cmpName.compareTo(outName) == 0;
    }

    private boolean objectsIsEquals(PdfNumber outNumber, PdfNumber cmpNumber) {
        return cmpNumber.doubleValue() == outNumber.doubleValue();
    }

    private boolean objectsIsEquals(PdfString outString, PdfString cmpString) {
        return Arrays.equals(cmpString.getBytes(), outString.getBytes());
    }

    private boolean objectsIsEquals(PdfBoolean outBoolean, PdfBoolean cmpBoolean) {
        return Arrays.equals(cmpBoolean.getBytes(), outBoolean.getBytes());
    }

    public String compareXmp() {
        return compareXmp(false);
    }

    public String compareXmp(boolean ignoreDateAndProducerProperties) {
        PdfReader cmpReader = null;
        PdfReader outReader = null;
        try {
            PdfReader cmpReader2 = new PdfReader(this.cmpPdf);
            try {
                PdfReader outReader2 = new PdfReader(this.outPdf);
                try {
                    byte[] cmpBytes = cmpReader2.getMetadata();
                    byte[] outBytes = outReader2.getMetadata();
                    if (ignoreDateAndProducerProperties) {
                        XMPMeta xmpMeta = XMPMetaFactory.parseFromBuffer(cmpBytes);
                        XMPUtils.removeProperties(xmpMeta, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.CREATEDATE, true, true);
                        XMPUtils.removeProperties(xmpMeta, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.MODIFYDATE, true, true);
                        XMPUtils.removeProperties(xmpMeta, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.METADATADATE, true, true);
                        XMPUtils.removeProperties(xmpMeta, "http://ns.adobe.com/pdf/1.3/", PdfProperties.PRODUCER, true, true);
                        cmpBytes = XMPMetaFactory.serializeToBuffer(xmpMeta, new SerializeOptions(8192));
                        XMPMeta xmpMeta2 = XMPMetaFactory.parseFromBuffer(outBytes);
                        XMPUtils.removeProperties(xmpMeta2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.CREATEDATE, true, true);
                        XMPUtils.removeProperties(xmpMeta2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.MODIFYDATE, true, true);
                        XMPUtils.removeProperties(xmpMeta2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.METADATADATE, true, true);
                        XMPUtils.removeProperties(xmpMeta2, "http://ns.adobe.com/pdf/1.3/", PdfProperties.PRODUCER, true, true);
                        outBytes = XMPMetaFactory.serializeToBuffer(xmpMeta2, new SerializeOptions(8192));
                    }
                    if (compareXmls(cmpBytes, outBytes)) {
                        if (cmpReader2 != null) {
                            cmpReader2.close();
                        }
                        if (outReader2 != null) {
                            outReader2.close();
                        }
                        return null;
                    }
                    if (cmpReader2 != null) {
                        cmpReader2.close();
                    }
                    if (outReader2 != null) {
                        outReader2.close();
                    }
                    return "The XMP packages different!";
                } catch (XMPException e) {
                    outReader = outReader2;
                    cmpReader = cmpReader2;
                    if (cmpReader != null) {
                        cmpReader.close();
                    }
                    if (outReader != null) {
                        outReader.close();
                        return "XMP parsing failure!";
                    }
                    return "XMP parsing failure!";
                } catch (IOException e2) {
                    outReader = outReader2;
                    cmpReader = cmpReader2;
                    if (cmpReader != null) {
                        cmpReader.close();
                    }
                    if (outReader != null) {
                        outReader.close();
                        return "XMP parsing failure!";
                    }
                    return "XMP parsing failure!";
                } catch (ParserConfigurationException e3) {
                    outReader = outReader2;
                    cmpReader = cmpReader2;
                    if (cmpReader != null) {
                        cmpReader.close();
                    }
                    if (outReader != null) {
                        outReader.close();
                        return "XMP parsing failure!";
                    }
                    return "XMP parsing failure!";
                } catch (SAXException e4) {
                    outReader = outReader2;
                    cmpReader = cmpReader2;
                    if (cmpReader != null) {
                        cmpReader.close();
                    }
                    if (outReader != null) {
                        outReader.close();
                        return "XMP parsing failure!";
                    }
                    return "XMP parsing failure!";
                } catch (Throwable th) {
                    th = th;
                    outReader = outReader2;
                    cmpReader = cmpReader2;
                    if (cmpReader != null) {
                        cmpReader.close();
                    }
                    if (outReader != null) {
                        outReader.close();
                    }
                    throw th;
                }
            } catch (XMPException e5) {
                cmpReader = cmpReader2;
            } catch (IOException e6) {
                cmpReader = cmpReader2;
            } catch (ParserConfigurationException e7) {
                cmpReader = cmpReader2;
            } catch (SAXException e8) {
                cmpReader = cmpReader2;
            } catch (Throwable th2) {
                th = th2;
                cmpReader = cmpReader2;
            }
        } catch (XMPException e9) {
        } catch (IOException e10) {
        } catch (ParserConfigurationException e11) {
        } catch (SAXException e12) {
        } catch (Throwable th3) {
            th = th3;
        }
    }

    public boolean compareXmls(byte[] xml1, byte[] xml2) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setCoalescing(true);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setIgnoringComments(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc1 = db.parse(new ByteArrayInputStream(xml1));
        doc1.normalizeDocument();
        Document doc2 = db.parse(new ByteArrayInputStream(xml2));
        doc2.normalizeDocument();
        return doc2.isEqualNode(doc1);
    }

    public String compareDocumentInfo(String outPdf, String cmpPdf) throws IOException {
        System.out.println("Comparing document info...");
        String message = null;
        PdfReader outReader = new PdfReader(outPdf);
        PdfReader cmpReader = new PdfReader(cmpPdf);
        String[] cmpInfo = convertInfo(cmpReader.getInfo());
        String[] outInfo = convertInfo(outReader.getInfo());
        int i = 0;
        while (true) {
            if (i >= cmpInfo.length) {
                break;
            } else if (cmpInfo[i].equals(outInfo[i])) {
                i++;
            } else {
                message = "Document info fail";
                break;
            }
        }
        outReader.close();
        cmpReader.close();
        return message;
    }

    private boolean linksAreSame(PdfAnnotation.PdfImportedLink cmpLink, PdfAnnotation.PdfImportedLink outLink) {
        if (cmpLink.getDestinationPage() == outLink.getDestinationPage() && cmpLink.getRect().toString().equals(outLink.getRect().toString())) {
            Map<PdfName, PdfObject> cmpParams = cmpLink.getParameters();
            Map<PdfName, PdfObject> outParams = outLink.getParameters();
            if (cmpParams.size() == outParams.size()) {
                for (Map.Entry<PdfName, PdfObject> cmpEntry : cmpParams.entrySet()) {
                    PdfObject cmpObj = cmpEntry.getValue();
                    if (outParams.containsKey(cmpEntry.getKey())) {
                        PdfObject outObj = outParams.get(cmpEntry.getKey());
                        if (cmpObj.type() == outObj.type()) {
                            switch (cmpObj.type()) {
                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                case 8:
                                    if (cmpObj.toString().equals(outObj.toString())) {
                                        break;
                                    } else {
                                        return false;
                                    }
                            }
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        return false;
    }

    public String compareLinks(String outPdf, String cmpPdf) throws IOException {
        System.out.println("Comparing link annotations...");
        String message = null;
        PdfReader outReader = new PdfReader(outPdf);
        PdfReader cmpReader = new PdfReader(cmpPdf);
        int i = 0;
        while (true) {
            if (i >= outReader.getNumberOfPages() || i >= cmpReader.getNumberOfPages()) {
                break;
            }
            List<PdfAnnotation.PdfImportedLink> outLinks = outReader.getLinks(i + 1);
            List<PdfAnnotation.PdfImportedLink> cmpLinks = cmpReader.getLinks(i + 1);
            if (cmpLinks.size() != outLinks.size()) {
                message = String.format("Different number of links on page %d.", Integer.valueOf(i + 1));
                break;
            }
            int j = 0;
            while (true) {
                if (j >= cmpLinks.size()) {
                    break;
                } else if (linksAreSame(cmpLinks.get(j), outLinks.get(j))) {
                    j++;
                } else {
                    message = String.format("Different links on page %d.\n%s\n%s", Integer.valueOf(i + 1), cmpLinks.get(j).toString(), outLinks.get(j).toString());
                    break;
                }
            }
            i++;
        }
        outReader.close();
        cmpReader.close();
        return message;
    }

    public String compareTagStructures(String outPdf, String cmpPdf) throws IOException, ParserConfigurationException, SAXException {
        System.out.println("Comparing tag structures...");
        String outXml = outPdf.replace(".pdf", ".xml");
        String cmpXml = outPdf.replace(".pdf", ".cmp.xml");
        String error = null;
        PdfReader reader = new PdfReader(outPdf);
        FileOutputStream xmlOut1 = new FileOutputStream(outXml);
        new CmpTaggedPdfReaderTool().convertToXml(reader, xmlOut1);
        reader.close();
        PdfReader reader2 = new PdfReader(cmpPdf);
        FileOutputStream xmlOut2 = new FileOutputStream(cmpXml);
        new CmpTaggedPdfReaderTool().convertToXml(reader2, xmlOut2);
        reader2.close();
        if (!compareXmls(outXml, cmpXml)) {
            error = "The tag structures are different.";
        }
        xmlOut1.close();
        xmlOut2.close();
        return error;
    }

    private String[] convertInfo(HashMap<String, String> info) {
        String[] convertedInfo = {PdfObject.NOTHING, PdfObject.NOTHING, PdfObject.NOTHING, PdfObject.NOTHING};
        for (Map.Entry<String, String> entry : info.entrySet()) {
            if ("title".equalsIgnoreCase(entry.getKey())) {
                convertedInfo[0] = entry.getValue();
            } else if (Meta.AUTHOR.equalsIgnoreCase(entry.getKey())) {
                convertedInfo[1] = entry.getValue();
            } else if ("subject".equalsIgnoreCase(entry.getKey())) {
                convertedInfo[2] = entry.getValue();
            } else if (Meta.KEYWORDS.equalsIgnoreCase(entry.getKey())) {
                convertedInfo[3] = entry.getValue();
            }
        }
        return convertedInfo;
    }

    public boolean compareXmls(String xml1, String xml2) throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setCoalescing(true);
        dbf.setIgnoringElementContentWhitespace(true);
        dbf.setIgnoringComments(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc1 = db.parse(new File(xml1));
        doc1.normalizeDocument();
        Document doc2 = db.parse(new File(xml2));
        doc2.normalizeDocument();
        return doc2.isEqualNode(doc1);
    }

    private void init(String outPdf, String cmpPdf) {
        this.outPdf = outPdf;
        this.cmpPdf = cmpPdf;
        this.outPdfName = new File(outPdf).getName();
        this.cmpPdfName = new File(cmpPdf).getName();
        this.outImage = this.outPdfName + "-%03d.png";
        if (!this.cmpPdfName.startsWith("cmp_")) {
            this.cmpImage = "cmp_" + this.cmpPdfName + "-%03d.png";
        } else {
            this.cmpImage = this.cmpPdfName + "-%03d.png";
        }
    }

    private boolean compareStreams(InputStream is1, InputStream is2) throws IOException {
        int len1;
        byte[] buffer1 = new byte[65536];
        byte[] buffer2 = new byte[65536];
        do {
            len1 = is1.read(buffer1);
            int len2 = is2.read(buffer2);
            if (len1 != len2 || !Arrays.equals(buffer1, buffer2)) {
                return false;
            }
        } while (len1 != -1);
        return true;
    }

    public class PngFileFilter implements FileFilter {
        PngFileFilter() {
        }

        @Override
        public boolean accept(File pathname) {
            String ap = pathname.getAbsolutePath();
            boolean b1 = ap.endsWith(".png");
            boolean b2 = ap.contains("cmp_");
            return b1 && !b2 && ap.contains(CompareTool.this.outPdfName);
        }
    }

    public class CmpPngFileFilter implements FileFilter {
        CmpPngFileFilter() {
        }

        @Override
        public boolean accept(File pathname) {
            String ap = pathname.getAbsolutePath();
            boolean b1 = ap.endsWith(".png");
            boolean b2 = ap.contains("cmp_");
            return b1 && b2 && ap.contains(CompareTool.this.cmpPdfName);
        }
    }

    public class ImageNameComparator implements Comparator<File> {
        ImageNameComparator() {
        }

        @Override
        public int compare(File f1, File f2) {
            String f1Name = f1.getAbsolutePath();
            String f2Name = f2.getAbsolutePath();
            return f1Name.compareTo(f2Name);
        }
    }

    class CmpTaggedPdfReaderTool extends TaggedPdfReaderTool {
        Map<PdfDictionary, Map<Integer, String>> parsedTags = new HashMap();

        CmpTaggedPdfReaderTool() {
        }

        @Override
        public void parseTag(String tag, PdfObject object, PdfDictionary page) throws IOException {
            if (object instanceof PdfNumber) {
                if (!this.parsedTags.containsKey(page)) {
                    CmpMarkedContentRenderFilter listener = new CmpMarkedContentRenderFilter();
                    PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
                    processor.processContent(PdfReader.getPageContent(page), page.getAsDict(PdfName.RESOURCES));
                    this.parsedTags.put(page, listener.getParsedTagContent());
                }
                String tagContent = PdfObject.NOTHING;
                if (this.parsedTags.get(page).containsKey(Integer.valueOf(((PdfNumber) object).intValue()))) {
                    String tagContent2 = this.parsedTags.get(page).get(Integer.valueOf(((PdfNumber) object).intValue()));
                    tagContent = tagContent2;
                }
                this.out.print(XMLUtil.escapeXML(tagContent, true));
                return;
            }
            super.parseTag(tag, object, page);
        }

        @Override
        public void inspectChildDictionary(PdfDictionary k) throws IOException {
            inspectChildDictionary(k, true);
        }
    }

    class CmpMarkedContentRenderFilter implements RenderListener {
        Map<Integer, TextExtractionStrategy> tagsByMcid = new HashMap();

        CmpMarkedContentRenderFilter() {
        }

        public Map<Integer, String> getParsedTagContent() {
            Map<Integer, String> content = new HashMap<>();
            for (Integer num : this.tagsByMcid.keySet()) {
                int id = num.intValue();
                content.put(Integer.valueOf(id), this.tagsByMcid.get(Integer.valueOf(id)).getResultantText());
            }
            return content;
        }

        @Override
        public void beginTextBlock() {
            for (Integer num : this.tagsByMcid.keySet()) {
                int id = num.intValue();
                this.tagsByMcid.get(Integer.valueOf(id)).beginTextBlock();
            }
        }

        @Override
        public void renderText(TextRenderInfo renderInfo) {
            Integer mcid = renderInfo.getMcid();
            if (mcid != null && this.tagsByMcid.containsKey(mcid)) {
                this.tagsByMcid.get(mcid).renderText(renderInfo);
            } else if (mcid != null) {
                this.tagsByMcid.put(mcid, new SimpleTextExtractionStrategy());
                this.tagsByMcid.get(mcid).renderText(renderInfo);
            }
        }

        @Override
        public void endTextBlock() {
            for (Integer num : this.tagsByMcid.keySet()) {
                int id = num.intValue();
                this.tagsByMcid.get(Integer.valueOf(id)).endTextBlock();
            }
        }

        @Override
        public void renderImage(ImageRenderInfo renderInfo) {
        }
    }
}