PDFParser extends AbstractParser implements Initializable { public void parse( InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException { PDFParserConfig localConfig = context.get(PDFParserConfig.class, defaultConfig); if (localConfig.getSetKCMS()) { System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider"); } PDDocument pdfDocument = null; String password = ""; try { TikaInputStream tstream = TikaInputStream.cast(stream); password = getPassword(metadata, context); MemoryUsageSetting memoryUsageSetting = MemoryUsageSetting.setupMainMemoryOnly(); if (localConfig.getMaxMainMemoryBytes() >= 0) { memoryUsageSetting = MemoryUsageSetting.setupMixed(localConfig.getMaxMainMemoryBytes()); } if (tstream != null && tstream.hasFile()) { pdfDocument = getPDDocument(tstream, password, memoryUsageSetting, metadata, context); } else { pdfDocument = getPDDocument(new CloseShieldInputStream(stream), password, memoryUsageSetting, metadata, context); } metadata.set(PDF.IS_ENCRYPTED, Boolean.toString(pdfDocument.isEncrypted())); metadata.set(Metadata.CONTENT_TYPE, MEDIA_TYPE.toString()); extractMetadata(pdfDocument, metadata, context); AccessChecker checker = localConfig.getAccessChecker(); checker.check(metadata); if (handler != null) { boolean hasXFA = hasXFA(pdfDocument); metadata.set(PDF.HAS_XFA, Boolean.toString(hasXFA)); boolean hasMarkedContent = hasMarkedContent(pdfDocument); metadata.set(PDF.HAS_MARKED_CONTENT, Boolean.toString(hasMarkedContent)); if (shouldHandleXFAOnly(hasXFA, localConfig)) { handleXFAOnly(pdfDocument, handler, metadata, context); } else if (localConfig.getOcrStrategy().equals(PDFParserConfig.OCR_STRATEGY.OCR_ONLY)) { metadata.add("X-Parsed-By", TesseractOCRParser.class.toString()); OCR2XHTML.process(pdfDocument, handler, context, metadata, localConfig); } else if (hasMarkedContent && localConfig.getExtractMarkedContent()) { PDFMarkedContent2XHTML.process(pdfDocument, handler, context, metadata, localConfig); } else { if (localConfig.getOcrStrategy().equals(PDFParserConfig.OCR_STRATEGY.OCR_AND_TEXT_EXTRACTION)) { metadata.add("X-Parsed-By", TesseractOCRParser.class.toString()); } PDF2XHTML.process(pdfDocument, handler, context, metadata, localConfig); } } } catch (InvalidPasswordException e) { metadata.set(PDF.IS_ENCRYPTED, "true"); throw new EncryptedDocumentException(e); } finally { if (pdfDocument != null) { pdfDocument.close(); } } }  Set<MediaType> getSupportedTypes(ParseContext context); void parse(
            InputStream stream, ContentHandler handler,
            Metadata metadata, ParseContext context); PDFParserConfig getPDFParserConfig(); void setPDFParserConfig(PDFParserConfig config); boolean getEnableAutoSpace(); @Field void setEnableAutoSpace(boolean v); boolean getExtractAnnotationText(); void setExtractAnnotationText(boolean v); boolean getSuppressDuplicateOverlappingText(); @Field void setSuppressDuplicateOverlappingText(boolean v); boolean getSortByPosition(); @Field void setSortByPosition(boolean v); @Field void setOcrStrategy(String ocrStrategyString); @Field void setOcrImageType(String imageType); void setInitializableProblemHandler(InitializableProblemHandler initializableProblemHandler); @Field void setDropThreshold(float dropThreshold); @Field void setMaxMainMemoryBytes(long maxMainMemoryBytes); @Override void initialize(Map<String, Param> params); @Override void checkInitialization(InitializableProblemHandler handler); static final String PASSWORD; }
@Test public void testProtectedPDF() throws Exception { XMLResult r = getXML("testPDF_protected.pdf"); Metadata metadata = r.metadata; assertEquals("true", metadata.get("pdf:encrypted")); assertEquals("application/pdf", metadata.get(Metadata.CONTENT_TYPE)); assertEquals("The Bank of England", metadata.get(TikaCoreProperties.CREATOR)); assertEquals("Speeches by Andrew G Haldane", metadata.get(OfficeOpenXMLCore.SUBJECT)); assertEquals("Rethinking the Financial Network, Speech by Andrew G Haldane, Executive Director, Financial Stability delivered at the Financial Student Association, Amsterdam on 28 April 2009", metadata.get(TikaCoreProperties.TITLE)); assertContains("RETHINKING THE FINANCIAL NETWORK", r.xml); assertContains("On 16 November 2002", r.xml); assertContains("In many important respects", r.xml); ParseContext context = new ParseContext(); context.set(PasswordProvider.class, new PasswordProvider() { public String getPassword(Metadata metadata) { return ""; } }); r = getXML("testPDF_protected.pdf", context); metadata = r.metadata; assertEquals("true", metadata.get("pdf:encrypted")); assertEquals("application/pdf", metadata.get(Metadata.CONTENT_TYPE)); assertEquals("The Bank of England", metadata.get(TikaCoreProperties.CREATOR)); assertEquals("Speeches by Andrew G Haldane", metadata.get(OfficeOpenXMLCore.SUBJECT)); assertEquals("Rethinking the Financial Network, Speech by Andrew G Haldane, Executive Director, Financial Stability delivered at the Financial Student Association, Amsterdam on 28 April 2009", metadata.get(TikaCoreProperties.TITLE)); assertContains("RETHINKING THE FINANCIAL NETWORK", r.xml); assertContains("On 16 November 2002", r.xml); assertContains("In many important respects", r.xml); context.set(PasswordProvider.class, new PasswordProvider() { public String getPassword(Metadata metadata) { return "WRONG!!!!"; } }); boolean ex = false; ContentHandler handler = new BodyContentHandler(); metadata = new Metadata(); try (InputStream stream = PDFParserTest.class.getResourceAsStream( "/test-documents/testPDF_protected.pdf")) { AUTO_DETECT_PARSER.parse(stream, handler, metadata, context); } catch (EncryptedDocumentException e) { ex = true; } assertTrue("encryption exception", ex); assertEquals("application/pdf", metadata.get(Metadata.CONTENT_TYPE)); assertEquals("true", metadata.get("pdf:encrypted")); assertEquals("very little metadata should be parsed", 3, metadata.names().length); assertEquals(0, handler.toString().length()); }
@Test public void testSingleCloseDoc() throws Exception { Metadata m = new Metadata(); ParseContext c = new ParseContext(); ContentHandler h = new EventCountingHandler(); try(InputStream is = PDFParserTest.class.getResourceAsStream( "/test-documents/testPDFTripleLangTitle.pdf")) { AUTO_DETECT_PARSER.parse(is, h, m, c); } assertEquals(1, ((EventCountingHandler) h).getEndDocument()); }
@Test public void testSkipBadPage() throws Exception { ContentHandler handler = new BodyContentHandler(-1); Metadata m = new Metadata(); ParseContext context = new ParseContext(); boolean tikaEx = false; try (InputStream is = getResourceAsStream("/test-documents/testPDF_bad_page_303226.pdf")) { AUTO_DETECT_PARSER.parse(is, handler, m, context); } catch (TikaException e) { tikaEx = true; } String content = handler.toString(); assertTrue("Should have thrown exception", tikaEx); assertEquals(1, m.getValues(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING).length); assertContains("Unknown dir", m.get(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING)); assertContains("1309.61", content); PDFParserConfig config = new PDFParserConfig(); config.setCatchIntermediateIOExceptions(false); context.set(PDFParserConfig.class, config); handler = new BodyContentHandler(-1); m = new Metadata(); tikaEx = false; try (InputStream is = getResourceAsStream("/test-documents/testPDF_bad_page_303226.pdf")) { AUTO_DETECT_PARSER.parse(is, handler, m, context); } catch (TikaException e) { tikaEx = true; } content = handler.toString(); assertTrue("Should have thrown exception", tikaEx); assertEquals(0, m.getValues(TikaCoreProperties.TIKA_META_EXCEPTION_WARNING).length); assertNotContained("1309.61", content); }