This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/master by this push:
     new bb4458e  TIKA-3101 -- extract metadata from XMP basic schema
bb4458e is described below

commit bb4458e417116cfc1b7cba70783c5a97c9ec3681
Author: tallison <[email protected]>
AuthorDate: Mon Jun 1 10:03:00 2020 -0400

    TIKA-3101 -- extract metadata from XMP basic schema
---
 .../main/java/org/apache/tika/metadata/XMP.java    |  15 ++++-
 .../tika/parser/pdf/PDMetadataExtractor.java       |  69 ++++++++++++++++++++-
 .../org/apache/tika/parser/pdf/PDFParserTest.java  |  14 ++++-
 .../test-documents/testPDF_XMPBasicSchema.pdf      | Bin 0 -> 1577 bytes
 4 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/tika-core/src/main/java/org/apache/tika/metadata/XMP.java 
b/tika-core/src/main/java/org/apache/tika/metadata/XMP.java
index 43bca6b..d8f81b2 100644
--- a/tika-core/src/main/java/org/apache/tika/metadata/XMP.java
+++ b/tika-core/src/main/java/org/apache/tika/metadata/XMP.java
@@ -26,6 +26,14 @@ public interface XMP {
     String PREFIX_ = PREFIX + TikaCoreProperties.NAMESPACE_PREFIX_DELIMITER;
 
     /**
+     * An unordered array of text strings that unambiguously identify the 
resource
+     * within a given context. An array item may be qualified with 
xmpidq:Scheme
+     * (see 8.7, “xmpidq namespace”) to denote the formal identification 
system to
+     * which that identifier conforms.
+     */
+    Property ADVISORY = Property.externalTextBag(PREFIX_ + "Advisory");
+
+    /**
      * The date and time the resource was created. For a digital file, this 
need not
      * match a file-system creation time. For a freshly created resource, it 
should
      * be close to that time, modulo the time taken to write the file. Later 
file
@@ -49,7 +57,7 @@ public interface XMP {
     /**
      * A word or short phrase that identifies a resource as a member of a 
userdefined collection.
      */
-    Property LABEL = Property.externalDate(PREFIX_ + "Label");
+    Property LABEL = Property.externalText(PREFIX_ + "Label");
 
     /**
      * The date and time that any metadata for this resource was last changed. 
It
@@ -63,6 +71,11 @@ public interface XMP {
     Property MODIFY_DATE = Property.externalDate(PREFIX_ + "ModifyDate");
 
     /**
+     * A word or short phrase that identifies a resource as a member of a 
userdefined collection.
+     */
+    Property NICKNAME = Property.externalText(PREFIX_ + "NickName");
+
+    /**
      * A user-assigned rating for this file. The value shall be -1 or in the 
range
      * [0..5], where -1 indicates “rejected” and 0 indicates “unrated”. If 
xmp:Rating
      * is not present, a value of 0 should be assumed.
diff --git 
a/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
 
b/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
index 374471b..16605cb 100644
--- 
a/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
+++ 
b/tika-parsers/src/main/java/org/apache/tika/parser/pdf/PDMetadataExtractor.java
@@ -22,8 +22,10 @@ import java.util.Calendar;
 import java.util.List;
 import java.util.Locale;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.jempbox.xmp.XMPMetadata;
 import org.apache.jempbox.xmp.XMPSchema;
+import org.apache.jempbox.xmp.XMPSchemaBasic;
 import org.apache.jempbox.xmp.XMPSchemaDublinCore;
 import org.apache.jempbox.xmp.pdfa.XMPSchemaPDFAId;
 import org.apache.pdfbox.cos.COSArray;
@@ -38,6 +40,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.PDF;
 import org.apache.tika.metadata.Property;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.metadata.XMP;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.image.xmp.JempboxExtractor;
@@ -66,21 +69,26 @@ class PDMetadataExtractor {
             xmp = new XMPMetadata(dom);
         }
         XMPSchemaDublinCore dcSchema = null;
-
+        XMPSchemaBasic basic = null;
         if (xmp != null) {
             try {
                 dcSchema = xmp.getDublinCoreSchema();
             } catch (IOException e) {
             }
-
+            try {
+                basic = xmp.getBasicSchema();
+            } catch (IOException e) {
+                //swallow
+            }
             JempboxExtractor.extractXMPMM(xmp, metadata);
         }
-
         extractMultilingualItems(metadata, TikaCoreProperties.DESCRIPTION, 
null, dcSchema);
         extractDublinCoreListItems(metadata, TikaCoreProperties.CONTRIBUTOR, 
dcSchema);
         extractDublinCoreListItems(metadata, TikaCoreProperties.CREATOR, 
dcSchema);
         extractMultilingualItems(metadata, TikaCoreProperties.TITLE, null, 
dcSchema);
 
+        extractBasic(basic, metadata);
+
         try {
             if (xmp != null) {
                 xmp.addXMLNSMapping(XMPSchemaPDFAId.NAMESPACE, 
XMPSchemaPDFAId.class);
@@ -104,6 +112,61 @@ class PDMetadataExtractor {
         }
     }
 
+    private static void extractBasic(XMPSchemaBasic basic, Metadata metadata) {
+        if (basic == null) {
+            return;
+        }
+        //add the elements from the basic schema if they haven't already
+        //been extracted from dublin core
+        setNotNull(XMP.CREATOR_TOOL, basic.getCreatorTool(), metadata);
+        setNotNull(XMP.LABEL, basic.getLabel(), metadata);
+        try {
+            setNotNull(XMP.CREATE_DATE, basic.getCreateDate(), metadata);
+        } catch (IOException e) {
+        }
+        try {
+            setNotNull(XMP.MODIFY_DATE, basic.getModifyDate(), metadata);
+        } catch (IOException e) {
+        }
+        try {
+            setNotNull(XMP.METADATA_DATE, basic.getMetadataDate(), metadata);
+        } catch (IOException e) {
+        }
+
+        List<String> identifiers = basic.getIdentifiers();
+        if (identifiers != null) {
+            for (String identifier : identifiers) {
+                metadata.add(XMP.IDENTIFIER, identifier);
+            }
+        }
+        List<String> advisories = basic.getAdvisories();
+        if (advisories != null) {
+            for (String advisory : advisories) {
+                metadata.add(XMP.ADVISORY, advisory);
+            }
+        }
+        setNotNull(XMP.NICKNAME, basic.getNickname(), metadata);
+        setNotNull(XMP.RATING, basic.getRating(), metadata);
+    }
+
+    private static void setNotNull(Property property, String value, Metadata 
metadata) {
+        if (metadata.get(property) == null && ! StringUtils.isEmpty(value)) {
+            metadata.set(property, value);
+        }
+    }
+
+    private static void setNotNull(Property property, Calendar value, Metadata 
metadata) {
+        if (metadata.get(property) == null && value != null) {
+            metadata.set(property, value);
+        }
+    }
+
+    private static void setNotNull(Property property, Integer value, Metadata 
metadata) {
+        if (metadata.get(property) == null && value != null) {
+            metadata.set(property, value);
+        }
+    }
+
     /**
      * As of this writing, XMPSchema can contain bags or sequence lists
      * for some attributes...despite standards documentation.
diff --git 
a/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java 
b/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
index 08ef5f7..bca4da5 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
 import java.io.InputStream;
+import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -56,6 +57,7 @@ import org.apache.tika.metadata.Office;
 import org.apache.tika.metadata.OfficeOpenXMLCore;
 import org.apache.tika.metadata.PDF;
 import org.apache.tika.metadata.TikaCoreProperties;
+import org.apache.tika.metadata.XMP;
 import org.apache.tika.metadata.XMPMM;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.parser.AutoDetectParser;
@@ -1548,7 +1550,15 @@ public class PDFParserTest extends TikaTest {
         assertEquals(35, max);
     }
 
-
+    @Test
+    public void testXMPBasicSchema() throws Exception {
+        //TIKA-3101
+        List<Metadata> metadataList = 
getRecursiveMetadata("testPDF_XMPBasicSchema.pdf");
+        Metadata m = metadataList.get(0);
+        //these two fields derive from the basic schema in the XMP, not dublin 
core
+        assertEquals("Hewlett-Packard MFP", m.get(XMP.CREATOR_TOOL));
+        assertEquals("1998-08-29T13:53:15Z", m.get(XMP.CREATE_DATE));
+    }
     /**
      * Simple class to count end of document events.  If functionality is 
useful,
      * move to org.apache.tika in src/test
@@ -1577,4 +1587,6 @@ public class PDFParserTest extends TikaTest {
             return true;
         }
     }
+
+
 }
diff --git 
a/tika-parsers/src/test/resources/test-documents/testPDF_XMPBasicSchema.pdf 
b/tika-parsers/src/test/resources/test-documents/testPDF_XMPBasicSchema.pdf
new file mode 100644
index 0000000..69c912e
Binary files /dev/null and 
b/tika-parsers/src/test/resources/test-documents/testPDF_XMPBasicSchema.pdf 
differ

Reply via email to