This is an automated email from the ASF dual-hosted git repository.
tallison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new 94c681223 TIKA-3852 -- extract signature info at the document level
from PDFs
94c681223 is described below
commit 94c6812232a85c4a8dd24ba393055f58e7436fca
Author: tballison <[email protected]>
AuthorDate: Tue Sep 13 11:51:10 2022 -0400
TIKA-3852 -- extract signature info at the document level from PDFs
---
.../java/org/apache/tika/metadata/Metadata.java | 19 ++++++++
.../java/org/apache/tika/metadata/Property.java | 4 ++
.../apache/tika/metadata/TikaCoreProperties.java | 6 +++
.../tika-parser-pdf-module/pom.xml | 17 +++++++
.../java/org/apache/tika/parser/pdf/PDFParser.java | 35 ++++++++++++++
.../tika/parser/pdf/PDMetadataExtractor.java | 6 +++
.../org/apache/tika/parser/pdf/PDFParserTest.java | 56 ++++++++++++----------
.../src/test/resources/log4j2.xml | 42 ++++++++++++++++
8 files changed, 159 insertions(+), 26 deletions(-)
diff --git a/tika-core/src/main/java/org/apache/tika/metadata/Metadata.java
b/tika-core/src/main/java/org/apache/tika/metadata/Metadata.java
index 98de6d282..1614f8cca 100644
--- a/tika-core/src/main/java/org/apache/tika/metadata/Metadata.java
+++ b/tika-core/src/main/java/org/apache/tika/metadata/Metadata.java
@@ -590,6 +590,25 @@ public class Metadata
set(property, dateString);
}
+ /**
+ * Adds the date value of the identified metadata property.
+ *
+ * @param property simple calendar property definition
+ * @param date property value
+ * @since Apache Tika 2.5.0
+ */
+ public void add(Property property, Calendar date) {
+ if (property.getPrimaryProperty().getValueType() !=
Property.ValueType.DATE) {
+ throw new PropertyTypeException(Property.ValueType.DATE,
+ property.getPrimaryProperty().getValueType());
+ }
+ String dateString = null;
+ if (date != null) {
+ dateString = formatDate(date);
+ }
+ add(property, dateString);
+ }
+
/**
* Remove a metadata and all its associated values.
*
diff --git a/tika-core/src/main/java/org/apache/tika/metadata/Property.java
b/tika-core/src/main/java/org/apache/tika/metadata/Property.java
index 93614b72b..3d6714141 100644
--- a/tika-core/src/main/java/org/apache/tika/metadata/Property.java
+++ b/tika-core/src/main/java/org/apache/tika/metadata/Property.java
@@ -144,6 +144,10 @@ public final class Property implements
Comparable<Property> {
return new Property(name, true, ValueType.DATE);
}
+ public static Property internalDateBag(String name) {
+ return new Property(name, true, PropertyType.BAG, ValueType.DATE);
+ }
+
public static Property internalInteger(String name) {
return new Property(name, true, ValueType.INTEGER);
}
diff --git
a/tika-core/src/main/java/org/apache/tika/metadata/TikaCoreProperties.java
b/tika-core/src/main/java/org/apache/tika/metadata/TikaCoreProperties.java
index 79d80d658..03a0e2cd2 100644
--- a/tika-core/src/main/java/org/apache/tika/metadata/TikaCoreProperties.java
+++ b/tika-core/src/main/java/org/apache/tika/metadata/TikaCoreProperties.java
@@ -284,6 +284,12 @@ public interface TikaCoreProperties {
EmbeddedResourceType.THUMBNAIL.toString(),
EmbeddedResourceType.RENDERING.toString());
Property HAS_SIGNATURE = Property.internalBoolean("hasSignature");
+ Property SIGNATURE_NAME = Property.internalTextBag("signature:name");
+ Property SIGNATURE_DATE = Property.internalDateBag("signature:date");
+ Property SIGNATURE_LOCATION =
Property.internalTextBag("signature:location");
+ Property SIGNATURE_REASON = Property.internalTextBag("signature:reason");
+ Property SIGNATURE_FILTER = Property.internalTextBag("signature:filter");
+ Property SIGNATURE_CONTACT_INFO =
Property.internalTextBag("signature:contact-info");
/**
* A file might contain different types of embedded documents.
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/pom.xml
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/pom.xml
index fc655e0b9..4d8470026 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/pom.xml
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/pom.xml
@@ -80,6 +80,23 @@
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>${log4j2.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>${log4j2.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
<!-- incompatible with Apache license, only use in testing -->
<dependency>
<groupId>com.github.jai-imageio</groupId>
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
index e790378ae..94afd30db 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFParser.java
@@ -42,7 +42,9 @@ import
org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.fixup.AbstractFixup;
import org.apache.pdfbox.pdmodel.fixup.PDDocumentFixup;
import org.apache.pdfbox.pdmodel.fixup.processor.AcroFormDefaultsProcessor;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -178,6 +180,7 @@ public class PDFParser extends AbstractParser implements
RenderingParser, Initia
boolean hasXFA = hasXFA(pdfDocument, metadata);
boolean hasMarkedContent = hasMarkedContent(pdfDocument, metadata);
extractMetadata(pdfDocument, metadata, context);
+ extractSignatures(pdfDocument, metadata);
AccessChecker checker = localConfig.getAccessChecker();
checker.check(metadata);
renderPagesBeforeParse(tstream, handler, metadata, context,
localConfig);
@@ -218,6 +221,38 @@ public class PDFParser extends AbstractParser implements
RenderingParser, Initia
}
}
}
+ private void extractSignatures(PDDocument pdfDocument, Metadata metadata) {
+ boolean hasSignature = false;
+ try {
+ for (PDSignatureField signatureField :
pdfDocument.getSignatureFields()) {
+ PDSignature signature = signatureField.getSignature();
+ if (signature == null) {
+ continue;
+ }
+
PDMetadataExtractor.addNotNull(TikaCoreProperties.SIGNATURE_NAME,
+ signature.getName(), metadata);
+
+ Calendar date = signature.getSignDate();
+ if (date != null) {
+ metadata.add(TikaCoreProperties.SIGNATURE_DATE, date);
+ }
+
PDMetadataExtractor.addNotNull(TikaCoreProperties.SIGNATURE_CONTACT_INFO,
+ signature.getContactInfo(), metadata);
+
PDMetadataExtractor.addNotNull(TikaCoreProperties.SIGNATURE_FILTER,
+ signature.getFilter(), metadata);
+
PDMetadataExtractor.addNotNull(TikaCoreProperties.SIGNATURE_LOCATION,
+ signature.getLocation(), metadata);
+
PDMetadataExtractor.addNotNull(TikaCoreProperties.SIGNATURE_REASON,
+ signature.getReason(), metadata);
+ hasSignature = true;
+ }
+ } catch (IOException e) {
+ //swallow
+ }
+ if (hasSignature) {
+ metadata.set(TikaCoreProperties.HAS_SIGNATURE, hasSignature);
+ }
+ }
private boolean shouldSpool(PDFParserConfig localConfig) {
if (localConfig.getImageStrategy() ==
PDFParserConfig.IMAGE_STRATEGY.RENDER_PAGES_BEFORE_PARSE
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
index 34beb3f77..cb36de0a9 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
@@ -309,6 +309,12 @@ public class PDMetadataExtractor {
}
}
+ static void addNotNull(Property property, String value, Metadata metadata)
{
+ if (! StringUtils.isBlank(value)) {
+ metadata.add(property, value);
+ }
+ }
+
/**
* As of this writing, XMPSchema can contain bags or sequence lists
* for some attributes...despite standards documentation.
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
index e554a784a..585feb02c 100644
---
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
@@ -1390,32 +1390,36 @@ public class PDFParserTest extends TikaTest {
}
}
- /**
- @Test
- public void testWriteLimit() throws Exception {
- for (int i = 0; i < 10000; i += 13) {
- Metadata metadata =
testWriteLimit("testPDF_childAttachments.pdf", i);
- assertEquals("true",
metadata.get(TikaCoreProperties.WRITE_LIMIT_REACHED));
- int len =
metadata.get(TikaCoreProperties.TIKA_CONTENT).length();
- System.out.println(len + " : " + i);
- assertTrue(len <= i);
- }
- }
+ /**
+ * TODO -- need to test signature extraction
+ */
- private Metadata testWriteLimit(String fileName, int limit) throws
Exception {
- BasicContentHandlerFactory factory = new
BasicContentHandlerFactory(
- BasicContentHandlerFactory.HANDLER_TYPE.TEXT, limit
- );
- ContentHandler contentHandler = factory.getNewContentHandler();
- Metadata metadata = new Metadata();
- ParseContext parseContext = new ParseContext();
- try (InputStream is = getResourceAsStream("/test-documents/" +
fileName)) {
- AUTO_DETECT_PARSER.parse(is, contentHandler, metadata,
parseContext);
- } catch (WriteLimitReachedException e) {
- //e.printStackTrace();
- }
- metadata.set(TikaCoreProperties.TIKA_CONTENT,
contentHandler.toString());
- return metadata;
- }*/
+ /**
+ @Test
+ public void testWriteLimit() throws Exception {
+ for (int i = 0; i < 10000; i += 13) {
+ Metadata metadata = testWriteLimit("testPDF_childAttachments.pdf",
i);
+ assertEquals("true",
metadata.get(TikaCoreProperties.WRITE_LIMIT_REACHED));
+ int len = metadata.get(TikaCoreProperties.TIKA_CONTENT).length();
+ System.out.println(len + " : " + i);
+ assertTrue(len <= i);
+ }
+ }
+
+ private Metadata testWriteLimit(String fileName, int limit) throws
Exception {
+ BasicContentHandlerFactory factory = new BasicContentHandlerFactory(
+ BasicContentHandlerFactory.HANDLER_TYPE.TEXT, limit
+ );
+ ContentHandler contentHandler = factory.getNewContentHandler();
+ Metadata metadata = new Metadata();
+ ParseContext parseContext = new ParseContext();
+ try (InputStream is = getResourceAsStream("/test-documents/" +
fileName)) {
+ AUTO_DETECT_PARSER.parse(is, contentHandler, metadata,
parseContext);
+ } catch (WriteLimitReachedException e) {
+ //e.printStackTrace();
+ }
+ metadata.set(TikaCoreProperties.TIKA_CONTENT,
contentHandler.toString());
+ return metadata;
+ }*/
}
diff --git
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/resources/log4j2.xml
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/resources/log4j2.xml
new file mode 100644
index 000000000..6f4371a49
--- /dev/null
+++
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/test/resources/log4j2.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<Configuration status="WARN">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_ERR">
+ <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+ </Console>
+
+ <File name="pdfbox-appender"
fileName="logs/pdfbox-${sys:pipesClientId}.log">
+ <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+ </File>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ </Root>
+ <Logger name="org.apache.fontbox" level="ERROR" additivity="false">
+ <AppenderRef ref="pdfbox-appender"/>
+ </Logger>
+ <Logger name="org.apache.pdfbox" level="ERROR" additivity="false">
+ <AppenderRef ref="pdfbox-appender"/>
+ </Logger>
+ </Loggers>
+</Configuration>
\ No newline at end of file