Skip to content

Commit 2de3027

Browse files
authored
Upgrade PDFBox API to v2.0.10 (#344)
1 parent cbc9616 commit 2de3027

File tree

69 files changed

+2227
-943
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2227
-943
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.tom_roush.pdfbox.android;
2+
3+
import android.util.Log;
4+
5+
import java.io.File;
6+
import java.io.FileOutputStream;
7+
import java.io.InputStream;
8+
import java.net.URL;
9+
10+
import com.tom_roush.pdfbox.io.IOUtils;
11+
12+
public class TestResourceGenerator
13+
{
14+
public static File downloadTestResource(File targetDir, String targetName, String url) {
15+
File resourceFile = new File(targetDir, targetName);
16+
if (!resourceFile.exists())
17+
{
18+
try
19+
{
20+
Log.i("PdfBox-Android", "Resource file not cached, Downloading file " + targetName);
21+
InputStream urlStream = new URL(url).openStream();
22+
IOUtils.copy(urlStream, new FileOutputStream(resourceFile));
23+
}
24+
catch (Exception e)
25+
{
26+
Log.w("PdfBox-Android", "Unable to download test file. Test will be skipped");
27+
return null;
28+
}
29+
}
30+
return resourceFile;
31+
}
32+
}

library/src/androidTest/java/com/tom_roush/pdfbox/multipdf/PDFMergerUtilityTest.java

Lines changed: 110 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,21 @@
1717

1818
import android.content.Context;
1919
import android.graphics.Bitmap;
20-
import android.util.Log;
2120

2221
import androidx.test.platform.app.InstrumentationRegistry;
2322

2423
import java.io.File;
25-
import java.io.FileOutputStream;
2624
import java.io.IOException;
27-
import java.io.InputStream;
28-
import java.net.URL;
25+
import java.util.HashSet;
26+
import java.util.Set;
2927

3028
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
29+
import com.tom_roush.pdfbox.android.TestResourceGenerator;
3130
import com.tom_roush.pdfbox.cos.COSArray;
3231
import com.tom_roush.pdfbox.cos.COSBase;
3332
import com.tom_roush.pdfbox.cos.COSDictionary;
3433
import com.tom_roush.pdfbox.cos.COSName;
3534
import com.tom_roush.pdfbox.cos.COSObject;
36-
import com.tom_roush.pdfbox.io.IOUtils;
3735
import com.tom_roush.pdfbox.io.MemoryUsageSetting;
3836
import com.tom_roush.pdfbox.pdmodel.PDDocument;
3937
import com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog;
@@ -45,27 +43,30 @@
4543
import com.tom_roush.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitDestination;
4644
import com.tom_roush.pdfbox.rendering.PDFRenderer;
4745

48-
import junit.framework.TestCase;
46+
import org.junit.Before;
47+
import org.junit.Test;
48+
49+
import static org.junit.Assert.assertEquals;
50+
import static org.junit.Assert.assertTrue;
51+
import static org.junit.Assume.assumeNotNull;
4952

5053
/**
5154
* Test suite for PDFMergerUtility.
5255
*
5356
* @author Maruan Sahyoun (PDF files)
5457
* @author Tilman Hausherr (code)
5558
*/
56-
public class PDFMergerUtilityTest extends TestCase
59+
public class PDFMergerUtilityTest
5760
{
5861
final String SRCDIR = "pdfbox/input/merge";
5962
String TARGETTESTDIR;
60-
private File TARGETPDFDIR;
63+
private static File TARGETPDFDIR;
6164
final int DPI = 96;
6265
private Context testContext;
6366

64-
@Override
65-
protected void setUp() throws Exception
67+
@Before
68+
public void setUp() throws Exception
6669
{
67-
super.setUp();
68-
6970
testContext = InstrumentationRegistry.getInstrumentation().getContext();
7071
PDFBoxResourceLoader.init(testContext);
7172
TARGETTESTDIR = testContext.getCacheDir() + "/pdfbox-test-output/merge/";
@@ -91,6 +92,7 @@ protected void setUp() throws Exception
9192
*
9293
* @throws IOException if something goes wrong.
9394
*/
95+
@Test
9496
public void testPDFMergerUtility() throws IOException
9597
{
9698
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.decoded.pdf",
@@ -112,6 +114,7 @@ public void testPDFMergerUtility() throws IOException
112114
*
113115
* @throws IOException if something goes wrong.
114116
*/
117+
@Test
115118
public void testJpegCcitt() throws IOException
116119
{
117120
checkMergeIdentical("jpegrgb.pdf",
@@ -127,6 +130,7 @@ public void testJpegCcitt() throws IOException
127130
}
128131

129132
// see PDFBOX-2893
133+
@Test
130134
public void testPDFMergerUtility2() throws IOException
131135
{
132136
checkMergeIdentical("PDFBox.GlobalResourceMergeTest.Doc01.pdf",
@@ -146,6 +150,7 @@ public void testPDFMergerUtility2() throws IOException
146150
*
147151
* @throws IOException
148152
*/
153+
@Test
149154
public void testPDFMergerOpenAction() throws IOException
150155
{
151156
PDDocument doc1 = new PDDocument();
@@ -184,47 +189,117 @@ public void testPDFMergerOpenAction() throws IOException
184189
*
185190
* @throws IOException
186191
*/
192+
@Test
187193
public void testStructureTreeMerge() throws IOException
188194
{
189-
File pdfFile = new File(TARGETPDFDIR, "PDFBOX-3999-GeneralForbearance.pdf");
195+
File inputPdf = TestResourceGenerator.downloadTestResource(TARGETPDFDIR, "PDFBOX-3999-GeneralForbearance.pdf", "https://issues.apache.org/jira/secure/attachment/12896905/GeneralForbearance.pdf");
196+
assumeNotNull(inputPdf);
190197

191-
if (!pdfFile.exists())
192-
{
193-
try
194-
{
195-
Log.i("PdfBox-Android", "PDF not cached, Downloading PDF for PDFMergerUtility.testStructureTreeMerge");
196-
InputStream pdfUrlStream = new URL(
197-
"https://issues.apache.org/jira/secure/attachment/12896905/GeneralForbearance.pdf")
198-
.openStream();
199-
IOUtils.copy(pdfUrlStream, new FileOutputStream(pdfFile));
200-
}
201-
catch (Exception e)
202-
{
203-
Log.w("PdfBox-Android", "Unable to download test PDF. Skipping test PDFMergerUtility.testStructureTreeMerge");
204-
return;
205-
}
206-
}
198+
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
199+
PDDocument src = PDDocument.load(inputPdf);
200+
PDDocument dst = PDDocument.load(inputPdf);
201+
pdfMergerUtility.appendDocument(dst, src);
202+
src.close();
203+
dst.save(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-merged.pdf"));
204+
dst.close();
205+
206+
PDDocument doc = PDDocument.load(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-merged.pdf"));
207+
PDPageTree pageTree = doc.getPages();
208+
209+
// check for orphan pages in the StructTreeRoot/K and StructTreeRoot/ParentTree trees.
210+
PDStructureTreeRoot structureTreeRoot = doc.getDocumentCatalog().getStructureTreeRoot();
211+
checkElement(pageTree, structureTreeRoot.getParentTree().getCOSObject());
212+
checkElement(pageTree, structureTreeRoot.getK());
213+
}
214+
215+
/**
216+
* PDFBOX-3999: check that no streams are kept from the source document by the destination
217+
* document, despite orphan annotations remaining in the structure tree.
218+
*
219+
* @throws IOException
220+
*/
221+
@Test
222+
public void testStructureTreeMerge2() throws IOException
223+
{
224+
File inputPdf = TestResourceGenerator.downloadTestResource(TARGETPDFDIR, "PDFBOX-3999-GeneralForbearance.pdf", "https://issues.apache.org/jira/secure/attachment/12896905/GeneralForbearance.pdf");
225+
assumeNotNull(inputPdf);
207226

208227
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
209-
PDDocument src = PDDocument.load(pdfFile);
210-
PDDocument dst = PDDocument.load(pdfFile);
228+
PDDocument doc = PDDocument.load(inputPdf);
229+
doc.getDocumentCatalog().getAcroForm().flatten();
230+
doc.save(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-flattened.pdf"));
231+
232+
ElementCounter elementCounter = new ElementCounter();
233+
elementCounter.walk(doc.getDocumentCatalog().getStructureTreeRoot().getK());
234+
int singleCnt = elementCounter.cnt;
235+
int singleSetSize = elementCounter.set.size();
236+
237+
doc.close();
238+
239+
PDDocument src = PDDocument.load(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-flattened.pdf"));
240+
PDDocument dst = PDDocument.load(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-flattened.pdf"));
211241
pdfMergerUtility.appendDocument(dst, src);
242+
// before solving PDFBOX-3999, the close() below brought
243+
// IOException: COSStream has been closed and cannot be read.
212244
src.close();
213-
dst.save(new File(TARGETTESTDIR, "PDFBOX-3999-GovFormPreFlattened-merged.pdf"));
245+
dst.save(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-flattened-merged.pdf"));
214246
dst.close();
215247

216-
PDDocument doc = PDDocument.load(new File(TARGETTESTDIR, "PDFBOX-3999-GovFormPreFlattened-merged.pdf"));
248+
doc = PDDocument.load(new File(TARGETTESTDIR, "PDFBOX-3999-GeneralForbearance-flattened-merged.pdf"));
217249
PDPageTree pageTree = doc.getPages();
218250

219251
// check for orphan pages in the StructTreeRoot/K and StructTreeRoot/ParentTree trees.
220252
PDStructureTreeRoot structureTreeRoot = doc.getDocumentCatalog().getStructureTreeRoot();
221253
checkElement(pageTree, structureTreeRoot.getParentTree().getCOSObject());
222254
checkElement(pageTree, structureTreeRoot.getK());
255+
256+
// Assume that the merged tree has double element count
257+
elementCounter = new ElementCounter();
258+
elementCounter.walk(structureTreeRoot.getK());
259+
assertEquals(singleCnt * 2, elementCounter.cnt);
260+
assertEquals(singleSetSize * 2, elementCounter.set.size());
261+
262+
doc.close();
263+
}
264+
265+
private class ElementCounter
266+
{
267+
int cnt = 0;
268+
Set<COSBase> set = new HashSet<COSBase>();
269+
270+
void walk(COSBase base)
271+
{
272+
if (base instanceof COSArray)
273+
{
274+
for (COSBase base2 : (COSArray) base)
275+
{
276+
if (base2 instanceof COSObject)
277+
{
278+
base2 = ((COSObject) base2).getObject();
279+
}
280+
walk(base2);
281+
}
282+
}
283+
else if (base instanceof COSDictionary)
284+
{
285+
COSDictionary kdict = (COSDictionary) base;
286+
if (kdict.containsKey(COSName.PG))
287+
{
288+
++cnt;
289+
set.add(kdict);
290+
}
291+
if (kdict.containsKey(COSName.K))
292+
{
293+
walk(kdict.getDictionaryObject(COSName.K));
294+
}
295+
}
296+
}
223297
}
224298

225299
// Each element can be an array, a dictionary or a number.
226-
// See PDF specification Table 37 – Entries in a number tree node dictionary
227-
// See PDF specification Table 322 – Entries in the structure tree root
300+
// See PDF specification Table 37 - Entries in a number tree node dictionary
301+
// See PDF specification Table 322 - Entries in the structure tree root
302+
// See PDF specification Table 323 - Entries in a structure element dictionary
228303
// example of file with /Kids: 000153.pdf 000208.pdf 000314.pdf 000359.pdf 000671.pdf
229304
// from digitalcorpora site
230305
private void checkElement(PDPageTree pageTree, COSBase base)

library/src/androidTest/java/com/tom_roush/pdfbox/pdfparser/TestPDFParserInstrumentation.java

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
package com.tom_roush.pdfbox.pdfparser;
22

33
import android.content.Context;
4-
import android.util.Log;
54

65
import androidx.test.platform.app.InstrumentationRegistry;
76

87
import java.io.File;
9-
import java.io.FileOutputStream;
108
import java.io.IOException;
11-
import java.io.InputStream;
12-
import java.net.URL;
139

1410
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
15-
import com.tom_roush.pdfbox.io.IOUtils;
11+
import com.tom_roush.pdfbox.android.TestResourceGenerator;
1612
import com.tom_roush.pdfbox.pdmodel.PDDocument;
1713
import com.tom_roush.pdfbox.rendering.PDFRenderer;
1814

1915
import org.junit.Before;
2016
import org.junit.Test;
2117

2218
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assume.assumeNotNull;
2320

2421
public class TestPDFParserInstrumentation
2522
{
@@ -42,23 +39,8 @@ public void testPDFBox3950() throws IOException
4239
{
4340
File TARGETPDFDIR = new File(testContext.getCacheDir(), "pdfs");
4441
TARGETPDFDIR.mkdirs();
45-
File pdfFile = new File(TARGETPDFDIR, "PDFBOX-3950-23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf");
46-
47-
if (!pdfFile.exists())
48-
{
49-
try
50-
{
51-
Log.i("PdfBox-Android", "PDF not cached, Downloading PDF for TestPDFParser.testPDFBox3950");
52-
InputStream pdfUrlStream = new URL("https://issues.apache.org/jira/secure/attachment/12890042/23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf")
53-
.openStream();
54-
IOUtils.copy(pdfUrlStream, new FileOutputStream(pdfFile));
55-
}
56-
catch (Exception e)
57-
{
58-
Log.w("PdfBox-Android", "Unable to download test PDF. Skipping test TestPDFParser.testPDFBox3950");
59-
return;
60-
}
61-
}
42+
File pdfFile = TestResourceGenerator.downloadTestResource(TARGETPDFDIR, "PDFBOX-3950-23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf", "https://issues.apache.org/jira/secure/attachment/12890042/23EGDHXSBBYQLKYOKGZUOVYVNE675PRD.pdf");
43+
assumeNotNull(pdfFile);
6244

6345
PDDocument doc = PDDocument.load(pdfFile);
6446
assertEquals(4, doc.getNumberOfPages());

library/src/androidTest/java/com/tom_roush/pdfbox/pdmodel/font/PDFontTest.java

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package com.tom_roush.pdfbox.pdmodel.font;
1919

2020
import android.content.Context;
21-
import android.util.Log;
2221

2322
import androidx.test.platform.app.InstrumentationRegistry;
2423

@@ -27,14 +26,13 @@
2726
import java.io.FileInputStream;
2827
import java.io.FileOutputStream;
2928
import java.io.IOException;
30-
import java.io.InputStream;
3129
import java.io.OutputStream;
3230
import java.net.URISyntaxException;
33-
import java.net.URL;
3431

3532
import com.tom_roush.fontbox.ttf.TTFParser;
3633
import com.tom_roush.fontbox.ttf.TrueTypeFont;
3734
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
35+
import com.tom_roush.pdfbox.android.TestResourceGenerator;
3836
import com.tom_roush.pdfbox.cos.COSName;
3937
import com.tom_roush.pdfbox.io.IOUtils;
4038
import com.tom_roush.pdfbox.pdmodel.PDDocument;
@@ -48,6 +46,8 @@
4846
import org.junit.Before;
4947
import org.junit.Test;
5048

49+
import static org.junit.Assume.assumeNotNull;
50+
5151
/**
5252
*
5353
* @author adam
@@ -135,24 +135,8 @@ public void testPDFBox3826() throws IOException, URISyntaxException
135135
@Test
136136
public void testPDFBOX4115() throws IOException
137137
{
138-
File fontFile = new File(IN_DIR, "n019003l.pfb");
139-
140-
if (!fontFile.exists())
141-
{
142-
try
143-
{
144-
Log.i("PdfBox-Android", "Font not cached, Downloading font for PDFontTest.testPDFBOX4115");
145-
InputStream fontUrlStream = new URL(
146-
"https://issues.apache.org/jira/secure/attachment/12911053/n019003l.pfb")
147-
.openStream();
148-
IOUtils.copy(fontUrlStream, new FileOutputStream(fontFile));
149-
}
150-
catch (Exception e)
151-
{
152-
Log.w("PdfBox-Android", "Unable to download test font. Skipping test PDFontTest.testPDFBOX4115");
153-
return;
154-
}
155-
}
138+
File fontFile = TestResourceGenerator.downloadTestResource(IN_DIR, "n019003l.pfb", "https://issues.apache.org/jira/secure/attachment/12911053/n019003l.pfb");
139+
assumeNotNull(fontFile);
156140

157141
File outputFile = new File(OUT_DIR, "FontType1.pdf");
158142
String text = "äöüÄÖÜ";

0 commit comments

Comments
 (0)