正在查看: Harvest v2.32 应用的 CompareTool.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: Harvest v2.32 应用的 CompareTool.java JAVA 源代码文件
本页面展示 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.html.HtmlTags;
import com.itextpdf.text.io.RandomAccessSourceFactory;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PRTokeniser;
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.PdfContentParser;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfIndirectReference;
import com.itextpdf.text.pdf.PdfLiteral;
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.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.RefKey;
import com.itextpdf.text.pdf.parser.ContentByteUtils;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.InlineImageInfo;
import com.itextpdf.text.pdf.parser.InlineImageUtils;
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.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
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>\"";
private int compareByContentErrorsLimit = 1;
private boolean generateCompareByContentXmlReport = false;
private String xmlReportName = "report";
private double floatComparisonError = 0.0d;
private boolean absoluteError = true;
private class ObjectPath {
protected RefKey baseCmpObject;
protected RefKey baseOutObject;
protected Stack<Pair<RefKey>> indirects;
protected Stack<PathItem> path;
public ObjectPath() {
this.path = new Stack<>();
this.indirects = new Stack<>();
}
protected ObjectPath(RefKey refKey, RefKey refKey2) {
this.path = new Stack<>();
this.indirects = new Stack<>();
this.baseCmpObject = refKey;
this.baseOutObject = refKey2;
}
private ObjectPath(RefKey refKey, RefKey refKey2, Stack<PathItem> stack) {
this.path = new Stack<>();
this.indirects = new Stack<>();
this.baseCmpObject = refKey;
this.baseOutObject = refKey2;
this.path = stack;
}
private class Pair<T> {
private T first;
private T second;
public Pair(T t, T t2) {
this.first = t;
this.second = t2;
}
public int hashCode() {
return (this.first.hashCode() * 31) + this.second.hashCode();
}
public boolean equals(Object obj) {
if (obj instanceof Pair) {
Pair pair = (Pair) obj;
if (this.first.equals(pair.first) && this.second.equals(pair.second)) {
return true;
}
}
return false;
}
}
private abstract class PathItem {
protected abstract Node toXmlNode(Document document);
private PathItem() {
}
}
private class DictPathItem extends PathItem {
String key;
public DictPathItem(String str) {
super();
this.key = str;
}
public String toString() {
return "Dict key: " + this.key;
}
public int hashCode() {
return this.key.hashCode();
}
public boolean equals(Object obj) {
return (obj instanceof DictPathItem) && this.key.equals(((DictPathItem) obj).key);
}
@Override
protected Node toXmlNode(Document document) {
Element createElement = document.createElement("dictKey");
createElement.appendChild(document.createTextNode(this.key));
return createElement;
}
}
private class ArrayPathItem extends PathItem {
int index;
public ArrayPathItem(int i) {
super();
this.index = i;
}
public String toString() {
return "Array index: " + String.valueOf(this.index);
}
public int hashCode() {
return this.index;
}
public boolean equals(Object obj) {
return (obj instanceof ArrayPathItem) && this.index == ((ArrayPathItem) obj).index;
}
@Override
protected Node toXmlNode(Document document) {
Element createElement = document.createElement("arrayIndex");
createElement.appendChild(document.createTextNode(String.valueOf(this.index)));
return createElement;
}
}
private class OffsetPathItem extends PathItem {
int offset;
public OffsetPathItem(int i) {
super();
this.offset = i;
}
public String toString() {
return "Offset: " + String.valueOf(this.offset);
}
public int hashCode() {
return this.offset;
}
public boolean equals(Object obj) {
return (obj instanceof OffsetPathItem) && this.offset == ((OffsetPathItem) obj).offset;
}
@Override
protected Node toXmlNode(Document document) {
Element createElement = document.createElement("offset");
createElement.appendChild(document.createTextNode(String.valueOf(this.offset)));
return createElement;
}
}
public ObjectPath resetDirectPath(RefKey refKey, RefKey refKey2) {
ObjectPath objectPath = CompareTool.this.new ObjectPath(refKey, refKey2);
Stack<Pair<RefKey>> stack = (Stack) this.indirects.clone();
objectPath.indirects = stack;
stack.add(new Pair<>(refKey, refKey2));
return objectPath;
}
public boolean isComparing(RefKey refKey, RefKey refKey2) {
return this.indirects.contains(new Pair(refKey, refKey2));
}
public void pushArrayItemToPath(int i) {
this.path.add(new ArrayPathItem(i));
}
public void pushDictItemToPath(String str) {
this.path.add(new DictPathItem(str));
}
public void pushOffsetToPath(int i) {
this.path.add(new OffsetPathItem(i));
}
public void pop() {
this.path.pop();
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(String.format("Base cmp object: %s obj. Base out object: %s obj", this.baseCmpObject, this.baseOutObject));
Iterator<PathItem> it = this.path.iterator();
while (it.hasNext()) {
PathItem next = it.next();
sb.append("\n");
sb.append(next.toString());
}
return sb.toString();
}
public int hashCode() {
RefKey refKey = this.baseCmpObject;
int hashCode = refKey != null ? refKey.hashCode() : 1;
RefKey refKey2 = this.baseOutObject;
int hashCode2 = (hashCode * 31) + (refKey2 != null ? refKey2.hashCode() : 1);
Iterator<PathItem> it = this.path.iterator();
while (it.hasNext()) {
hashCode2 = (hashCode2 * 31) + it.next().hashCode();
}
return hashCode2;
}
public boolean equals(Object obj) {
if (obj instanceof ObjectPath) {
ObjectPath objectPath = (ObjectPath) obj;
if (this.baseCmpObject.equals(objectPath.baseCmpObject) && this.baseOutObject.equals(objectPath.baseOutObject) && this.path.equals(objectPath.path)) {
return true;
}
}
return false;
}
protected Object clone() {
return CompareTool.this.new ObjectPath(this.baseCmpObject, this.baseOutObject, (Stack) this.path.clone());
}
public Node toXmlNode(Document document) {
Element createElement = document.createElement("path");
Element createElement2 = document.createElement("base");
createElement2.setAttribute("cmp", this.baseCmpObject.toString() + " obj");
createElement2.setAttribute("out", this.baseOutObject.toString() + " obj");
createElement.appendChild(createElement2);
Iterator<PathItem> it = this.path.iterator();
while (it.hasNext()) {
createElement.appendChild(it.next().toXmlNode(document));
}
return createElement;
}
}
protected class CompareResult {
protected Map<ObjectPath, String> differences = new LinkedHashMap();
protected int messageLimit;
public CompareResult(int i) {
this.messageLimit = i;
}
public boolean isOk() {
return this.differences.size() == 0;
}
public int getErrorCount() {
return this.differences.size();
}
protected boolean isMessageLimitReached() {
return this.differences.size() >= this.messageLimit;
}
public String getReport() {
StringBuilder sb = new StringBuilder();
boolean z = true;
for (Map.Entry<ObjectPath, String> entry : this.differences.entrySet()) {
if (!z) {
sb.append("-----------------------------\n");
}
ObjectPath key = entry.getKey();
sb.append(entry.getValue());
sb.append("\n");
sb.append(key.toString());
sb.append("\n");
z = false;
}
return sb.toString();
}
protected void addError(ObjectPath objectPath, String str) {
if (this.differences.size() < this.messageLimit) {
this.differences.put((ObjectPath) objectPath.clone(), str);
}
}
public void writeReportToXml(OutputStream outputStream) throws ParserConfigurationException, TransformerException {
Document newDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element createElement = newDocument.createElement("report");
Element createElement2 = newDocument.createElement("errors");
createElement2.setAttribute("count", String.valueOf(this.differences.size()));
createElement.appendChild(createElement2);
for (Map.Entry<ObjectPath, String> entry : this.differences.entrySet()) {
Element createElement3 = newDocument.createElement("error");
Element createElement4 = newDocument.createElement("message");
createElement4.appendChild(newDocument.createTextNode(entry.getValue()));
Node xmlNode = entry.getKey().toXmlNode(newDocument);
createElement3.appendChild(createElement4);
createElement3.appendChild(xmlNode);
createElement2.appendChild(createElement3);
}
newDocument.appendChild(createElement);
Transformer newTransformer = TransformerFactory.newInstance().newTransformer();
newTransformer.setOutputProperty(HtmlTags.INDENT, "yes");
newTransformer.transform(new DOMSource(newDocument), new StreamResult(outputStream));
}
}
public CompareTool() {
String property = System.getProperty("gsExec");
this.gsExec = property;
if (property == null) {
this.gsExec = System.getenv("gsExec");
}
String property2 = System.getProperty("compareExec");
this.compareExec = property2;
if (property2 == null) {
this.compareExec = System.getenv("compareExec");
}
}
private String compare(String str, String str2, Map<Integer, List<Rectangle>> map) throws IOException, InterruptedException, DocumentException {
return compare(str, str2, map, (List<Integer>) null);
}
private String compare(String str, String str2, Map<Integer, List<Rectangle>> map, List<Integer> list) throws IOException, InterruptedException, DocumentException {
File[] fileArr;
String replace;
String str3 = str;
List<Integer> list2 = list;
if (this.gsExec == null) {
return undefinedGsPath;
}
if (!new File(this.gsExec).exists()) {
return new File(this.gsExec).getAbsolutePath() + " does not exist";
}
if (!str3.endsWith("/")) {
str3 = str3 + "/";
}
File file = new File(str3);
if (!file.exists()) {
file.mkdirs();
} else {
for (File file2 : file.listFiles(new PngFileFilter())) {
file2.delete();
}
for (File file3 : file.listFiles(new CmpPngFileFilter())) {
file3.delete();
}
}
File file4 = new File(str3 + str2);
if (file4.exists()) {
file4.delete();
}
if (map != null && !map.isEmpty()) {
PdfReader pdfReader = new PdfReader(this.cmpPdf);
PdfReader pdfReader2 = new PdfReader(this.outPdf);
PdfStamper pdfStamper = new PdfStamper(pdfReader2, new FileOutputStream(str3 + ignoredAreasPrefix + this.outPdfName));
PdfStamper pdfStamper2 = new PdfStamper(pdfReader, new FileOutputStream(str3 + ignoredAreasPrefix + this.cmpPdfName));
for (Map.Entry<Integer, List<Rectangle>> entry : map.entrySet()) {
int intValue = entry.getKey().intValue();
List<Rectangle> value = entry.getValue();
if (value != null && !value.isEmpty()) {
PdfContentByte overContent = pdfStamper.getOverContent(intValue);
PdfContentByte overContent2 = pdfStamper2.getOverContent(intValue);
for (Rectangle rectangle : value) {
rectangle.setBackgroundColor(BaseColor.BLACK);
overContent.rectangle(rectangle);
overContent2.rectangle(rectangle);
}
}
}
pdfStamper.close();
pdfStamper2.close();
pdfReader2.close();
pdfReader.close();
init(str3 + ignoredAreasPrefix + this.outPdfName, str3 + ignoredAreasPrefix + this.cmpPdfName);
}
if (file.exists()) {
Process runProcess = runProcess(this.gsExec, " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>".replace("<outputfile>", str3 + this.cmpImage).replace("<inputfile>", this.cmpPdf));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
while (true) {
String readLine = bufferedReader.readLine();
if (readLine == null) {
break;
}
System.out.println(readLine);
}
bufferedReader.close();
while (true) {
String readLine2 = bufferedReader2.readLine();
if (readLine2 == null) {
break;
}
System.out.println(readLine2);
}
bufferedReader2.close();
if (runProcess.waitFor() == 0) {
Process runProcess2 = runProcess(this.gsExec, " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=<outputfile> <inputfile>".replace("<outputfile>", str3 + this.outImage).replace("<inputfile>", this.outPdf));
BufferedReader bufferedReader3 = new BufferedReader(new InputStreamReader(runProcess2.getInputStream()));
BufferedReader bufferedReader4 = new BufferedReader(new InputStreamReader(runProcess2.getErrorStream()));
while (true) {
String readLine3 = bufferedReader3.readLine();
if (readLine3 == null) {
break;
}
System.out.println(readLine3);
}
bufferedReader3.close();
while (true) {
String readLine4 = bufferedReader4.readLine();
if (readLine4 == null) {
break;
}
System.out.println(readLine4);
}
bufferedReader4.close();
if (runProcess2.waitFor() == 0) {
File[] listFiles = file.listFiles(new PngFileFilter());
File[] listFiles2 = file.listFiles(new CmpPngFileFilter());
boolean z = listFiles.length != listFiles2.length;
int min = Math.min(listFiles.length, listFiles2.length);
if (min < 1) {
return "No files for comparing!!!\nThe result or sample pdf file is not processed by GhostScript.";
}
Arrays.sort(listFiles, new ImageNameComparator());
Arrays.sort(listFiles2, new ImageNameComparator());
int i = 0;
String str4 = null;
while (i < min) {
if (list2 == null || !list2.contains(Integer.valueOf(i))) {
PrintStream printStream = System.out;
StringBuilder sb = new StringBuilder("Comparing page ");
int i2 = i + 1;
sb.append(Integer.toString(i2));
sb.append(" (");
sb.append(listFiles[i].getAbsolutePath());
sb.append(")...");
printStream.print(sb.toString());
FileInputStream fileInputStream = new FileInputStream(listFiles[i]);
FileInputStream fileInputStream2 = new FileInputStream(listFiles2[i]);
boolean compareStreams = compareStreams(fileInputStream, fileInputStream2);
fileInputStream.close();
fileInputStream2.close();
if (!compareStreams) {
if (this.compareExec != null && new File(this.compareExec).exists()) {
Process runProcess3 = runProcess(this.compareExec, " \"<image1>\" \"<image2>\" \"<difference>\"".replace("<image1>", listFiles[i].getAbsolutePath()).replace("<image2>", listFiles2[i].getAbsolutePath()).replace("<difference>", str3 + str2 + Integer.toString(i2) + ".png"));
fileArr = listFiles2;
BufferedReader bufferedReader5 = new BufferedReader(new InputStreamReader(runProcess3.getErrorStream()));
while (true) {
String readLine5 = bufferedReader5.readLine();
if (readLine5 == null) {
break;
}
System.out.println(readLine5);
}
bufferedReader5.close();
if (runProcess3.waitFor() != 0) {
replace = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i2));
} else if (str4 == null) {
replace = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i2)) + "\nPlease, examine " + str3 + str2 + Integer.toString(i2) + ".png for more details.";
} else {
replace = "File " + this.outPdf + " differs.\nPlease, examine difference images for more details.";
}
str4 = replace;
System.out.println(str4);
} else {
str4 = differentPages.replace("<filename>", this.outPdf).replace("<pagenumber>", Integer.toString(i2)) + "\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 {
fileArr = listFiles2;
System.out.println("done.");
}
} else {
fileArr = listFiles2;
}
i++;
listFiles2 = fileArr;
list2 = list;
}
if (str4 != null) {
return str4;
}
if (z) {
return unexpectedNumberOfPages.replace("<filename>", this.outPdf);
}
return null;
}
return gsFailed.replace("<filename>", this.outPdf);
}
return gsFailed.replace("<filename>", this.cmpPdf);
}
return cannotOpenTargetDirectory.replace("<filename>", this.outPdf);
}
private Process runProcess(String str, String str2) throws IOException, InterruptedException {
StringTokenizer stringTokenizer = new StringTokenizer(str2);
String[] strArr = new String[stringTokenizer.countTokens() + 1];
strArr[0] = str;
int i = 1;
while (stringTokenizer.hasMoreTokens()) {
strArr[i] = stringTokenizer.nextToken();
i++;
}
return Runtime.getRuntime().exec(strArr);
}
public String compare(String str, String str2, String str3, String str4, Map<Integer, List<Rectangle>> map) throws IOException, InterruptedException, DocumentException {
init(str, str2);
return compare(str3, str4, map);
}
public String compare(String str, String str2, String str3, String str4) throws IOException, InterruptedException, DocumentException {
return compare(str, str2, str3, str4, null);
}
public CompareTool setCompareByContentErrorsLimit(int i) {
this.compareByContentErrorsLimit = i;
return this;
}
public void setGenerateCompareByContentXmlReport(boolean z) {
this.generateCompareByContentXmlReport = z;
}
public CompareTool setFloatAbsoluteError(float f) {
this.floatComparisonError = f;
this.absoluteError = true;
return this;
}
public CompareTool setFloatRelativeError(float f) {
this.floatComparisonError = f;
this.absoluteError = false;
return this;
}
public String getXmlReportName() {
return this.xmlReportName;
}
public void setXmlReportName(String str) {
this.xmlReportName = str;
}
protected String compareByContent(String str, String str2, Map<Integer, List<Rectangle>> map) throws DocumentException, InterruptedException, IOException {
System.out.print("[itext] INFO Comparing by content..........");
PdfReader pdfReader = new PdfReader(this.outPdf);
this.outPages = new ArrayList();
ArrayList arrayList = new ArrayList();
this.outPagesRef = arrayList;
loadPagesFromReader(pdfReader, this.outPages, arrayList);
PdfReader pdfReader2 = new PdfReader(this.cmpPdf);
this.cmpPages = new ArrayList();
ArrayList arrayList2 = new ArrayList();
this.cmpPagesRef = arrayList2;
loadPagesFromReader(pdfReader2, this.cmpPages, arrayList2);
if (this.outPages.size() != this.cmpPages.size()) {
return compare(str, str2, map);
}
CompareResult compareResult = new CompareResult(this.compareByContentErrorsLimit);
ArrayList arrayList3 = new ArrayList(this.cmpPages.size());
for (int i = 0; i < this.cmpPages.size(); i++) {
if (compareDictionariesExtended(this.outPages.get(i), this.cmpPages.get(i), new ObjectPath(this.cmpPagesRef.get(i), this.outPagesRef.get(i)), compareResult)) {
arrayList3.add(Integer.valueOf(i));
}
}
PdfObject pdfObject = pdfReader.getCatalog().get(PdfName.STRUCTTREEROOT);
PdfObject pdfObject2 = pdfReader2.getCatalog().get(PdfName.STRUCTTREEROOT);
compareObjects(pdfObject, pdfObject2, new ObjectPath(pdfObject == null ? null : new RefKey((PdfIndirectReference) pdfObject), pdfObject2 == null ? null : new RefKey((PdfIndirectReference) pdfObject2)), compareResult);
PdfObject pdfObject3 = pdfReader.getCatalog().get(PdfName.OCPROPERTIES);
PdfObject pdfObject4 = pdfReader2.getCatalog().get(PdfName.OCPROPERTIES);
compareObjects(pdfObject3, pdfObject4, new ObjectPath(pdfObject3 instanceof PdfIndirectReference ? new RefKey((PdfIndirectReference) pdfObject3) : null, pdfObject4 instanceof PdfIndirectReference ? new RefKey((PdfIndirectReference) pdfObject4) : null), compareResult);
pdfReader.close();
pdfReader2.close();
if (this.generateCompareByContentXmlReport) {
try {
compareResult.writeReportToXml(new FileOutputStream(str + "/" + this.xmlReportName + ".xml"));
} catch (Exception unused) {
}
}
if (arrayList3.size() == this.cmpPages.size() && compareResult.isOk()) {
System.out.println("OK");
System.out.flush();
return null;
}
System.out.println("Fail");
System.out.flush();
System.out.println("Compare by content report:\n" + compareResult.getReport());
System.out.flush();
String compare = compare(str, str2, map, arrayList3);
return (compare == null || compare.length() == 0) ? "Compare by content fails. No visual differences" : compare;
}
public String compareByContent(String str, String str2, String str3, String str4, Map<Integer, List<Rectangle>> map) throws DocumentException, InterruptedException, IOException {
init(str, str2);
return compareByContent(str3, str4, map);
}
public String compareByContent(String str, String str2, String str3, String str4) throws DocumentException, InterruptedException, IOException {
return compareByContent(str, str2, str3, str4, null);
}
private void loadPagesFromReader(PdfReader pdfReader, List<PdfDictionary> list, List<RefKey> list2) {
addPagesFromDict(pdfReader.getCatalog().get(PdfName.PAGES), list, list2);
}
private void addPagesFromDict(PdfObject pdfObject, List<PdfDictionary> list, List<RefKey> list2) {
PdfDictionary pdfDictionary = (PdfDictionary) PdfReader.getPdfObject(pdfObject);
if (pdfDictionary.isPages()) {
PdfArray asArray = pdfDictionary.getAsArray(PdfName.KIDS);
if (asArray == null) {
return;
}
Iterator<PdfObject> it = asArray.iterator();
while (it.hasNext()) {
addPagesFromDict(it.next(), list, list2);
}
return;
}
if (pdfDictionary.isPage()) {
list.add(pdfDictionary);
list2.add(new RefKey((PdfIndirectReference) pdfObject));
}
}
private boolean compareObjects(PdfObject pdfObject, PdfObject pdfObject2, ObjectPath objectPath, CompareResult compareResult) throws IOException {
PdfObject pdfObject3 = PdfReader.getPdfObject(pdfObject);
PdfObject pdfObject4 = PdfReader.getPdfObject(pdfObject2);
if (pdfObject4 == null && pdfObject3 == null) {
return true;
}
if (pdfObject3 == null) {
compareResult.addError(objectPath, "Expected object was not found.");
return false;
}
if (pdfObject4 == null) {
compareResult.addError(objectPath, "Found object which was not expected to be found.");
return false;
}
if (pdfObject4.type() != pdfObject3.type()) {
compareResult.addError(objectPath, String.format("Types do not match. Expected: %s. Found: %s.", pdfObject4.getClass().getSimpleName(), pdfObject3.getClass().getSimpleName()));
return false;
}
if (pdfObject2.isIndirect() && pdfObject.isIndirect()) {
PdfIndirectReference pdfIndirectReference = (PdfIndirectReference) pdfObject2;
PdfIndirectReference pdfIndirectReference2 = (PdfIndirectReference) pdfObject;
if (objectPath.isComparing(new RefKey(pdfIndirectReference), new RefKey(pdfIndirectReference2))) {
return true;
}
objectPath = objectPath.resetDirectPath(new RefKey(pdfIndirectReference), new RefKey(pdfIndirectReference2));
}
if (pdfObject4.isDictionary() && ((PdfDictionary) pdfObject4).isPage()) {
if (!pdfObject3.isDictionary() || !((PdfDictionary) pdfObject3).isPage()) {
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, "Expected a page. Found not a page.");
}
return false;
}
RefKey refKey = new RefKey((PdfIndirectReference) pdfObject2);
RefKey refKey2 = new RefKey((PdfIndirectReference) pdfObject);
if (this.cmpPagesRef.contains(refKey) && this.cmpPagesRef.indexOf(refKey) == this.outPagesRef.indexOf(refKey2)) {
return true;
}
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("The dictionaries refer to different pages. Expected page number: %s. Found: %s", Integer.valueOf(this.cmpPagesRef.indexOf(refKey)), Integer.valueOf(this.outPagesRef.indexOf(refKey2))));
}
return false;
}
if (pdfObject4.isDictionary()) {
if (!compareDictionariesExtended((PdfDictionary) pdfObject3, (PdfDictionary) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isStream()) {
if (!compareStreamsExtended((PRStream) pdfObject3, (PRStream) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isArray()) {
if (!compareArraysExtended((PdfArray) pdfObject3, (PdfArray) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isName()) {
if (!compareNamesExtended((PdfName) pdfObject3, (PdfName) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isNumber()) {
if (!compareNumbersExtended((PdfNumber) pdfObject3, (PdfNumber) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isString()) {
if (!compareStringsExtended((PdfString) pdfObject3, (PdfString) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4.isBoolean()) {
if (!compareBooleansExtended((PdfBoolean) pdfObject3, (PdfBoolean) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (pdfObject4 instanceof PdfLiteral) {
if (!compareLiteralsExtended((PdfLiteral) pdfObject3, (PdfLiteral) pdfObject4, objectPath, compareResult)) {
return false;
}
} else if (!pdfObject3.isNull() || !pdfObject4.isNull()) {
throw new UnsupportedOperationException();
}
return true;
}
public boolean compareDictionaries(PdfDictionary pdfDictionary, PdfDictionary pdfDictionary2) throws IOException {
return compareDictionariesExtended(pdfDictionary, pdfDictionary2, null, null);
}
private boolean compareDictionariesExtended(com.itextpdf.text.pdf.PdfDictionary r17, com.itextpdf.text.pdf.PdfDictionary r18, com.itextpdf.testutils.CompareTool.ObjectPath r19, com.itextpdf.testutils.CompareTool.CompareResult r20) throws java.io.IOException {
throw new UnsupportedOperationException("Method not decompiled: com.itextpdf.testutils.CompareTool.compareDictionariesExtended(com.itextpdf.text.pdf.PdfDictionary, com.itextpdf.text.pdf.PdfDictionary, com.itextpdf.testutils.CompareTool$ObjectPath, com.itextpdf.testutils.CompareTool$CompareResult):boolean");
}
public boolean compareContentStreamsByParsing(PdfObject pdfObject, PdfObject pdfObject2) throws IOException {
return compareContentStreamsByParsingExtended(pdfObject, pdfObject2, null, null, null, null);
}
public boolean compareContentStreamsByParsing(PdfObject pdfObject, PdfObject pdfObject2, PdfDictionary pdfDictionary, PdfDictionary pdfDictionary2) throws IOException {
return compareContentStreamsByParsingExtended(pdfObject, pdfObject2, pdfDictionary, pdfDictionary2, null, null);
}
private boolean compareContentStreamsByParsingExtended(PdfObject pdfObject, PdfObject pdfObject2, PdfDictionary pdfDictionary, PdfDictionary pdfDictionary2, ObjectPath objectPath, CompareResult compareResult) throws IOException {
int i = 2;
if (pdfObject.type() != pdfObject.type()) {
compareResult.addError(objectPath, String.format("PdfObject. Types are different. Expected: %s. Found: %s", Integer.valueOf(pdfObject2.type()), Integer.valueOf(pdfObject.type())));
return false;
}
if (pdfObject.isArray()) {
PdfArray pdfArray = (PdfArray) pdfObject;
PdfArray pdfArray2 = (PdfArray) pdfObject2;
if (pdfArray2.size() != pdfArray.size()) {
compareResult.addError(objectPath, String.format("PdfArray. Sizes are different. Expected: %s. Found: %s", Integer.valueOf(pdfArray2.size()), Integer.valueOf(pdfArray.size())));
return false;
}
for (int i2 = 0; i2 < pdfArray2.size(); i2++) {
if (!compareContentStreamsByParsingExtended(pdfArray.getPdfObject(i2), pdfArray2.getPdfObject(i2), pdfDictionary, pdfDictionary2, objectPath, compareResult)) {
return false;
}
}
}
PRTokeniser pRTokeniser = new PRTokeniser(new RandomAccessFileOrArray(new RandomAccessSourceFactory().createSource(ContentByteUtils.getContentBytesFromContentObject(pdfObject2))));
PRTokeniser pRTokeniser2 = new PRTokeniser(new RandomAccessFileOrArray(new RandomAccessSourceFactory().createSource(ContentByteUtils.getContentBytesFromContentObject(pdfObject))));
PdfContentParser pdfContentParser = new PdfContentParser(pRTokeniser);
PdfContentParser pdfContentParser2 = new PdfContentParser(pRTokeniser2);
ArrayList<PdfObject> arrayList = new ArrayList<>();
ArrayList<PdfObject> arrayList2 = new ArrayList<>();
PdfDictionary pdfDictionary3 = pdfDictionary;
PdfDictionary pdfDictionary4 = pdfDictionary2;
while (pdfContentParser.parse(arrayList).size() > 0) {
pdfContentParser2.parse(arrayList2);
if (arrayList.size() != arrayList2.size()) {
Object[] objArr = new Object[i];
objArr[0] = Integer.valueOf(arrayList.size());
objArr[1] = Integer.valueOf(arrayList2.size());
compareResult.addError(objectPath, String.format("PdfObject. Different commands lengths. Expected: %s. Found: %s", objArr));
return false;
}
if (arrayList.size() == 1 && compareLiterals((PdfLiteral) arrayList.get(0), new PdfLiteral("BI")) && compareLiterals((PdfLiteral) arrayList2.get(0), new PdfLiteral("BI"))) {
PRStream pRStream = (PRStream) pdfObject2;
PRStream pRStream2 = (PRStream) pdfObject;
if (pRStream2.getDirectObject(PdfName.RESOURCES) != null && pRStream.getDirectObject(PdfName.RESOURCES) != null) {
pdfDictionary3 = (PdfDictionary) pRStream2.getDirectObject(PdfName.RESOURCES);
pdfDictionary4 = (PdfDictionary) pRStream.getDirectObject(PdfName.RESOURCES);
}
PdfDictionary pdfDictionary5 = pdfDictionary3;
PdfDictionary pdfDictionary6 = pdfDictionary4;
ArrayList<PdfObject> arrayList3 = arrayList2;
if (!compareInlineImagesExtended(pdfContentParser2, pdfContentParser, pdfDictionary5, pdfDictionary6, objectPath, compareResult)) {
return false;
}
arrayList2 = arrayList3;
pdfDictionary3 = pdfDictionary5;
pdfDictionary4 = pdfDictionary6;
} else {
ArrayList<PdfObject> arrayList4 = arrayList2;
for (int i3 = 0; i3 < arrayList.size(); i3++) {
if (!compareObjects(arrayList4.get(i3), arrayList.get(i3), objectPath, compareResult)) {
return false;
}
}
arrayList2 = arrayList4;
}
i = 2;
}
return true;
}
private boolean compareInlineImagesExtended(PdfContentParser pdfContentParser, PdfContentParser pdfContentParser2, PdfDictionary pdfDictionary, PdfDictionary pdfDictionary2, ObjectPath objectPath, CompareResult compareResult) throws IOException {
InlineImageInfo parseInlineImage = InlineImageUtils.parseInlineImage(pdfContentParser2, pdfDictionary2);
InlineImageInfo parseInlineImage2 = InlineImageUtils.parseInlineImage(pdfContentParser, pdfDictionary);
return compareObjects(parseInlineImage2.getImageDictionary(), parseInlineImage.getImageDictionary(), objectPath, compareResult) && Arrays.equals(parseInlineImage2.getSamples(), parseInlineImage.getSamples());
}
public boolean compareStreams(PRStream pRStream, PRStream pRStream2) throws IOException {
return compareStreamsExtended(pRStream, pRStream2, null, null);
}
private boolean compareStreamsExtended(PRStream pRStream, PRStream pRStream2, ObjectPath objectPath, CompareResult compareResult) throws IOException {
boolean equals = PdfName.FLATEDECODE.equals(pRStream.get(PdfName.FILTER));
byte[] streamBytesRaw = PdfReader.getStreamBytesRaw(pRStream);
byte[] streamBytesRaw2 = PdfReader.getStreamBytesRaw(pRStream2);
if (equals) {
streamBytesRaw = PdfReader.decodeBytes(streamBytesRaw, pRStream);
streamBytesRaw2 = PdfReader.decodeBytes(streamBytesRaw2, pRStream2);
}
if (this.floatComparisonError != 0.0d && PdfName.XOBJECT.equals(pRStream2.getDirectObject(PdfName.TYPE)) && PdfName.XOBJECT.equals(pRStream.getDirectObject(PdfName.TYPE)) && PdfName.FORM.equals(pRStream2.getDirectObject(PdfName.SUBTYPE)) && PdfName.FORM.equals(pRStream.getDirectObject(PdfName.SUBTYPE))) {
return compareContentStreamsByParsingExtended(pRStream, pRStream2, pRStream.getAsDict(PdfName.RESOURCES), pRStream2.getAsDict(PdfName.RESOURCES), objectPath, compareResult) && compareDictionariesExtended(pRStream, pRStream2, objectPath, compareResult);
}
if (Arrays.equals(streamBytesRaw, streamBytesRaw2)) {
return compareDictionariesExtended(pRStream, pRStream2, objectPath, compareResult);
}
if (streamBytesRaw2.length == streamBytesRaw.length) {
for (int i = 0; i < streamBytesRaw2.length; i++) {
if (streamBytesRaw2[i] != streamBytesRaw[i]) {
int max = Math.max(0, i - 10);
int min = Math.min(streamBytesRaw2.length, i + 10);
if (compareResult != null && objectPath != null) {
objectPath.pushOffsetToPath(i);
int i2 = min - max;
compareResult.addError(objectPath, String.format("PRStream. The bytes differ at index %s. Expected: %s (%s). Found: %s (%s)", Integer.valueOf(i), new String(new byte[]{streamBytesRaw2[i]}), new String(streamBytesRaw2, max, i2).replaceAll("\\n", "\\\\n"), new String(new byte[]{streamBytesRaw[i]}), new String(streamBytesRaw, max, i2).replaceAll("\\n", "\\\\n")));
objectPath.pop();
}
}
}
} else if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PRStream. Lengths are different. Expected: %s. Found: %s", Integer.valueOf(streamBytesRaw2.length), Integer.valueOf(streamBytesRaw.length)));
}
return false;
}
public boolean compareArrays(PdfArray pdfArray, PdfArray pdfArray2) throws IOException {
return compareArraysExtended(pdfArray, pdfArray2, null, null);
}
private boolean compareArraysExtended(PdfArray pdfArray, PdfArray pdfArray2, ObjectPath objectPath, CompareResult compareResult) throws IOException {
if (pdfArray == null) {
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, "Found null. Expected PdfArray.");
}
return false;
}
if (pdfArray.size() != pdfArray2.size()) {
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfArrays. Lengths are different. Expected: %s. Found: %s.", Integer.valueOf(pdfArray2.size()), Integer.valueOf(pdfArray.size())));
}
return false;
}
boolean z = true;
for (int i = 0; i < pdfArray2.size(); i++) {
if (objectPath != null) {
objectPath.pushArrayItemToPath(i);
}
z = compareObjects(pdfArray.getPdfObject(i), pdfArray2.getPdfObject(i), objectPath, compareResult) && z;
if (objectPath != null) {
objectPath.pop();
}
if (!z && (objectPath == null || compareResult == null || compareResult.isMessageLimitReached())) {
return false;
}
}
return z;
}
public boolean compareNames(PdfName pdfName, PdfName pdfName2) {
return pdfName2.compareTo(pdfName) == 0;
}
private boolean compareNamesExtended(PdfName pdfName, PdfName pdfName2, ObjectPath objectPath, CompareResult compareResult) {
if (pdfName2.compareTo(pdfName) == 0) {
return true;
}
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfName. Expected: %s. Found: %s", pdfName2.toString(), pdfName.toString()));
}
return false;
}
public boolean compareNumbers(PdfNumber pdfNumber, PdfNumber pdfNumber2) {
double abs = Math.abs(pdfNumber.doubleValue() - pdfNumber2.doubleValue());
if (!this.absoluteError && pdfNumber2.doubleValue() != 0.0d) {
abs /= pdfNumber2.doubleValue();
}
return abs <= this.floatComparisonError;
}
private boolean compareNumbersExtended(PdfNumber pdfNumber, PdfNumber pdfNumber2, ObjectPath objectPath, CompareResult compareResult) {
if (compareNumbers(pdfNumber, pdfNumber2)) {
return true;
}
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfNumber. Expected: %s. Found: %s", pdfNumber2, pdfNumber));
}
return false;
}
public boolean compareStrings(PdfString pdfString, PdfString pdfString2) {
return Arrays.equals(pdfString2.getBytes(), pdfString.getBytes());
}
private boolean compareStringsExtended(PdfString pdfString, PdfString pdfString2, ObjectPath objectPath, CompareResult compareResult) {
if (Arrays.equals(pdfString2.getBytes(), pdfString.getBytes())) {
return true;
}
String unicodeString = pdfString2.toUnicodeString();
String unicodeString2 = pdfString.toUnicodeString();
if (unicodeString.length() == unicodeString2.length()) {
int i = 0;
while (true) {
if (i >= unicodeString.length()) {
break;
}
if (unicodeString.charAt(i) != unicodeString2.charAt(i)) {
int max = Math.max(0, i - 10);
int min = Math.min(unicodeString.length(), i + 10);
if (compareResult != null && objectPath != null) {
objectPath.pushOffsetToPath(i);
compareResult.addError(objectPath, String.format("PdfString. Characters differ at position %s. Expected: %s (%s). Found: %s (%s).", Integer.valueOf(i), Character.toString(unicodeString.charAt(i)), unicodeString.substring(max, min).replace("\n", "\\n"), Character.toString(unicodeString2.charAt(i)), unicodeString2.substring(max, min).replace("\n", "\\n")));
objectPath.pop();
}
} else {
i++;
}
}
} else if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfString. Lengths are different. Expected: %s. Found: %s", Integer.valueOf(unicodeString.length()), Integer.valueOf(unicodeString2.length())));
}
return false;
}
public boolean compareLiterals(PdfLiteral pdfLiteral, PdfLiteral pdfLiteral2) {
return Arrays.equals(pdfLiteral2.getBytes(), pdfLiteral.getBytes());
}
private boolean compareLiteralsExtended(PdfLiteral pdfLiteral, PdfLiteral pdfLiteral2, ObjectPath objectPath, CompareResult compareResult) {
if (compareLiterals(pdfLiteral, pdfLiteral2)) {
return true;
}
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfLiteral. Expected: %s. Found: %s", pdfLiteral2, pdfLiteral));
}
return false;
}
public boolean compareBooleans(PdfBoolean pdfBoolean, PdfBoolean pdfBoolean2) {
return Arrays.equals(pdfBoolean2.getBytes(), pdfBoolean.getBytes());
}
private boolean compareBooleansExtended(PdfBoolean pdfBoolean, PdfBoolean pdfBoolean2, ObjectPath objectPath, CompareResult compareResult) {
if (pdfBoolean2.booleanValue() == pdfBoolean.booleanValue()) {
return true;
}
if (compareResult != null && objectPath != null) {
compareResult.addError(objectPath, String.format("PdfBoolean. Expected: %s. Found: %s.", Boolean.valueOf(pdfBoolean2.booleanValue()), Boolean.valueOf(pdfBoolean.booleanValue())));
}
return false;
}
public String compareXmp(byte[] bArr, byte[] bArr2) {
return compareXmp(bArr, bArr2, false);
}
public String compareXmp(byte[] bArr, byte[] bArr2, boolean z) {
if (z) {
try {
XMPMeta parseFromBuffer = XMPMetaFactory.parseFromBuffer(bArr);
XMPUtils.removeProperties(parseFromBuffer, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.CREATEDATE, true, true);
XMPUtils.removeProperties(parseFromBuffer, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.MODIFYDATE, true, true);
XMPUtils.removeProperties(parseFromBuffer, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.METADATADATE, true, true);
XMPUtils.removeProperties(parseFromBuffer, "http://ns.adobe.com/pdf/1.3/", PdfProperties.PRODUCER, true, true);
bArr = XMPMetaFactory.serializeToBuffer(parseFromBuffer, new SerializeOptions(8192));
XMPMeta parseFromBuffer2 = XMPMetaFactory.parseFromBuffer(bArr2);
XMPUtils.removeProperties(parseFromBuffer2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.CREATEDATE, true, true);
XMPUtils.removeProperties(parseFromBuffer2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.MODIFYDATE, true, true);
XMPUtils.removeProperties(parseFromBuffer2, "http://ns.adobe.com/xap/1.0/", XmpBasicProperties.METADATADATE, true, true);
XMPUtils.removeProperties(parseFromBuffer2, "http://ns.adobe.com/pdf/1.3/", PdfProperties.PRODUCER, true, true);
bArr2 = XMPMetaFactory.serializeToBuffer(parseFromBuffer2, new SerializeOptions(8192));
} catch (XMPException | IOException | ParserConfigurationException | SAXException unused) {
return "XMP parsing failure!";
}
}
if (compareXmls(bArr, bArr2)) {
return null;
}
return "The XMP packages different!";
}
public String compareXmp(String str, String str2) {
return compareXmp(str, str2, false);
}
public String compareXmp(String str, String str2, boolean z) {
PdfReader pdfReader;
Throwable th;
PdfReader pdfReader2;
init(str, str2);
PdfReader pdfReader3 = null;
try {
pdfReader2 = new PdfReader(this.cmpPdf);
try {
pdfReader = new PdfReader(this.outPdf);
try {
String compareXmp = compareXmp(pdfReader2.getMetadata(), pdfReader.getMetadata(), z);
pdfReader2.close();
pdfReader.close();
return compareXmp;
} catch (IOException unused) {
pdfReader3 = pdfReader2;
if (pdfReader3 != null) {
pdfReader3.close();
}
if (pdfReader != null) {
pdfReader.close();
}
return "XMP parsing failure!";
} catch (Throwable th2) {
th = th2;
if (pdfReader2 != null) {
pdfReader2.close();
}
if (pdfReader != null) {
pdfReader.close();
}
throw th;
}
} catch (IOException unused2) {
pdfReader = null;
} catch (Throwable th3) {
pdfReader = null;
th = th3;
}
} catch (IOException unused3) {
pdfReader = null;
} catch (Throwable th4) {
pdfReader = null;
th = th4;
pdfReader2 = null;
}
}
public boolean compareXmls(byte[] bArr, byte[] bArr2) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance();
newInstance.setNamespaceAware(true);
newInstance.setCoalescing(true);
newInstance.setIgnoringElementContentWhitespace(true);
newInstance.setIgnoringComments(true);
DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder();
Document parse = newDocumentBuilder.parse(new ByteArrayInputStream(bArr));
parse.normalizeDocument();
Document parse2 = newDocumentBuilder.parse(new ByteArrayInputStream(bArr2));
parse2.normalizeDocument();
return parse2.isEqualNode(parse);
}
public String compareDocumentInfo(String str, String str2) throws IOException {
String str3;
System.out.print("[itext] INFO Comparing document info.......");
PdfReader pdfReader = new PdfReader(str);
PdfReader pdfReader2 = new PdfReader(str2);
String[] convertInfo = convertInfo(pdfReader2.getInfo());
String[] convertInfo2 = convertInfo(pdfReader.getInfo());
int i = 0;
while (true) {
if (i >= convertInfo.length) {
str3 = null;
break;
}
if (!convertInfo[i].equals(convertInfo2[i])) {
str3 = "Document info fail";
break;
}
i++;
}
pdfReader.close();
pdfReader2.close();
if (str3 == null) {
System.out.println("OK");
} else {
System.out.println("Fail");
}
System.out.flush();
return str3;
}
private boolean linksAreSame(PdfAnnotation.PdfImportedLink pdfImportedLink, PdfAnnotation.PdfImportedLink pdfImportedLink2) {
if (pdfImportedLink.getDestinationPage() != pdfImportedLink2.getDestinationPage() || !pdfImportedLink.getRect().toString().equals(pdfImportedLink2.getRect().toString())) {
return false;
}
Map<PdfName, PdfObject> parameters = pdfImportedLink.getParameters();
Map<PdfName, PdfObject> parameters2 = pdfImportedLink2.getParameters();
if (parameters.size() != parameters2.size()) {
return false;
}
for (Map.Entry<PdfName, PdfObject> entry : parameters.entrySet()) {
PdfObject value = entry.getValue();
if (!parameters2.containsKey(entry.getKey())) {
return false;
}
PdfObject pdfObject = parameters2.get(entry.getKey());
if (value.type() != pdfObject.type()) {
return false;
}
int type = value.type();
if (type == 1 || type == 2 || type == 3 || type == 4 || type == 8) {
if (!value.toString().equals(pdfObject.toString())) {
return false;
}
}
}
return true;
}
public String compareLinks(String str, String str2) throws IOException {
System.out.print("[itext] INFO Comparing link annotations....");
PdfReader pdfReader = new PdfReader(str);
PdfReader pdfReader2 = new PdfReader(str2);
String str3 = null;
int i = 0;
while (true) {
if (i >= pdfReader.getNumberOfPages() || i >= pdfReader2.getNumberOfPages()) {
break;
}
i++;
ArrayList<PdfAnnotation.PdfImportedLink> links = pdfReader.getLinks(i);
ArrayList<PdfAnnotation.PdfImportedLink> links2 = pdfReader2.getLinks(i);
if (links2.size() != links.size()) {
str3 = String.format("Different number of links on page %d.", Integer.valueOf(i));
break;
}
int i2 = 0;
while (true) {
if (i2 >= links2.size()) {
break;
}
if (!linksAreSame(links2.get(i2), links.get(i2))) {
str3 = String.format("Different links on page %d.\n%s\n%s", Integer.valueOf(i), links2.get(i2).toString(), links.get(i2).toString());
break;
}
i2++;
}
}
pdfReader.close();
pdfReader2.close();
if (str3 == null) {
System.out.println("OK");
} else {
System.out.println("Fail");
}
System.out.flush();
return str3;
}
public String compareTagStructures(String str, String str2) throws IOException, ParserConfigurationException, SAXException {
System.out.print("[itext] INFO Comparing tag structures......");
String replace = str.replace(".pdf", ".xml");
String replace2 = str.replace(".pdf", ".cmp.xml");
PdfReader pdfReader = new PdfReader(str);
FileOutputStream fileOutputStream = new FileOutputStream(replace);
new CmpTaggedPdfReaderTool().convertToXml(pdfReader, fileOutputStream);
pdfReader.close();
PdfReader pdfReader2 = new PdfReader(str2);
FileOutputStream fileOutputStream2 = new FileOutputStream(replace2);
new CmpTaggedPdfReaderTool().convertToXml(pdfReader2, fileOutputStream2);
pdfReader2.close();
String str3 = !compareXmls(replace, replace2) ? "The tag structures are different." : null;
fileOutputStream.close();
fileOutputStream2.close();
if (str3 == null) {
System.out.println("OK");
} else {
System.out.println("Fail");
}
System.out.flush();
return str3;
}
private String[] convertInfo(HashMap<String, String> hashMap) {
String[] strArr = {"", "", "", ""};
for (Map.Entry<String, String> entry : hashMap.entrySet()) {
if ("title".equalsIgnoreCase(entry.getKey())) {
strArr[0] = entry.getValue();
} else if (Meta.AUTHOR.equalsIgnoreCase(entry.getKey())) {
strArr[1] = entry.getValue();
} else if ("subject".equalsIgnoreCase(entry.getKey())) {
strArr[2] = entry.getValue();
} else if (Meta.KEYWORDS.equalsIgnoreCase(entry.getKey())) {
strArr[3] = entry.getValue();
}
}
return strArr;
}
public boolean compareXmls(String str, String str2) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance();
newInstance.setNamespaceAware(true);
newInstance.setCoalescing(true);
newInstance.setIgnoringElementContentWhitespace(true);
newInstance.setIgnoringComments(true);
DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder();
Document parse = newDocumentBuilder.parse(new File(str));
parse.normalizeDocument();
Document parse2 = newDocumentBuilder.parse(new File(str2));
parse2.normalizeDocument();
return parse2.isEqualNode(parse);
}
private void init(String str, String str2) {
this.outPdf = str;
this.cmpPdf = str2;
this.outPdfName = new File(str).getName();
this.cmpPdfName = new File(str2).getName();
this.outImage = this.outPdfName + "-%03d.png";
if (this.cmpPdfName.startsWith("cmp_")) {
this.cmpImage = this.cmpPdfName + "-%03d.png";
return;
}
this.cmpImage = "cmp_" + this.cmpPdfName + "-%03d.png";
}
private boolean compareStreams(InputStream inputStream, InputStream inputStream2) throws IOException {
int read;
byte[] bArr = new byte[65536];
byte[] bArr2 = new byte[65536];
do {
read = inputStream.read(bArr);
if (read != inputStream2.read(bArr2) || !Arrays.equals(bArr, bArr2)) {
return false;
}
} while (read != -1);
return true;
}
class PngFileFilter implements FileFilter {
PngFileFilter() {
}
@Override
public boolean accept(File file) {
String absolutePath = file.getAbsolutePath();
return absolutePath.endsWith(".png") && !absolutePath.contains("cmp_") && absolutePath.contains(CompareTool.this.outPdfName);
}
}
class CmpPngFileFilter implements FileFilter {
CmpPngFileFilter() {
}
@Override
public boolean accept(File file) {
String absolutePath = file.getAbsolutePath();
return absolutePath.endsWith(".png") && absolutePath.contains("cmp_") && absolutePath.contains(CompareTool.this.cmpPdfName);
}
}
class ImageNameComparator implements Comparator<File> {
ImageNameComparator() {
}
@Override
public int compare(File file, File file2) {
return file.getAbsolutePath().compareTo(file2.getAbsolutePath());
}
}
class CmpTaggedPdfReaderTool extends TaggedPdfReaderTool {
Map<PdfDictionary, Map<Integer, String>> parsedTags = new HashMap();
CmpTaggedPdfReaderTool() {
}
@Override
public void parseTag(String str, PdfObject pdfObject, PdfDictionary pdfDictionary) throws IOException {
if (pdfObject instanceof PdfNumber) {
if (!this.parsedTags.containsKey(pdfDictionary)) {
CmpMarkedContentRenderFilter cmpMarkedContentRenderFilter = CompareTool.this.new CmpMarkedContentRenderFilter();
new PdfContentStreamProcessor(cmpMarkedContentRenderFilter).processContent(PdfReader.getPageContent(pdfDictionary), pdfDictionary.getAsDict(PdfName.RESOURCES));
this.parsedTags.put(pdfDictionary, cmpMarkedContentRenderFilter.getParsedTagContent());
}
PdfNumber pdfNumber = (PdfNumber) pdfObject;
this.out.print(XMLUtil.escapeXML(this.parsedTags.get(pdfDictionary).containsKey(Integer.valueOf(pdfNumber.intValue())) ? this.parsedTags.get(pdfDictionary).get(Integer.valueOf(pdfNumber.intValue())) : "", true));
return;
}
super.parseTag(str, pdfObject, pdfDictionary);
}
@Override
public void inspectChildDictionary(PdfDictionary pdfDictionary) throws IOException {
inspectChildDictionary(pdfDictionary, true);
}
}
class CmpMarkedContentRenderFilter implements RenderListener {
Map<Integer, TextExtractionStrategy> tagsByMcid = new HashMap();
@Override
public void renderImage(ImageRenderInfo imageRenderInfo) {
}
CmpMarkedContentRenderFilter() {
}
public Map<Integer, String> getParsedTagContent() {
HashMap hashMap = new HashMap();
Iterator<Integer> it = this.tagsByMcid.keySet().iterator();
while (it.hasNext()) {
int intValue = it.next().intValue();
hashMap.put(Integer.valueOf(intValue), this.tagsByMcid.get(Integer.valueOf(intValue)).getResultantText());
}
return hashMap;
}
@Override
public void beginTextBlock() {
Iterator<Integer> it = this.tagsByMcid.keySet().iterator();
while (it.hasNext()) {
this.tagsByMcid.get(Integer.valueOf(it.next().intValue())).beginTextBlock();
}
}
@Override
public void renderText(TextRenderInfo textRenderInfo) {
Integer mcid = textRenderInfo.getMcid();
if (mcid != null && this.tagsByMcid.containsKey(mcid)) {
this.tagsByMcid.get(mcid).renderText(textRenderInfo);
} else if (mcid != null) {
this.tagsByMcid.put(mcid, new SimpleTextExtractionStrategy());
this.tagsByMcid.get(mcid).renderText(textRenderInfo);
}
}
@Override
public void endTextBlock() {
Iterator<Integer> it = this.tagsByMcid.keySet().iterator();
while (it.hasNext()) {
this.tagsByMcid.get(Integer.valueOf(it.next().intValue())).endTextBlock();
}
}
}
}