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..fd7df691 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfArray.java @@ -0,0 +1,367 @@ +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)); + if(entry.isIndirectReference()) { + 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 new file mode 100644 index 00000000..c9c6d4a5 --- /dev/null +++ b/src/main/java/com/itextpdf/rups/shims/RupsPdfString.java @@ -0,0 +1,284 @@ +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); + } + + 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(); + } + +// @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 + public String toString() { + String wrapper; + String stringValue; + if(isHexWriting()) { + wrapper = "<%s>"; + stringValue = ""; + for (byte b: getValueBytes()){ + stringValue = stringValue.concat(Integer.toHexString(b)); + } + } else { + wrapper = "(%s)"; + stringValue = new String(encodeBytes(getValueBytes())); + } + return String.format(wrapper, stringValue); + } +} 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/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..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,12 +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; @@ -110,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); @@ -132,6 +144,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 +412,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; + } } 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..d00678b8 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfArrayTest.java @@ -0,0 +1,126 @@ +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("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."); + + + } + @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 new file mode 100644 index 00000000..ae08e041 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfDictionaryTest.java @@ -0,0 +1,150 @@ +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 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(); + 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 new file mode 100644 index 00000000..054ba027 --- /dev/null +++ b/src/test/java/com/itextpdf/rups/shims/RupsPdfStringTest.java @@ -0,0 +1,70 @@ +package com.itextpdf.rups.shims; + +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("String") +public class RupsPdfStringTest { + + @Test + public void toStringBasicTest() { + PdfString initialString = new PdfString("Test"); + RupsPdfString pdfString = new RupsPdfString(initialString); + Assertions.assertEquals("(Test)", pdfString.toString(), "String is () Delimited."); + } + + @Test + public void toStringHexTest() { + byte[] hexArray = "Test".getBytes(); + StringBuilder hexString = new StringBuilder("<"); + for (byte b : hexArray) { + hexString.append(Integer.toHexString(b)); + } + hexString.append(">"); + + PdfString initialString = new PdfString(hexArray); + initialString.setHexWriting(true); + + RupsPdfString pdfString = new RupsPdfString(initialString); + + Assertions.assertEquals(hexString.toString(), pdfString.toString(), "String is <> Delimited."); + } + + @Test + public void toStringBalancedTest(){ + String balanced = "Test (of paretheses)"; + 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 :-)"; + 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 :-("; + 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"; + PdfString initialString = new PdfString(unbalanced_three); + RupsPdfString pdfString_three = new RupsPdfString(initialString); + Assertions.assertEquals("(@<----\\(\\( Robin Hood Test)", pdfString_three.toString(), "Unbalanced parens are escaped:"); + } + +} + 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)); + } +}