From 7d2f38056a75c13ffe29e2fd3d820657c4c61ae5 Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Fri, 3 Feb 2023 13:36:21 +0100 Subject: [PATCH 1/8] Pruned changes down to Minimal required set. Branch is dependant on changes to core mentioned in: RES-725 Signed-off-by: Nick Boyd --- .../itextpdf/rups/shims/RupsPdfString.java | 39 +++++++++++++++++++ .../contextmenu/CopyToClipboardAction.java | 31 +++++++++++---- .../view/contextmenu/PdfTreeContextMenu.java | 4 ++ .../itext/treenodes/PdfObjectTreeNode.java | 11 ++++++ 4 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/itextpdf/rups/shims/RupsPdfString.java diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java new file mode 100644 index 00000000..83e1b42b --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -0,0 +1,39 @@ +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.pdf.PdfString; + +public class RupsPdfString extends PdfString { + public RupsPdfString(String value, String encoding) { + super(value, encoding); + } + + public RupsPdfString(String value) { + super(value); + } + + public RupsPdfString(byte[] content) { + super(content); + } + + public RupsPdfString(PdfString unpatchedPdfString){ + this(unpatchedPdfString.getValueBytes()); + this.setHexWriting(unpatchedPdfString.isHexWriting()); + this.encoding = unpatchedPdfString.getEncoding(); + this.directOnly = !unpatchedPdfString.isIndirect(); + this.indirectReference = unpatchedPdfString.getIndirectReference(); + } + + protected RupsPdfString(byte[] content, boolean hexWriting) { + super(content, hexWriting); + } + + @Override + public String toString() { + String wrapper; + if(isHexWriting()) + wrapper = "<%s>"; + else + wrapper = "(%s)"; + return String.format(wrapper, getValue()); + } +} diff --git a/src/main/java/com/itextpdf/rups/view/contextmenu/CopyToClipboardAction.java b/src/main/java/com/itextpdf/rups/view/contextmenu/CopyToClipboardAction.java index d98e6093..3ea7172a 100644 --- a/src/main/java/com/itextpdf/rups/view/contextmenu/CopyToClipboardAction.java +++ b/src/main/java/com/itextpdf/rups/view/contextmenu/CopyToClipboardAction.java @@ -42,8 +42,14 @@ This file is part of the iText (R) project. */ package com.itextpdf.rups.view.contextmenu; +import com.itextpdf.rups.view.itext.PdfTree; +import com.itextpdf.rups.view.itext.treenodes.PdfObjectTreeNode; + import javax.swing.JTextPane; import java.awt.Component; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; /** @@ -54,23 +60,32 @@ This file is part of the iText (R) project. public class CopyToClipboardAction extends AbstractRupsAction { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + public CopyToClipboardAction(String name, Component invoker) { super(name, invoker); } public void actionPerformed(ActionEvent e) { boolean nothingSelected = false; - JTextPane textPane = (JTextPane) invoker; + + if (invoker instanceof JTextPane) { + JTextPane textPane = (JTextPane) invoker; - if (textPane.getSelectedText() == null || textPane.getSelectedText().trim().length() == 0) { - nothingSelected = true; - textPane.selectAll(); - } + if (textPane.getSelectedText() == null || textPane.getSelectedText().trim().length() == 0) { + nothingSelected = true; + textPane.selectAll(); + } - textPane.copy(); + textPane.copy(); - if (nothingSelected) { - textPane.select(0, 0); + if (nothingSelected) { + textPane.select(0, 0); + } + } else if (invoker instanceof PdfTree) { + PdfTree tree = (PdfTree) invoker; + PdfObjectTreeNode selectionNode = (PdfObjectTreeNode) tree.getSelectionPath().getLastPathComponent(); + clipboard.setContents(new StringSelection(selectionNode.getPdfObject().toString()), null); } } } diff --git a/src/main/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenu.java b/src/main/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenu.java index a00cabd4..88b7ac0b 100644 --- a/src/main/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenu.java +++ b/src/main/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenu.java @@ -67,6 +67,10 @@ public static JPopupMenu getPopupMenu(Component component) { new SaveToFilePdfTreeAction(Language.SAVE_RAW_BYTES_TO_FILE.getString(), component, true) )); + popup.add(getJMenuItem( + new CopyToClipboardAction(Language.COPY_TO_CLIPBOARD.getString(), component) + )); + popup.add(getJMenuItem( new SaveToFilePdfTreeAction(Language.SAVE_TO_FILE.getString(), component, false) )); diff --git a/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java b/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java index 86ada289..17f3a2b2 100644 --- a/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java +++ b/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java @@ -48,6 +48,7 @@ This file is part of the iText (R) project. import com.itextpdf.kernel.pdf.PdfObject; import com.itextpdf.kernel.pdf.PdfString; import com.itextpdf.rups.model.LoggerHelper; +import com.itextpdf.rups.shims.RupsPdfString; import com.itextpdf.rups.view.Language; import com.itextpdf.rups.view.icons.IconFetcher; import com.itextpdf.rups.view.icons.IconTreeNode; @@ -132,6 +133,8 @@ protected PdfObjectTreeNode(PdfObject object) { break; case PdfObject.STRING: icon = IconFetcher.getIcon(STRING_ICON); + // Patch to normalise PdfString's toString() behaviour with the remainder of iText's serialization. + this.object = new RupsPdfString((PdfString) object); break; } } @@ -398,4 +401,12 @@ public PdfName getPdfDictionaryType() { } return null; } + + /** + * Returns the Key that forms the node's final path component. + * @return a {@link PdfName} object or {@code null} + */ + public PdfName getKey() { + return key; + } } From 4c06c93ca7b5aa060414664c30552629149c14e3 Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Mon, 6 Feb 2023 10:52:35 +0100 Subject: [PATCH 2/8] Implemented tests for Tree Popup Menu and Shim UI and Content integration tests still to be implemented. Signed-off-by: Nick Boyd --- .../rups/shims/RupsPdfStringTest.java | 17 +++++++ .../contextmenu/PdfTreeContextMenuTest.java | 47 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java create mode 100644 src/test/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenuTest.java diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java new file mode 100644 index 00000000..a1dcdeb1 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -0,0 +1,17 @@ +package com.itextpdf.rups.shims; + +import com.itextpdf.test.annotations.type.UnitTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(UnitTest.class) +public class RupsPdfStringTest { + + @Test + public void toStringBasicTest() { + RupsPdfString pdfString = new RupsPdfString("Test"); + + Assert.assertEquals("String is () Delimited.","(Test)", pdfString.toString()); + } +} diff --git a/src/test/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenuTest.java b/src/test/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenuTest.java new file mode 100644 index 00000000..49b61ec1 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/view/contextmenu/PdfTreeContextMenuTest.java @@ -0,0 +1,47 @@ +package com.itextpdf.rups.view.contextmenu; + +import com.itextpdf.test.annotations.type.UnitTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.MenuElement; +import java.util.Arrays; + +@Category(UnitTest.class) +public class PdfTreeContextMenuTest { + + @Test + public void jMenuLengthTest() { + JPopupMenu popupMenu = PdfTreeContextMenu.getPopupMenu(null); + + MenuElement[] subElements = popupMenu.getSubElements(); + Assert.assertEquals(4, subElements.length); + } + + @Test + public void jMenuSubItemTypeTest() { + JPopupMenu popupMenu = PdfTreeContextMenu.getPopupMenu(null); + + MenuElement[] subElements = popupMenu.getSubElements(); + + Assert.assertTrue(Arrays.stream(subElements).allMatch(menuElement -> menuElement instanceof JMenuItem)); + } + + @Test + public void assignedActionsTest() { + JPopupMenu popupMenu = PdfTreeContextMenu.getPopupMenu(null); + + MenuElement[] subElements = popupMenu.getSubElements(); + + Assert.assertTrue(Arrays.stream(subElements).anyMatch(element -> ((JMenuItem) element).getAction() instanceof InspectObjectAction)); + + Assert.assertTrue(Arrays.stream(subElements).anyMatch(element -> ((JMenuItem) element).getAction() instanceof SaveToFilePdfTreeAction)); + + Assert.assertTrue(Arrays.stream(subElements).anyMatch(element -> ((JMenuItem) element).getAction() instanceof CopyToClipboardAction)); + + Assert.assertTrue(Arrays.stream(subElements).anyMatch(element -> ((JMenuItem) element).getAction() instanceof SaveToFilePdfTreeAction)); + } +} From bf5c1bc81a009c7ecb2d365fadea29e3252ffdd7 Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Mon, 6 Feb 2023 14:57:40 +0100 Subject: [PATCH 3/8] RupsPdfString.toString() modified to correctly encode Hex, Tests Added Signed-off-by: Nick Boyd --- .../com/itextpdf/rups/shims/RupsPdfString.java | 2 +- .../itextpdf/rups/shims/RupsPdfStringTest.java | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java index 83e1b42b..270a7579 100644 --- a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -34,6 +34,6 @@ public String toString() { wrapper = "<%s>"; else wrapper = "(%s)"; - return String.format(wrapper, getValue()); + return String.format(wrapper, new String(encodeBytes(getValueBytes()))); } } diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java index a1dcdeb1..bfabac9b 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -12,6 +12,22 @@ public class RupsPdfStringTest { public void toStringBasicTest() { RupsPdfString pdfString = new RupsPdfString("Test"); - Assert.assertEquals("String is () Delimited.","(Test)", pdfString.toString()); + Assert.assertEquals("String is () Delimited.", "(Test)", pdfString.toString()); + } + + @Test + public void toStringHexTest() { + byte[] hexArray = "Test".getBytes(); + StringBuilder hexString = new StringBuilder("<"); + for (byte b : hexArray) { + hexString.append(Integer.toHexString(b)); + } + hexString.append(">"); + + RupsPdfString pdfString = new RupsPdfString(hexArray); + pdfString.setHexWriting(true); + + Assert.assertEquals("String is <> Delimited.", hexString.toString(), pdfString.toString()); } } + From bde7013e97927ab1b1446ac064f81d81fe634335 Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Mon, 6 Feb 2023 15:40:50 +0100 Subject: [PATCH 4/8] RupsPdfString.toString() modified to correctly encode Hex, Tests Added Signed-off-by: Nick Boyd --- .../rups/shims/RupsPdfStringTest.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java index bfabac9b..71c6190c 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -29,5 +29,35 @@ public void toStringHexTest() { Assert.assertEquals("String is <> Delimited.", hexString.toString(), pdfString.toString()); } + + @Test + public void toStringBalancedTest(){ + String balanced = "Test (of paretheses)"; + RupsPdfString pdfString = new RupsPdfString(balanced); + Assert.assertEquals("Balanced parens are escaped:", "(Test \\(of paretheses\\))", pdfString.toString()); + // Note: This is optional, but performed this way in iText to avoid too much overhead evaluating the balance of symbols. + } + + @Test + public void toStringUnbalancedTest() { + String unbalanced = "Test :-)"; + RupsPdfString pdfString = new RupsPdfString(unbalanced); + Assert.assertEquals("Unbalanced parens are escaped:", "(Test :-\\))", pdfString.toString()); + } + + @Test + public void toStringUnbalancedTest_Two() { + String unbalanced_two = ")Test :-("; + RupsPdfString pdfString_two = new RupsPdfString(unbalanced_two); + Assert.assertEquals("Unbalanced parens are escaped:", "(\\)Test :-\\()", pdfString_two.toString()); + } + + @Test + public void toStringUnbalancedTest_Three(){ + String unbalanced_three = "@<----(( Robin Hood Test"; + RupsPdfString pdfString_three = new RupsPdfString(unbalanced_three); + Assert.assertEquals("Unbalanced parens are escaped:", "(@<----\\(\\( Robin Hood Test)", pdfString_three.toString()); + } + } From 5beb4d67fec89435a4c77a3d9d1fdc4ecdd84fb6 Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Fri, 19 May 2023 17:46:34 +0200 Subject: [PATCH 5/8] RES-725 - Added Shims for Container classes to resolve the core toString() inconsistencies Note: Dictionaries and Arrays populate the clipboard with indirect object references rather than serialized objects at the moment. This should probably be discussed futher in the future. Signed-off-by: Nick Boyd --- .../com/itextpdf/rups/shims/RupsPdfArray.java | 365 ++++++++++++++++++ .../rups/shims/RupsPdfDictionary.java | 334 ++++++++++++++++ .../itextpdf/rups/shims/RupsPdfString.java | 262 ++++++++++++- .../itextpdf/rups/shims/RupsPdfTextArray.java | 350 +++++++++++++++++ .../itext/treenodes/PdfObjectTreeNode.java | 11 + 5 files changed, 1314 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java create mode 100644 src/main/java/com/itextpdf/rups/shims/RupsPdfDictionary.java create mode 100644 src/main/java/com/itextpdf/rups/shims/RupsPdfTextArray.java diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java new file mode 100644 index 00000000..2220447f --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java @@ -0,0 +1,365 @@ +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfBoolean; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfIndirectReference; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfNumber; +import com.itextpdf.kernel.pdf.PdfObject; +import com.itextpdf.kernel.pdf.PdfStream; +import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.pdf.PdfTextArray; +import com.itextpdf.kernel.utils.ICopyFilter; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class RupsPdfArray extends PdfArray { + PdfArray original; + public RupsPdfArray(PdfArray arr) { + super(arr); + this.original = arr; + } + + @Override + public int size() { + return original.size(); + } + + @Override + public boolean isEmpty() { + return original.isEmpty(); + } + + @Override + public boolean contains(PdfObject o) { + return original.contains(o); + } + + @Override + public Iterator iterator() { + return original.iterator(); + } + + @Override + public void add(PdfObject pdfObject) { + original.add(pdfObject); + } + + @Override + public void add(int index, PdfObject element) { + original.add(index, element); + } + + @Override + public PdfObject set(int index, PdfObject element) { + return original.set(index, element); + } + + @Override + public void addAll(Collection c) { + original.addAll(c); + } + + @Override + public void addAll(PdfArray a) { + original.addAll(a); + } + + @Override + public PdfObject get(int index) { + return original.get(index); + } + + @Override + public void remove(int index) { + original.remove(index); + } + + @Override + public void remove(PdfObject o) { + original.remove(o); + } + + @Override + public void clear() { + original.clear(); + } + + @Override + public int indexOf(PdfObject o) { + return original.indexOf(o); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return original.subList(fromIndex, toIndex); + } + + @Override + public byte getType() { + return original.getType(); + } + + @Override + public String toString() { + return RupsPdfArray.getShimmedString(original); + } + + protected static String getShimmedString(PdfArray original) { + StringBuilder string = new StringBuilder(); + string.append("["); + for (PdfObject entry : original) { + string.append(RupsPdfArray.GetEntryString(entry)); + } + string.append(" "); + string.append("]"); + return string.toString(); + } + + protected static PdfObject GetEntryString(PdfObject entry) { + PdfIndirectReference indirectReference = entry.getIndirectReference(); + + if (indirectReference != null){ + return indirectReference; + } + if (entry instanceof PdfString){ + return new RupsPdfString((PdfString) entry); + } + if (entry instanceof PdfTextArray){ + return new RupsPdfTextArray((PdfTextArray) entry); + } + if (entry instanceof PdfArray){ + return new RupsPdfArray((PdfArray) entry); + } + if (entry instanceof PdfDictionary){ + return new RupsPdfDictionary((PdfDictionary) entry); + } + return entry; + } + + @Override + public PdfObject get(int index, boolean asDirect) { + return original.get(index, asDirect); + } + + @Override + public PdfArray getAsArray(int index) { + return original.getAsArray(index); + } + + @Override + public PdfDictionary getAsDictionary(int index) { + return original.getAsDictionary(index); + } + + @Override + public PdfStream getAsStream(int index) { + return original.getAsStream(index); + } + + @Override + public PdfNumber getAsNumber(int index) { + return original.getAsNumber(index); + } + + @Override + public PdfName getAsName(int index) { + return original.getAsName(index); + } + + @Override + public PdfString getAsString(int index) { + return original.getAsString(index); + } + + @Override + public PdfBoolean getAsBoolean(int index) { + return original.getAsBoolean(index); + } + + @Override + public Rectangle toRectangle() { + return original.toRectangle(); + } + + @Override + public float[] toFloatArray() { + return original.toFloatArray(); + } + + @Override + public double[] toDoubleArray() { + return original.toDoubleArray(); + } + + @Override + public long[] toLongArray() { + return original.toLongArray(); + } + + @Override + public int[] toIntArray() { + return original.toIntArray(); + } + + @Override + public boolean[] toBooleanArray() { + return original.toBooleanArray(); + } + + @Override + public PdfIndirectReference getIndirectReference() { + return original.getIndirectReference(); + } + + @Override + public boolean isIndirect() { + return original.isIndirect(); + } + + @Override + public PdfObject makeIndirect(PdfDocument document, PdfIndirectReference reference) { + return original.makeIndirect(document, reference); + } + + @Override + public PdfObject makeIndirect(PdfDocument document) { + return original.makeIndirect(document); + } + + @Override + public boolean isFlushed() { + return original.isFlushed(); + } + + @Override + public boolean isModified() { + return original.isModified(); + } + + @Override + public PdfObject clone() { + return original.clone(); + } + + @Override + public PdfObject clone(ICopyFilter filter) { + return original.clone(filter); + } + + @Override + public PdfObject copyTo(PdfDocument document) { + return original.copyTo(document); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating) { + return original.copyTo(document, allowDuplicating); + } + + @Override + public PdfObject copyTo(PdfDocument document, ICopyFilter copyFilter) { + return original.copyTo(document, copyFilter); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating, ICopyFilter copyFilter) { + return original.copyTo(document, allowDuplicating, copyFilter); + } + + @Override + public PdfObject setModified() { + return original.setModified(); + } + + @Override + public boolean isReleaseForbidden() { + return original.isReleaseForbidden(); + } + + @Override + public void release() { + original.release(); + } + + @Override + public boolean isNull() { + return original.isNull(); + } + + @Override + public boolean isBoolean() { + return original.isBoolean(); + } + + @Override + public boolean isNumber() { + return original.isNumber(); + } + + @Override + public boolean isString() { + return original.isString(); + } + + @Override + public boolean isName() { + return original.isName(); + } + + @Override + public boolean isArray() { + return original.isArray(); + } + + @Override + public boolean isDictionary() { + return original.isDictionary(); + } + + @Override + public boolean isStream() { + return original.isStream(); + } + + @Override + public boolean isIndirectReference() { + return original.isIndirectReference(); + } + + @Override + public boolean isLiteral() { + return original.isLiteral(); + } + + @Override + public void forEach(Consumer action) { + original.forEach(action); + } + + @Override + public Spliterator spliterator() { + return original.spliterator(); + } + + @Override + public int hashCode() { + return original.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PdfArray) { + return original.equals(obj); + } else { + return false; + } + } +} diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfDictionary.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfDictionary.java new file mode 100644 index 00000000..9179c234 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfDictionary.java @@ -0,0 +1,334 @@ +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfBoolean; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfIndirectReference; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfNumber; +import com.itextpdf.kernel.pdf.PdfObject; +import com.itextpdf.kernel.pdf.PdfStream; +import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.utils.ICopyFilter; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class RupsPdfDictionary extends PdfDictionary { + PdfDictionary original; + public RupsPdfDictionary(PdfDictionary dictionary) { + super(dictionary); + original = dictionary; + } + + @Override + public int size() { + return original.size(); + } + + @Override + public boolean isEmpty() { + return original.isEmpty(); + } + + @Override + public boolean containsKey(PdfName key) { + return original.containsKey(key); + } + + @Override + public boolean containsValue(PdfObject value) { + return original.containsValue(value); + } + + @Override + public PdfObject get(PdfName key) { + return original.get(key); + } + + @Override + public PdfArray getAsArray(PdfName key) { + return original.getAsArray(key); + } + + @Override + public PdfDictionary getAsDictionary(PdfName key) { + return original.getAsDictionary(key); + } + + @Override + public PdfStream getAsStream(PdfName key) { + return original.getAsStream(key); + } + + @Override + public PdfNumber getAsNumber(PdfName key) { + return original.getAsNumber(key); + } + + @Override + public PdfName getAsName(PdfName key) { + return original.getAsName(key); + } + + @Override + public PdfString getAsString(PdfName key) { + return original.getAsString(key); + } + + @Override + public PdfBoolean getAsBoolean(PdfName key) { + return original.getAsBoolean(key); + } + + @Override + public Rectangle getAsRectangle(PdfName key) { + return original.getAsRectangle(key); + } + + @Override + public Float getAsFloat(PdfName key) { + return original.getAsFloat(key); + } + + @Override + public Integer getAsInt(PdfName key) { + return original.getAsInt(key); + } + + @Override + public Boolean getAsBool(PdfName key) { + return original.getAsBool(key); + } + + @Override + public PdfObject put(PdfName key, PdfObject value) { + return original.put(key, value); + } + + @Override + public PdfObject remove(PdfName key) { + return original.remove(key); + } + + @Override + public void putAll(PdfDictionary d) { + original.putAll(d); + } + + @Override + public void clear() { + original.clear(); + } + + @Override + public Set keySet() { + return original.keySet(); + } + + @Override + public Collection values(boolean asDirects) { + return original.values(asDirects); + } + + @Override + public Collection values() { + return original.values(); + } + + @Override + public Set> entrySet() { + return original.entrySet(); + } + + @Override + public byte getType() { + return original.getType(); + } + + @Override + public String toString() { + if (!isFlushed()) { + StringBuilder string = new StringBuilder(); + string.append("<<"); + for (Map.Entry entry : original.entrySet()) { + string.append(entry.getKey().toString()); + string.append(" "); + string.append(RupsPdfArray.GetEntryString(entry.getValue())); + } + string.append(">>"); + return string.toString(); + } + return original.getIndirectReference().toString(); + + } + + @Override + public PdfDictionary clone(List excludeKeys) { + return original.clone(excludeKeys); + } + + @Override + public PdfDictionary copyTo(PdfDocument document, List excludeKeys, boolean allowDuplicating) { + return original.copyTo(document, excludeKeys, allowDuplicating); + } + + @Override + public PdfDictionary copyTo(PdfDocument document, List excludeKeys, boolean allowDuplicating, ICopyFilter copyFilter) { + return original.copyTo(document, excludeKeys, allowDuplicating, copyFilter); + } + + @Override + public PdfObject get(PdfName key, boolean asDirect) { + return original.get(key, asDirect); + } + + @Override + public void mergeDifferent(PdfDictionary other) { + original.mergeDifferent(other); + } + + @Override + public PdfIndirectReference getIndirectReference() { + return original.getIndirectReference(); + } + + @Override + public boolean isIndirect() { + return original.isIndirect(); + } + + @Override + public PdfObject makeIndirect(PdfDocument document, PdfIndirectReference reference) { + return original.makeIndirect(document, reference); + } + + @Override + public PdfObject makeIndirect(PdfDocument document) { + return original.makeIndirect(document); + } + + @Override + public boolean isFlushed() { + return original.isFlushed(); + } + + @Override + public boolean isModified() { + return original.isModified(); + } + + @Override + public PdfObject clone() { + return original.clone(); + } + + @Override + public PdfObject clone(ICopyFilter filter) { + return original.clone(filter); + } + + @Override + public PdfObject copyTo(PdfDocument document) { + return original.copyTo(document); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating) { + return original.copyTo(document, allowDuplicating); + } + + @Override + public PdfObject copyTo(PdfDocument document, ICopyFilter copyFilter) { + return original.copyTo(document, copyFilter); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating, ICopyFilter copyFilter) { + return original.copyTo(document, allowDuplicating, copyFilter); + } + + @Override + public PdfObject setModified() { + return original.setModified(); + } + + @Override + public boolean isReleaseForbidden() { + return original.isReleaseForbidden(); + } + + @Override + public void release() { + original.release(); + } + + @Override + public boolean isNull() { + return original.isNull(); + } + + @Override + public boolean isBoolean() { + return original.isBoolean(); + } + + @Override + public boolean isNumber() { + return original.isNumber(); + } + + @Override + public boolean isString() { + return original.isString(); + } + + @Override + public boolean isName() { + return original.isName(); + } + + @Override + public boolean isArray() { + return original.isArray(); + } + + @Override + public boolean isDictionary() { + return original.isDictionary(); + } + + @Override + public boolean isStream() { + return original.isStream(); + } + + @Override + public boolean isIndirectReference() { + return original.isIndirectReference(); + } + +// @Override +// protected PdfObject setIndirectReference(PdfIndirectReference indirectReference) { +// return original.setIndirectReference(indirectReference); +// } + + @Override + public boolean isLiteral() { + return original.isLiteral(); + } + + @Override + public int hashCode() { + return original.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return original.equals(obj); + } +} diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java index 270a7579..a8898b77 100644 --- a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -1,8 +1,14 @@ package com.itextpdf.rups.shims; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfIndirectReference; +import com.itextpdf.kernel.pdf.PdfObject; import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.utils.ICopyFilter; public class RupsPdfString extends PdfString { + + PdfString original; public RupsPdfString(String value, String encoding) { super(value, encoding); } @@ -15,16 +21,256 @@ public RupsPdfString(byte[] content) { super(content); } - public RupsPdfString(PdfString unpatchedPdfString){ - this(unpatchedPdfString.getValueBytes()); - this.setHexWriting(unpatchedPdfString.isHexWriting()); - this.encoding = unpatchedPdfString.getEncoding(); - this.directOnly = !unpatchedPdfString.isIndirect(); - this.indirectReference = unpatchedPdfString.getIndirectReference(); + public RupsPdfString(PdfString original){ + super(original.getValueBytes()); + this.original = original; + } + + + @Override + public byte[] getValueBytes(){ + return original.getValueBytes(); + } + @Override + public boolean isHexWriting(){ + return original.isHexWriting(); + } + @Override + public String getEncoding(){ + return original.getEncoding(); + } + @Override + public boolean isIndirect(){ + return original.isIndirect(); + } + + @Override + public byte getType() { + return original.getType(); + } + + @Override + public PdfString setHexWriting(boolean hexWriting) { + return original.setHexWriting(hexWriting); + } + + @Override + public String getValue() { + return original.getValue(); + } + + @Override + public String toUnicodeString() { + return original.toUnicodeString(); + } + + @Override + public int hashCode() { + return original.hashCode(); + } + + @Override + public void markAsUnencryptedObject() { + original.markAsUnencryptedObject(); + } + +// @Override +// protected void generateValue() { +// super.generateValue(); +// } + +// @Override +// protected void generateContent() { +// super.generateContent(); +// } + +// @Override +// protected boolean encrypt(PdfEncryption encrypt) { +// return original.encrypt(encrypt); +// } + +// @Override +// protected byte[] decodeContent() { +// return original.decodeContent(); +// } + +// @Override +// protected byte[] encodeBytes(byte[] bytes) { +// return original.encodeBytes(bytes); +// } + +// @Override +// protected PdfObject newInstance() { +// return original.clone(); +// } + +// @Override +// protected void copyContent(PdfObject from, PdfDocument document, ICopyFilter copyFilter) { +// super.copyContent(from, document, copyFilter); +// } + +// @Override +// protected boolean hasContent() { +// return original.hasContent(); +// } + + @Override + public PdfObject makeIndirect(PdfDocument document, PdfIndirectReference reference) { + return original.makeIndirect(document, reference); + } + + @Override + public PdfObject setIndirectReference(PdfIndirectReference indirectReference) { + return original.setIndirectReference(indirectReference); + } + +// @Override +// protected int compareContent(PdfPrimitiveObject o) { +// return original.compareContent(o); +// } + + @Override + public PdfIndirectReference getIndirectReference() { + return original.getIndirectReference(); + } + + @Override + public PdfObject makeIndirect(PdfDocument document) { + return original.makeIndirect(document); + } + + @Override + public boolean isFlushed() { + return original.isFlushed(); + } + + @Override + public boolean isModified() { + return original.isModified(); + } + + @Override + public PdfObject clone() { + return original.clone(); + } + + @Override + public PdfObject clone(ICopyFilter filter) { + return original.clone(filter); + } + + @Override + public PdfObject copyTo(PdfDocument document) { + return original.copyTo(document); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating) { + return original.copyTo(document, allowDuplicating); + } + + @Override + public PdfObject copyTo(PdfDocument document, ICopyFilter copyFilter) { + return original.copyTo(document, copyFilter); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating, ICopyFilter copyFilter) { + return original.copyTo(document, allowDuplicating, copyFilter); + } + + @Override + public PdfObject setModified() { + return original.setModified(); + } + + @Override + public boolean isReleaseForbidden() { + return original.isReleaseForbidden(); + } + + @Override + public void release() { + super.release(); + } + + @Override + public boolean isNull() { + return original.isNull(); + } + + @Override + public boolean isBoolean() { + return original.isBoolean(); + } + + @Override + public boolean isNumber() { + return original.isNumber(); + } + + @Override + public boolean isString() { + return original.isString(); + } + + @Override + public boolean isName() { + return original.isName(); + } + + @Override + public boolean isArray() { + return original.isArray(); + } + + @Override + public boolean isDictionary() { + return original.isDictionary(); + } + + @Override + public boolean isStream() { + return original.isStream(); + } + + @Override + public boolean isIndirectReference() { + return original.isIndirectReference(); + } + + @Override + public boolean isLiteral() { + return original.isLiteral(); } - protected RupsPdfString(byte[] content, boolean hexWriting) { - super(content, hexWriting); +// @Override +// protected boolean checkState(short state) { +// return original.checkState(state); +// } + +// @Override +// protected PdfObject setState(short state) { +// return original.setState(state); +// } + +// @Override +// protected PdfObject clearState(short state) { +// return original.clearState(state); +// } + + @Override + protected void copyContent(PdfObject from, PdfDocument document) { + super.copyContent(from, document); + } + + @Override + public boolean equals(Object o) { + if(o instanceof PdfString) { + return original.equals(o); + } else { + return false; + } } @Override diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfTextArray.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfTextArray.java new file mode 100644 index 00000000..78b32976 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfTextArray.java @@ -0,0 +1,350 @@ +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.font.PdfFont; +import com.itextpdf.kernel.geom.Rectangle; +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfBoolean; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfDocument; +import com.itextpdf.kernel.pdf.PdfIndirectReference; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfNumber; +import com.itextpdf.kernel.pdf.PdfObject; +import com.itextpdf.kernel.pdf.PdfStream; +import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.pdf.PdfTextArray; +import com.itextpdf.kernel.utils.ICopyFilter; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class RupsPdfTextArray extends PdfTextArray { + PdfTextArray original; + public RupsPdfTextArray(PdfTextArray pdfTextArray) { + super(); + original = pdfTextArray; + } + + @Override + public void add(PdfObject pdfObject) { + original.add(pdfObject); + } + + @Override + public void addAll(PdfArray a) { + original.addAll(a); + } + + @Override + public void addAll(Collection c) { + original.addAll(c); + } + + @Override + public boolean add(float number) { + return original.add(number); + } + + @Override + public boolean add(String text, PdfFont font) { + return original.add(text, font); + } + + @Override + public boolean add(byte[] text) { + return original.add(text); + } + + @Override + protected boolean add(String text) { + return add(text.getBytes()); + } + + @Override + public int size() { + return original.size(); + } + + @Override + public boolean isEmpty() { + return original.isEmpty(); + } + + @Override + public boolean contains(PdfObject o) { + return original.contains(o); + } + + @Override + public Iterator iterator() { + return original.iterator(); + } + + @Override + public void add(int index, PdfObject element) { + original.add(index, element); + } + + @Override + public PdfObject set(int index, PdfObject element) { + return original.set(index, element); + } + + @Override + public PdfObject get(int index) { + return original.get(index); + } + + @Override + public void remove(int index) { + original.remove(index); + } + + @Override + public void remove(PdfObject o) { + original.remove(o); + } + + @Override + public void clear() { + original.clear(); + } + + @Override + public int indexOf(PdfObject o) { + return original.indexOf(o); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return original.subList(fromIndex, toIndex); + } + + @Override + public byte getType() { + return original.getType(); + } + + @Override + public String toString() { + return RupsPdfArray.getShimmedString(original); + } + + @Override + public PdfObject get(int index, boolean asDirect) { + return original.get(index, asDirect); + } + + @Override + public PdfArray getAsArray(int index) { + return original.getAsArray(index); + } + + @Override + public PdfDictionary getAsDictionary(int index) { + return original.getAsDictionary(index); + } + + @Override + public PdfStream getAsStream(int index) { + return original.getAsStream(index); + } + + @Override + public PdfNumber getAsNumber(int index) { + return original.getAsNumber(index); + } + + @Override + public PdfName getAsName(int index) { + return original.getAsName(index); + } + + @Override + public PdfString getAsString(int index) { + return original.getAsString(index); + } + + @Override + public PdfBoolean getAsBoolean(int index) { + return original.getAsBoolean(index); + } + + @Override + public Rectangle toRectangle() { + return original.toRectangle(); + } + + @Override + public float[] toFloatArray() { + return original.toFloatArray(); + } + + @Override + public double[] toDoubleArray() { + return original.toDoubleArray(); + } + + @Override + public long[] toLongArray() { + return original.toLongArray(); + } + + @Override + public int[] toIntArray() { + return original.toIntArray(); + } + + @Override + public boolean[] toBooleanArray() { + return original.toBooleanArray(); + } + + @Override + public PdfIndirectReference getIndirectReference() { + return original.getIndirectReference(); + } + + @Override + public boolean isIndirect() { + return original.isIndirect(); + } + + @Override + public PdfObject makeIndirect(PdfDocument document, PdfIndirectReference reference) { + return original.makeIndirect(document, reference); + } + + @Override + public PdfObject makeIndirect(PdfDocument document) { + return original.makeIndirect(document); + } + + @Override + public boolean isFlushed() { + return original.isFlushed(); + } + + @Override + public boolean isModified() { + return original.isModified(); + } + + @Override + public PdfObject clone() { + return original.clone(); + } + + @Override + public PdfObject clone(ICopyFilter filter) { + return original.clone(filter); + } + + @Override + public PdfObject copyTo(PdfDocument document) { + return original.copyTo(document); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating) { + return original.copyTo(document, allowDuplicating); + } + + @Override + public PdfObject copyTo(PdfDocument document, ICopyFilter copyFilter) { + return original.copyTo(document, copyFilter); + } + + @Override + public PdfObject copyTo(PdfDocument document, boolean allowDuplicating, ICopyFilter copyFilter) { + return original.copyTo(document, allowDuplicating, copyFilter); + } + + @Override + public PdfObject setModified() { + return original.setModified(); + } + + @Override + public boolean isReleaseForbidden() { + return original.isReleaseForbidden(); + } + + @Override + public void release() { + original.release(); + } + + @Override + public boolean isNull() { + return original.isNull(); + } + + @Override + public boolean isBoolean() { + return original.isBoolean(); + } + + @Override + public boolean isNumber() { + return original.isNumber(); + } + + @Override + public boolean isString() { + return original.isString(); + } + + @Override + public boolean isName() { + return original.isName(); + } + + @Override + public boolean isArray() { + return original.isArray(); + } + + @Override + public boolean isDictionary() { + return original.isDictionary(); + } + + @Override + public boolean isStream() { + return original.isStream(); + } + + @Override + public boolean isIndirectReference() { + return original.isIndirectReference(); + } + + @Override + public boolean isLiteral() { + return original.isLiteral(); + } + + @Override + public void forEach(Consumer action) { + original.forEach(action); + } + + @Override + public Spliterator spliterator() { + return original.spliterator(); + } + + @Override + public int hashCode() { + return original.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return original.equals(obj); + } +} diff --git a/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java b/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java index 17f3a2b2..80563ae2 100644 --- a/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java +++ b/src/main/java/com/itextpdf/rups/view/itext/treenodes/PdfObjectTreeNode.java @@ -42,13 +42,18 @@ This file is part of the iText (R) project. */ package com.itextpdf.rups.view.itext.treenodes; +import com.itextpdf.kernel.pdf.PdfArray; import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfIndirectReference; import com.itextpdf.kernel.pdf.PdfName; import com.itextpdf.kernel.pdf.PdfObject; import com.itextpdf.kernel.pdf.PdfString; +import com.itextpdf.kernel.pdf.PdfTextArray; import com.itextpdf.rups.model.LoggerHelper; +import com.itextpdf.rups.shims.RupsPdfArray; +import com.itextpdf.rups.shims.RupsPdfDictionary; import com.itextpdf.rups.shims.RupsPdfString; +import com.itextpdf.rups.shims.RupsPdfTextArray; import com.itextpdf.rups.view.Language; import com.itextpdf.rups.view.icons.IconFetcher; import com.itextpdf.rups.view.icons.IconTreeNode; @@ -111,9 +116,15 @@ protected PdfObjectTreeNode(PdfObject object) { break; case PdfObject.ARRAY: icon = IconFetcher.getIcon(ARRAY_ICON); + if (object instanceof PdfTextArray) { + this.object = new RupsPdfTextArray((PdfTextArray) object); + } else if (object instanceof PdfArray) { + this.object = new RupsPdfArray((PdfArray) object); + } break; case PdfObject.DICTIONARY: icon = IconFetcher.getIcon(DICTIONARY_ICON); + this.object = new RupsPdfDictionary((PdfDictionary) object); break; case PdfObject.STREAM: icon = IconFetcher.getIcon(STREAM_ICON); From 62774570db3524e40d1dbc71ea4aa07438f99ebd Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Mon, 22 May 2023 16:34:24 +0200 Subject: [PATCH 6/8] Minor Fixes to ensure Formatting and behaviour parity outside of targeted changes. Signed-off-by: Nick Boyd --- src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java | 4 +++- src/main/java/com/itextpdf/rups/shims/RupsPdfString.java | 8 -------- .../java/com/itextpdf/rups/shims/RupsPdfArrayTest.java | 2 ++ .../com/itextpdf/rups/shims/RupsPdfDictionaryTest.java | 2 ++ 4 files changed, 7 insertions(+), 9 deletions(-) create mode 100644 src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java create mode 100644 src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java index 2220447f..fd7df691 100644 --- a/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java @@ -117,8 +117,10 @@ protected static String getShimmedString(PdfArray original) { string.append("["); for (PdfObject entry : original) { string.append(RupsPdfArray.GetEntryString(entry)); + if(entry.isIndirectReference()) { + string.append(" "); + } } - string.append(" "); string.append("]"); return string.toString(); } diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java index a8898b77..dd84cd39 100644 --- a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -13,14 +13,6 @@ public RupsPdfString(String value, String encoding) { super(value, encoding); } - public RupsPdfString(String value) { - super(value); - } - - public RupsPdfString(byte[] content) { - super(content); - } - public RupsPdfString(PdfString original){ super(original.getValueBytes()); this.original = original; diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java new file mode 100644 index 00000000..7bc9aec4 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java @@ -0,0 +1,2 @@ +package com.itextpdf.rups.shims;public class RupsPdfArrayTest { +} diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java new file mode 100644 index 00000000..90a6bbb8 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java @@ -0,0 +1,2 @@ +package com.itextpdf.rups.shims;public class RupsPdfDictionaryTest { +} From 469520d7ce7a0447886a092e12661ea878397cda Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Mon, 22 May 2023 16:34:55 +0200 Subject: [PATCH 7/8] Tests Started Signed-off-by: Nick Boyd --- .../itextpdf/rups/shims/RupsPdfArrayTest.java | 53 ++++++++++- .../rups/shims/RupsPdfDictionaryTest.java | 88 ++++++++++++++++++- .../rups/shims/RupsPdfStringTest.java | 45 ++++++---- 3 files changed, 165 insertions(+), 21 deletions(-) diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java index 7bc9aec4..47b55668 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java @@ -1,2 +1,53 @@ -package com.itextpdf.rups.shims;public class RupsPdfArrayTest { +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfName; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("UnitTest") +@Tag("Array") +public class RupsPdfArrayTest { + + @Test + public void BasicNameArrayTest(){ + PdfArray initialArray = new PdfArray(); + + PdfName initialValueOne = new PdfName("ValueOne"); + PdfName initialValueTwo = new PdfName("ValueTwo"); + initialArray.add(initialValueOne); + initialArray.add(initialValueTwo); + + RupsPdfArray pdfArray = new RupsPdfArray(initialArray); + + Assertions.assertEquals("[/ValueOne/ValueTwo]", pdfArray.toString(), "PDF Array fails to Serialize correctly."); + + + } + @Test + public void BasicNestedNameArrayTest(){ + PdfArray initialArray = new PdfArray(); + + PdfArray subArrayOne = new PdfArray(); + PdfArray subArrayTwo = new PdfArray(); + + PdfName initialValueOne = new PdfName("ValueOne"); + PdfName initialValueTwo = new PdfName("ValueTwo"); + + subArrayOne.add(initialValueOne); + subArrayOne.add(initialValueTwo); + + subArrayTwo.add(initialValueOne); + subArrayTwo.add(initialValueTwo); + + initialArray.add(subArrayOne); + initialArray.add(subArrayTwo); + + RupsPdfArray pdfArray = new RupsPdfArray(initialArray); + + Assertions.assertEquals("[[/ValueOne/ValueTwo][/ValueOne/ValueTwo]]", pdfArray.toString(), "PDF Array fails to Serialize correctly."); + + + } } diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java index 90a6bbb8..00ec03f2 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java @@ -1,2 +1,88 @@ -package com.itextpdf.rups.shims;public class RupsPdfDictionaryTest { +package com.itextpdf.rups.shims; + +import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfDictionary; +import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfString; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +@Tag("UnitTest") +@Tag("Dictionary") +public class RupsPdfDictionaryTest { + + @Test + public void BasicNameDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfName initialKeyOne = new PdfName("KeyOne"); + PdfName initialValueOne = new PdfName("ValueOne"); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + PdfName initialValueTwo = new PdfName("ValueTwo"); + + initialDict.put(initialKeyOne, initialValueOne); + initialDict.put(initialKeyTwo, initialValueTwo); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals("<>", pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + @Test + public void BasicStringDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfName initialKeyOne = new PdfName("KeyOne"); + PdfString initialValueOne = new PdfString("ValueOne"); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + PdfString initialValueTwo = new PdfString("ValueTwo"); + + initialDict.put(initialKeyOne, initialValueOne); + initialDict.put(initialKeyTwo, initialValueTwo); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals("<>", pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + @Test + public void NameAndNameArrayDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfArray subArray = new PdfArray(); + PdfName initialKeyOne = new PdfName("KeyOne"); + PdfName initialValueOne = new PdfName("ValueOne"); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + PdfName initialValueTwo = new PdfName("ValueTwo"); + + subArray.add(initialValueOne); + subArray.add(initialValueTwo); + + initialDict.put(initialKeyOne, initialValueOne); + initialDict.put(initialKeyTwo, subArray); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals("<>", pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + @Test + public void NestedNameDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfDictionary subDictOne = new PdfDictionary(); + PdfDictionary subDictTwo = new PdfDictionary(); + PdfName initialKeyOne = new PdfName("KeyOne"); + PdfName initialValueOne = new PdfName("ValueOne"); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + PdfName initialValueTwo = new PdfName("ValueTwo"); + + subDictOne.put(initialKeyOne, initialValueOne); + subDictOne.put(initialKeyTwo, initialValueTwo); + + subDictTwo.put(initialKeyOne, initialValueOne); + subDictTwo.put(initialKeyTwo, initialValueTwo); + + initialDict.put(initialKeyOne, subDictOne); + initialDict.put(initialKeyTwo, subDictTwo); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals("<>/KeyTwo <>>>", pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + } diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java index 71c6190c..d0803b96 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -1,18 +1,19 @@ package com.itextpdf.rups.shims; -import com.itextpdf.test.annotations.type.UnitTest; -import org.junit.Assert; -import org.junit.Test; -import org.junit.experimental.categories.Category; +import com.itextpdf.kernel.pdf.PdfString; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; -@Category(UnitTest.class) +@Tag("UnitTest") +@Tag("String") public class RupsPdfStringTest { @Test public void toStringBasicTest() { - RupsPdfString pdfString = new RupsPdfString("Test"); - - Assert.assertEquals("String is () Delimited.", "(Test)", pdfString.toString()); + PdfString initialString = new PdfString("Test"); + RupsPdfString pdfString = new RupsPdfString(initialString); + Assertions.assertEquals("(Test)", pdfString.toString(), "String is () Delimited."); } @Test @@ -24,39 +25,45 @@ public void toStringHexTest() { } hexString.append(">"); - RupsPdfString pdfString = new RupsPdfString(hexArray); - pdfString.setHexWriting(true); + PdfString initialString = new PdfString(hexArray); + initialString.setHexWriting(true); + + RupsPdfString pdfString = new RupsPdfString(initialString); - Assert.assertEquals("String is <> Delimited.", hexString.toString(), pdfString.toString()); + Assertions.assertEquals("", pdfString.toString(), "String is <> Delimited."); } @Test public void toStringBalancedTest(){ String balanced = "Test (of paretheses)"; - RupsPdfString pdfString = new RupsPdfString(balanced); - Assert.assertEquals("Balanced parens are escaped:", "(Test \\(of paretheses\\))", pdfString.toString()); + PdfString initialString = new PdfString(balanced); + RupsPdfString pdfString = new RupsPdfString(initialString); + Assertions.assertEquals("(Test \\(of paretheses\\))", pdfString.toString(), "Balanced parens are escaped:"); // Note: This is optional, but performed this way in iText to avoid too much overhead evaluating the balance of symbols. } @Test public void toStringUnbalancedTest() { String unbalanced = "Test :-)"; - RupsPdfString pdfString = new RupsPdfString(unbalanced); - Assert.assertEquals("Unbalanced parens are escaped:", "(Test :-\\))", pdfString.toString()); + PdfString initialString = new PdfString(unbalanced); + RupsPdfString pdfString = new RupsPdfString(initialString); + Assertions.assertEquals("(Test :-\\))", pdfString.toString(), "Unbalanced parens are escaped:"); } @Test public void toStringUnbalancedTest_Two() { String unbalanced_two = ")Test :-("; - RupsPdfString pdfString_two = new RupsPdfString(unbalanced_two); - Assert.assertEquals("Unbalanced parens are escaped:", "(\\)Test :-\\()", pdfString_two.toString()); + PdfString initialString = new PdfString(unbalanced_two); + RupsPdfString pdfString_two = new RupsPdfString(initialString); + Assertions.assertEquals("(\\)Test :-\\()", pdfString_two.toString(), "Unbalanced parens are escaped:"); } @Test public void toStringUnbalancedTest_Three(){ String unbalanced_three = "@<----(( Robin Hood Test"; - RupsPdfString pdfString_three = new RupsPdfString(unbalanced_three); - Assert.assertEquals("Unbalanced parens are escaped:", "(@<----\\(\\( Robin Hood Test)", pdfString_three.toString()); + PdfString initialString = new PdfString(unbalanced_three); + RupsPdfString pdfString_three = new RupsPdfString(initialString); + Assertions.assertEquals("(@<----\\(\\( Robin Hood Test)", pdfString_three.toString(), "Unbalanced parens are escaped:"); } } From 448f4b3567b04c9f17d7a3794191774031e4f77f Mon Sep 17 00:00:00 2001 From: Nick Boyd Date: Tue, 23 May 2023 11:29:34 +0200 Subject: [PATCH 8/8] Tests Implemented Signed-off-by: Nick Boyd --- .../itextpdf/rups/shims/RupsPdfString.java | 13 +++- .../itextpdf/rups/shims/RupsPdfArrayTest.java | 73 +++++++++++++++++++ .../rups/shims/RupsPdfDictionaryTest.java | 62 ++++++++++++++++ .../rups/shims/RupsPdfStringTest.java | 2 +- 4 files changed, 146 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java index dd84cd39..c9c6d4a5 100644 --- a/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -268,10 +268,17 @@ public boolean equals(Object o) { @Override public String toString() { String wrapper; - if(isHexWriting()) + String stringValue; + if(isHexWriting()) { wrapper = "<%s>"; - else + stringValue = ""; + for (byte b: getValueBytes()){ + stringValue = stringValue.concat(Integer.toHexString(b)); + } + } else { wrapper = "(%s)"; - return String.format(wrapper, new String(encodeBytes(getValueBytes()))); + stringValue = new String(encodeBytes(getValueBytes())); + } + return String.format(wrapper, stringValue); } } diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java index 47b55668..d00678b8 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java @@ -1,7 +1,9 @@ package com.itextpdf.rups.shims; import com.itextpdf.kernel.pdf.PdfArray; +import com.itextpdf.kernel.pdf.PdfDictionary; import com.itextpdf.kernel.pdf.PdfName; +import com.itextpdf.kernel.pdf.PdfString; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; @@ -50,4 +52,75 @@ public void BasicNestedNameArrayTest(){ } + @Test + public void MixedStringArrayTest(){ + PdfArray initialArray = new PdfArray(); + String valueOne = "ValueOne"; + byte[] hexArrayOne = valueOne.getBytes(); + PdfString initialValueOne = new PdfString(valueOne); + PdfString hexValueOne = new PdfString(hexArrayOne); + hexValueOne.setHexWriting(true); + + String valueTwo = "ValueTwo"; + byte[] hexArrayTwo = valueTwo.getBytes(); + PdfString initialValueTwo = new PdfString(valueTwo); + PdfString hexValueTwo = new PdfString(hexArrayTwo); + hexValueTwo.setHexWriting(true); + String hexStringOne = ""; + for (byte b: hexArrayOne) + hexStringOne = hexStringOne.concat(Integer.toHexString(b)); + + String hexStringTwo = ""; + for (byte b: hexArrayTwo) + hexStringTwo = hexStringTwo.concat(Integer.toHexString(b)); + + initialArray.add(initialValueOne); + initialArray.add(hexValueOne); + + initialArray.add(initialValueTwo); + initialArray.add(hexValueTwo); + + RupsPdfArray pdfArray = new RupsPdfArray(initialArray); + + Assertions.assertEquals(String.format("[(%1$s)<%2$s>(%3$s)<%4$s>]", initialValueOne, hexStringOne, initialValueTwo, hexStringTwo), pdfArray.toString(), "PDF Array fails to Serialize correctly."); + } + + + @Test + public void HexStringDictionaryArrayTest(){ + PdfArray initialArray = new PdfArray(); + + PdfDictionary initialDictOne = new PdfDictionary(); + PdfDictionary initialDictTwo = new PdfDictionary(); + + PdfName initialKeyOne = new PdfName("KeyOne"); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + + byte[] hexArrayOne = "ValueOne".getBytes(); + PdfString hexValueOne = new PdfString(hexArrayOne); + hexValueOne.setHexWriting(true); + initialDictOne.put(initialKeyOne, hexValueOne); + + + byte[] hexArrayTwo = "ValueTwo".getBytes(); + PdfString hexValueTwo = new PdfString(hexArrayTwo); + hexValueTwo.setHexWriting(true); + + initialDictTwo.put(initialKeyTwo, hexValueTwo); + + initialArray.add(initialDictOne); + initialArray.add(initialDictTwo); + + String hexStringOne = ""; + for (byte b: hexArrayOne) + hexStringOne = hexStringOne.concat(Integer.toHexString(b)); + + String hexStringTwo = ""; + for (byte b: hexArrayTwo) + hexStringTwo = hexStringTwo.concat(Integer.toHexString(b)); + + RupsPdfArray pdfArray = new RupsPdfArray(initialArray); + + Assertions.assertEquals(String.format("[<>><>>]", hexStringOne, hexStringTwo), pdfArray.toString(), "PDF Array fails to Serialize correctly."); + } } diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java index 00ec03f2..ae08e041 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java @@ -42,6 +42,68 @@ public void BasicStringDictionaryTest(){ Assertions.assertEquals("<>", pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); } + @Test + public void HexStringDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfName initialKeyOne = new PdfName("KeyOne"); + byte[] hexArrayOne = "ValueOne".getBytes(); + PdfString initialValueOne = new PdfString(hexArrayOne); + initialValueOne.setHexWriting(true); + PdfName initialKeyTwo = new PdfName("KeyTwo"); + byte[] hexArrayTwo = "ValueTwo".getBytes(); + PdfString initialValueTwo = new PdfString(hexArrayTwo); + initialValueTwo.setHexWriting(true); + + initialDict.put(initialKeyOne, initialValueOne); + initialDict.put(initialKeyTwo, initialValueTwo); + + String hexStringOne = "<"; + for (byte b: hexArrayOne) + hexStringOne = hexStringOne.concat(Integer.toHexString(b)); + hexStringOne = hexStringOne.concat(">"); + + String hexStringTwo = "<"; + for (byte b: hexArrayTwo) + hexStringTwo = hexStringTwo.concat(Integer.toHexString(b)); + hexStringTwo = hexStringTwo.concat(">"); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals(String.format("<>", hexStringOne, hexStringTwo), pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + @Test + public void HexStringArrayDictionaryTest(){ + PdfDictionary initialDict = new PdfDictionary(); + PdfArray initialValue = new PdfArray(); + + PdfName initialKeyOne = new PdfName("KeyOne"); + + byte[] hexArrayOne = "ValueOne".getBytes(); + PdfString hexValueOne = new PdfString(hexArrayOne); + hexValueOne.setHexWriting(true); + initialValue.add(hexValueOne); + + byte[] hexArrayTwo = "ValueTwo".getBytes(); + PdfString hexValueTwo = new PdfString(hexArrayTwo); + hexValueTwo.setHexWriting(true); + initialValue.add(hexValueTwo); + + + initialDict.put(initialKeyOne, initialValue); + + String hexStringOne = ""; + for (byte b: hexArrayOne) + hexStringOne = hexStringOne.concat(Integer.toHexString(b)); + + String hexStringTwo = ""; + for (byte b: hexArrayTwo) + hexStringTwo = hexStringTwo.concat(Integer.toHexString(b)); + + RupsPdfDictionary pdfDictionary = new RupsPdfDictionary(initialDict); + + Assertions.assertEquals(String.format("<<%2$s>]>>", hexStringOne, hexStringTwo), pdfDictionary.toString(), "PDF Dictionary fails to Serialize correctly."); + } + @Test public void NameAndNameArrayDictionaryTest(){ PdfDictionary initialDict = new PdfDictionary(); diff --git a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java index d0803b96..054ba027 100644 --- a/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -30,7 +30,7 @@ public void toStringHexTest() { RupsPdfString pdfString = new RupsPdfString(initialString); - Assertions.assertEquals("", pdfString.toString(), "String is <> Delimited."); + Assertions.assertEquals(hexString.toString(), pdfString.toString(), "String is <> Delimited."); } @Test