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

tballison 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 7b36986bb7 TIKA-4885: clean up tika cli (#3144)
7b36986bb7 is described below

commit 7b36986bb7ce035aca23892052cbdff3e5a1f4e6
Author: Tim Allison <[email protected]>
AuthorDate: Tue Sep 8 16:26:02 2026 -0400

    TIKA-4885: clean up tika cli (#3144)
---
 CHANGES.txt                                        |  3 ++
 .../src/main/java/org/apache/tika/cli/TikaCLI.java | 58 +++++++---------------
 .../test/java/org/apache/tika/cli/TikaCLITest.java | 16 ++++++
 3 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 673a175fe8..95b46ec3af 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,8 @@
 Release 4.1.0 - unreleased
 
+   * tika-app's -m and --json wrote metadata at the SAX endDocument event
+     thereby dropping keys added by a parser after the endDocument (TIKA-4885).
+     
    * "content-enrichers": _mime-exclude now matches the real media type, so
      excluding image/tiff also drops a legacy image/ocr-tiff engine (it was
      a no-op). The zero-media-types check at config load asks the engine
diff --git a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java 
b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
index 1089229760..e6ba42a9d4 100644
--- a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
+++ b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
@@ -1384,41 +1384,28 @@ public class TikaCLI {
         }
     }
 
+    /** Swallows the document; {@link #output()} writes the metadata after the 
parse. */
     private static class NoDocumentMetHandler extends DefaultHandler {
 
         protected final Metadata metadata;
 
         protected PrintWriter writer;
 
-        private boolean metOutput;
-
         public NoDocumentMetHandler(Metadata metadata, PrintWriter writer) {
             this.metadata = metadata;
             this.writer = writer;
-            this.metOutput = false;
         }
 
-        @Override
-        public void endDocument() {
+        public void output() throws IOException {
             String[] names = metadata.names();
             Arrays.sort(names);
-            outputMetadata(names);
-            writer.flush();
-            this.metOutput = true;
-        }
-
-        public void outputMetadata(String[] names) {
             for (String name : names) {
                 for (String value : metadata.getValues(name)) {
                     writer.println(name + ": " + value);
                 }
             }
+            writer.flush();
         }
-
-        public boolean metOutput() {
-            return this.metOutput;
-        }
-
     }
 
     /**
@@ -1463,16 +1450,16 @@ public class TikaCLI {
 
     private class OutputType {
         public void process(TikaInputStream tis, OutputStream output, Metadata 
metadata) throws Exception {
-            Parser p = parser;
             ContentHandler handler = getContentHandler(output, metadata);
-            p.parse(tis, handler, metadata, context);
-            // fix for TIKA-596: if a parser doesn't generate
-            // XHTML output, the lack of an output document prevents
-            // metadata from being output: this fixes that
-            if (handler instanceof NoDocumentMetHandler) {
-                NoDocumentMetHandler metHandler = (NoDocumentMetHandler) 
handler;
-                if (!metHandler.metOutput()) {
-                    metHandler.endDocument();
+            try {
+                parser.parse(tis, handler, metadata, context);
+            } finally {
+                // Metadata is written once parse() returns, never at 
endDocument: parsers
+                // set keys after their SAX document ends (the PDF totals in a 
finally block,
+                // tk:parsed-by-full-set), some never start a document 
(TIKA-596), and a
+                // failed parse still has metadata worth showing before the 
error.
+                if (handler instanceof NoDocumentMetHandler metHandler) {
+                    metHandler.output();
                 }
             }
         }
@@ -1484,26 +1471,17 @@ public class TikaCLI {
     }
 
 
-    private class NoDocumentJSONMetHandler extends DefaultHandler {
-
-        protected final Metadata metadata;
-
-        protected PrintWriter writer;
+    private class NoDocumentJSONMetHandler extends NoDocumentMetHandler {
 
         public NoDocumentJSONMetHandler(Metadata metadata, PrintWriter writer) 
{
-            this.metadata = metadata;
-            this.writer = writer;
+            super(metadata, writer);
         }
 
         @Override
-        public void endDocument() throws SAXException {
-            try {
-                JsonMetadata.setPrettyPrinting(prettyPrint);
-                JsonMetadata.toJson(metadata, writer);
-                writer.flush();
-            } catch (IOException e) {
-                throw new SAXException(e);
-            }
+        public void output() throws IOException {
+            JsonMetadata.setPrettyPrinting(prettyPrint);
+            JsonMetadata.toJson(metadata, writer);
+            writer.flush();
         }
     }
 }
diff --git a/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java 
b/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
index b5efaeb364..1b3469a5f0 100644
--- a/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
+++ b/tika-app/src/test/java/org/apache/tika/cli/TikaCLITest.java
@@ -279,6 +279,22 @@ public class TikaCLITest {
         assertTrue(json.contains("\"tk:digest:MD2\":"));
     }
 
+    /**
+     * Keys a parser sets after its SAX document ends (the PDF parser's 
document totals in
+     * its finally block, tk:parsed-by-full-set from the composite) must still 
reach -m and
+     * --json, which used to write at endDocument.
+     */
+    @Test
+    public void testMetadataSetAfterEndDocumentIsOutput() throws Exception {
+        String content = getParamOutContent("-m", resourcePrefix + 
"testPDF_childAttachments.pdf");
+        assertTrue(content.contains("pdf:ocr-page-count: 0"), content);
+        assertTrue(content.contains("tk:parsed-by-full-set:"), content);
+
+        String json = getParamOutContent("--json", resourcePrefix + 
"testPDF_childAttachments.pdf");
+        assertTrue(json.contains("\"pdf:ocr-page-count\":"), json);
+        assertTrue(json.contains("\"tk:parsed-by-full-set\":"), json);
+    }
+
     /**
      * Test for -json with prettyprint option
      *

Reply via email to