FOP-2879: Add caching to avoid parsing content stream

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop-pdf-images/trunk@1864947 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 a49fd89..55cf5af 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
@@ -369,10 +369,12 @@
 //            }
         }
         if (newStream == null) {
-            PDFWriter writer = new PDFWriter(uniqueName, currentMCID);
-            newStream = writer.writeText(pdStream);
-            currentMCID = writer.getCurrentMCID();
-
+            newStream = (String) clonedVersion.get(key);
+            if (newStream == null) {
+                PDFWriter writer = new PDFWriter(uniqueName, currentMCID);
+                newStream = writer.writeText(pdStream);
+                clonedVersion.put(key, newStream);
+            }
         }
         pdStream = new PDStream(sourceDoc, new ByteArrayInputStream(newStream.getBytes("ISO-8859-1")));
         mergeXObj(sourcePageResources, fontinfo, uniqueName);
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
index 34ffb72..a375ad1 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFWriter.java
@@ -149,8 +149,4 @@
         dictArgs.add(cn.getKey());
         dictArgs.add(updatedID);
     }
-
-    protected int getCurrentMCID() {
-        return currentMCID;
-    }
 }
diff --git a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
index 09c3f95..cb78dd2 100644
--- a/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFBoxAdapterTestCase.java
@@ -30,6 +30,7 @@
 import java.net.URI;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
@@ -478,55 +479,60 @@
 
     @Test
     public void testPDFCache() throws IOException {
-        PDFDocument pdfdoc = new PDFDocument("");
-        Map<Object, Object> pdfCache = new LinkedHashMap<Object, Object>();
-        Map<Object, Object> objectCachePerFile = loadPDFWithCache(pdfdoc, pdfCache, LOOP);
+        LoadPDFWithCache loadPDFWithCache = new LoadPDFWithCache();
+        loadPDFWithCache.run(LOOP);
 
-        Object item = pdfCache.values().iterator().next();
+        Object item = loadPDFWithCache.pdfCache.values().iterator().next();
         Assert.assertEquals(item.getClass(), PDFStream.class);
-        item = pdfCache.keySet().iterator().next();
+        item = loadPDFWithCache.pdfCache.keySet().iterator().next();
         Assert.assertEquals(item.getClass(), Integer.class);
-        Assert.assertEquals(pdfCache.size(), 12);
+        Assert.assertEquals(loadPDFWithCache.pdfCache.size(), 12);
 
-        int pdfDictionary = 0;
-        int strings = 0;
-        for (Map.Entry<Object, Object> o : objectCachePerFile.entrySet()) {
-            if (o.getValue().getClass().equals(PDFDictionary.class)) {
-                pdfDictionary++;
-            }
-            if (o.getKey() instanceof String) {
-                strings++;
-            }
-        }
-        Assert.assertEquals(pdfDictionary, 26);
-        Assert.assertEquals(strings, 33);
-        Assert.assertEquals(objectCachePerFile.size(), 45);
+        Iterator<Object> iterator = loadPDFWithCache.objectCachePerFile.values().iterator();
+        iterator.next();
+        item = iterator.next();
+        Assert.assertEquals(item.getClass(), PDFDictionary.class);
+        item = loadPDFWithCache.objectCachePerFile.keySet().iterator().next();
+        Assert.assertEquals(item.getClass(), String.class);
+        Assert.assertEquals(loadPDFWithCache.objectCachePerFile.size(), 46);
     }
 
-    private Map<Object, Object> loadPDFWithCache(PDFDocument pdfdoc, Map<Object, Object> pdfCache, String pdf)
-        throws IOException {
-        Map<Object, Object> objectCachePerFile = new LinkedHashMap<Object, Object>();
-        PDFPage pdfpage = getPDFPage(pdfdoc);
-        pdfdoc.assignObjectNumber(pdfpage);
-        pdfpage.setDocument(pdfdoc);
-        PDFBoxAdapter adapter = new PDFBoxAdapter(
-                pdfpage, objectCachePerFile, new HashMap<Integer, PDFArray>(), pdfCache);
-        PDDocument doc = PDDocument.load(new File(pdf));
-        PDPage page = doc.getPage(0);
-        adapter.createStreamFromPDFBoxPage(doc, page, "key", new AffineTransform(), null, new Rectangle());
-        doc.close();
-        return objectCachePerFile;
+    @Test
+    public void testPDFCache2() throws IOException {
+        LoadPDFWithCache loadPDFWithCache = new LoadPDFWithCache();
+        String stream = loadPDFWithCache.run(LOOP);
+        String cachedStream = (String) loadPDFWithCache.objectCachePerFile.get(LOOP);
+        Assert.assertTrue(cachedStream.contains("EMC"));
+        Assert.assertTrue(stream.endsWith(cachedStream));
+    }
+
+    private static class LoadPDFWithCache {
+        private PDFDocument pdfdoc = new PDFDocument("");
+        private Map<Object, Object> pdfCache = new LinkedHashMap<Object, Object>();
+        private Map<Object, Object> objectCachePerFile = new LinkedHashMap<Object, Object>();
+        private String run(String pdf) throws IOException {
+            PDFPage pdfpage = getPDFPage(pdfdoc);
+            pdfdoc.assignObjectNumber(pdfpage);
+            pdfpage.setDocument(pdfdoc);
+            PDFBoxAdapter adapter = new PDFBoxAdapter(
+                    pdfpage, objectCachePerFile, new HashMap<Integer, PDFArray>(), pdfCache);
+            PDDocument doc = PDDocument.load(new File(pdf));
+            PDPage page = doc.getPage(0);
+            String stream = adapter.createStreamFromPDFBoxPage(
+                    doc, page, pdf, new AffineTransform(), null, new Rectangle());
+            doc.close();
+            return stream;
+        }
     }
 
     @Test
     public void testPDFSize() throws IOException {
-        PDFDocument pdfdoc = new PDFDocument("");
-        Map<Object, Object> pdfCache = new HashMap<Object, Object>();
-        loadPDFWithCache(pdfdoc, pdfCache, ANNOT);
-        loadPDFWithCache(pdfdoc, pdfCache, ANNOT);
+        LoadPDFWithCache loadPDFWithCache = new LoadPDFWithCache();
+        loadPDFWithCache.run(ANNOT);
+        loadPDFWithCache.run(ANNOT);
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        pdfdoc.output(bos);
-        Assert.assertEquals(pdfCache.size(), 2);
+        loadPDFWithCache.pdfdoc.output(bos);
+        Assert.assertEquals(loadPDFWithCache.pdfCache.size(), 2);
         Assert.assertTrue(bos.size() <= 6418);
     }