FOP-2683: PDF Annotation ClassCastException

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1779919 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
index 7e3e315..d258466 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
@@ -638,16 +638,10 @@
                 exclude.add(COSName.P);
                 if (annot1 instanceof COSObject) {
                     COSObject annot = (COSObject) annot1;
-                    COSObject fieldObject = annot;
-                    COSDictionary field = (COSDictionary) fieldObject.getObject();
-                    COSObject parent;
-                    while ((parent = (COSObject) field.getItem(COSName.PARENT)) != null) {
-                        fieldObject = parent;
-                        field = (COSDictionary) fieldObject.getObject();
-                    }
-                    fields.add(fieldObject);
+                    getField(annot, fields);
 
-                    if (((COSDictionary) annot.getObject()).getItem(COSName.getPDFName("StructParent")) != null) {
+
+                    if (((COSDictionary) annot.getObject()).getItem(COSName.STRUCT_PARENT) != null) {
                         exclude.add(COSName.PARENT);
                     }
                 }
@@ -663,6 +657,25 @@
         return fields;
     }
 
+    private COSDictionary getField(COSObject fieldObject, Set<COSObject> fields) {
+        COSDictionary field = (COSDictionary) fieldObject.getObject();
+        COSObject parent;
+        while ((parent = getParent(field)) != null) {
+            fieldObject = parent;
+            field = (COSDictionary) fieldObject.getObject();
+        }
+        fields.add(fieldObject);
+        return field;
+    }
+
+    private COSObject getParent(COSDictionary field) {
+        COSBase parent = field.getItem(COSName.PARENT);
+        if (parent instanceof COSObject) {
+            return (COSObject) parent;
+        }
+        return null;
+    }
+
     static class CompareFields implements Comparator<COSObject>, Serializable {
         private static final long serialVersionUID = -6081505461660440801L;
 
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java b/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java
index 48177f1..2436fc8 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/StructureTreeMerger.java
@@ -194,8 +194,7 @@
             copyElemEntries(cosParentElem, elemParent);
             elem.setParent(elemParent);
             fillKidsWithNull(elemParent, (COSDictionary)cosParentElem.getObject());
-            if (((COSName)parentElemDictionary.getDictionaryObject(COSName.S)).getName()
-                .equals(StandardStructureTypes.TR)) {
+            if (parentElemDictionary.getDictionaryObject(COSName.S) == COSName.TR) {
                 COSBase rowKids = parentElemDictionary.getItem(COSName.K);
                 createKids(rowKids, parentElemDictionary, elemParent, true);
             } else {
@@ -378,7 +377,7 @@
         for (COSBase base : originalParentTree) {
             if (base instanceof COSNull || base == null) {
                 complete.add(null);
-            } else {
+            } else if (!list.isEmpty()) {
                 complete.add(list.get(0));
                 list.remove(0);
             }
diff --git a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
index 0b953fb..ae63aba 100644
--- a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
@@ -28,6 +28,7 @@
 import java.io.OutputStream;
 import java.net.URI;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -44,8 +45,11 @@
 import org.apache.fontbox.cff.CFFParser;
 import org.apache.fontbox.ttf.TTFParser;
 import org.apache.fontbox.type1.Type1Font;
+import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSInteger;
 import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDResources;
@@ -112,10 +116,10 @@
     private static final String XFORM = "test/resources/xform.pdf";
     private static final String LOOP = "test/resources/loop.pdf";
 
-    private PDFBoxAdapter getPDFBoxAdapter() {
+    private PDFBoxAdapter getPDFBoxAdapter(boolean mergeFonts) {
         PDFDocument doc = new PDFDocument("");
         PDFPage pdfpage = new PDFPage(new PDFResources(doc), 0, r, r, r, r);
-        doc.setMergeFontsEnabled(true);
+        doc.setMergeFontsEnabled(mergeFonts);
         pdfpage.setDocument(doc);
         pdfpage.setObjectNumber(1);
         return new PDFBoxAdapter(pdfpage, new HashMap(), new HashMap<Integer, PDFArray>());
@@ -180,7 +184,7 @@
         PDDocument doc = PDDocument.load(new File(pdf));
         PDPage page = doc.getDocumentCatalog().getPages().get(0);
         AffineTransform at = new AffineTransform();
-        String c = getPDFBoxAdapter().createStreamFromPDFBoxPage(doc, page, pdf, at, fi, new Rectangle());
+        String c = getPDFBoxAdapter(true).createStreamFromPDFBoxPage(doc, page, pdf, at, fi, new Rectangle());
 //        PDResources sourcePageResources = page.findResources();
 //        COSDictionary fonts = (COSDictionary)sourcePageResources.getCOSDictionary().getDictionaryObject(COSName.FONT);
 //        PDFBoxAdapter.PDFWriter w = adapter. new MergeFontsPDFWriter(fonts, fi, "", new ArrayList<COSName>());
@@ -356,6 +360,21 @@
     }
 
     @Test
+    public void testAnnot2() throws Exception {
+        PDFBoxAdapter adapter = getPDFBoxAdapter(false);
+        PDDocument doc = PDDocument.load(new File(ANNOT));
+        PDPage page = doc.getDocumentCatalog().getPages().get(0);
+        COSArray annots = (COSArray) page.getCOSObject().getDictionaryObject(COSName.ANNOTS);
+        COSDictionary dict = (COSDictionary) ((COSObject)annots.get(0)).getObject();
+        dict.setItem(COSName.PARENT, COSInteger.ONE);
+
+        AffineTransform at = new AffineTransform();
+        Rectangle r = new Rectangle(0, 1650, 842000, 595000);
+        adapter.createStreamFromPDFBoxPage(doc, page, "key", at, null, r);
+        doc.close();
+    }
+
+    @Test
     public void testLink() throws Exception {
         PDFDocument pdfdoc = new PDFDocument("");
         PDFPage pdfpage = new PDFPage(new PDFResources(pdfdoc), 0, r, r, r, r);
@@ -378,7 +397,7 @@
     @Test
     public void testXform() throws Exception {
         PDFDocument pdfdoc = new PDFDocument("");
-        pdfdoc.getFilterMap().put(PDFFilterList.DEFAULT_FILTER, Arrays.asList("null"));
+        pdfdoc.getFilterMap().put(PDFFilterList.DEFAULT_FILTER, Collections.singletonList("null"));
         pdfdoc.setMergeFontsEnabled(true);
         PDFPage pdfpage = new PDFPage(new PDFResources(pdfdoc), 0, r, r, r, r);
         pdfpage.setDocument(pdfdoc);
diff --git a/test/java/org/apache/fop/render/pdf/StructureTreeMergerUtilTestCase.java b/test/java/org/apache/fop/render/pdf/StructureTreeMergerUtilTestCase.java
index ea11639..d0029d8 100644
--- a/test/java/org/apache/fop/render/pdf/StructureTreeMergerUtilTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/StructureTreeMergerUtilTestCase.java
@@ -35,9 +35,9 @@
 
         COSDictionary rolemap = new COSDictionary();
         COSName key1 = COSName.getPDFName("Para");
-        COSName value1 = COSName.getPDFName("P");
+        COSName value1 = COSName.P;
         COSName key2 = COSName.getPDFName("Icon");
-        COSName value2 = COSName.getPDFName("Image");
+        COSName value2 = COSName.IMAGE;
         rolemap.setItem(key1, value1);
         rolemap.setItem(key2, value2);
         String type = "Image";