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 ecabd9fa6 TIKA-4330 -- Add a MetadataListFilter
ecabd9fa6 is described below

commit ecabd9fa67788f8881b3b23c473c9fdd443c9375
Author: tallison <[email protected]>
AuthorDate: Tue Oct 22 07:19:19 2024 -0400

    TIKA-4330 -- Add a MetadataListFilter
---
 .../src/main/java/org/apache/tika/cli/TikaCLI.java |  4 +-
 .../src/main/java/org/apache/tika/gui/TikaGUI.java | 14 ++++--
 .../java/org/apache/tika/config/TikaConfig.java    | 11 ++++
 .../listfilter/CompositeMetadataListFilter.java    | 58 ++++++++++++++++++++++
 .../metadata/listfilter/MetadataListFilter.java    | 52 +++++++++++++++++++
 .../tika/metadata/listfilter/NoOpListFilter.java   | 28 +++++++++++
 .../java/org/apache/tika/pipes/PipesServer.java    | 39 ++++++++++++---
 .../listfilter/AttachmentCountingListFilter.java   | 33 ++++++++++++
 .../org/apache/tika/pipes/PipesClientTest.java     | 17 +++++++
 .../resources/test-documents/mock/embedded.xml     | 53 ++++++++++++++++++++
 .../core/resource/RecursiveMetadataResource.java   |  6 ++-
 11 files changed, 300 insertions(+), 15 deletions(-)

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 4aa5361ba..aa087910a 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
@@ -499,7 +499,9 @@ public class TikaCLI {
         }
         JsonMetadataList.setPrettyPrinting(prettyPrint);
         try (Writer writer = getOutputWriter(output, encoding)) {
-            JsonMetadataList.toJson(handler.getMetadataList(), writer);
+            List<Metadata> metadataList = handler.getMetadataList();
+            metadataList = config.getMetadataListFilter().filter(metadataList);
+            JsonMetadataList.toJson(metadataList, writer);
         }
     }
 
diff --git a/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java 
b/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
index 41ed93232..d314b472c 100644
--- a/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
+++ b/tika-app/src/main/java/org/apache/tika/gui/TikaGUI.java
@@ -38,6 +38,7 @@ import java.net.URL;
 import java.nio.file.Files;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import javax.swing.Box;
@@ -152,9 +153,11 @@ public class TikaGUI extends JFrame implements 
ActionListener, HyperlinkListener
      * File chooser.
      */
     private final JFileChooser chooser = new JFileChooser();
+    private final TikaConfig tikaConfig;
 
-    public TikaGUI(Parser parser) {
+    public TikaGUI(Parser parser, TikaConfig tikaConfig) {
         super("Apache Tika");
+        this.tikaConfig = tikaConfig;
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
         addMenuBar();
@@ -198,8 +201,9 @@ public class TikaGUI extends JFrame implements 
ActionListener, HyperlinkListener
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         final TikaConfig finalConfig = config;
         SwingUtilities.invokeLater(() -> new TikaGUI(
-                new DigestingParser(new AutoDetectParser(finalConfig), new 
CommonsDigester(MAX_MARK, CommonsDigester.DigestAlgorithm.MD5, 
CommonsDigester.DigestAlgorithm.SHA256),
-                        false)).setVisible(true));
+                new DigestingParser(new AutoDetectParser(finalConfig),
+                        new CommonsDigester(MAX_MARK, 
CommonsDigester.DigestAlgorithm.MD5, CommonsDigester.DigestAlgorithm.SHA256),
+                        false), finalConfig).setVisible(true));
     }
 
     private void addMenuBar() {
@@ -374,7 +378,9 @@ public class TikaGUI extends JFrame implements 
ActionListener, HyperlinkListener
             wrapper.parse(input, recursiveParserWrapperHandler, new 
Metadata(), new ParseContext());
             StringWriter jsonBuffer = new StringWriter();
             JsonMetadataList.setPrettyPrinting(true);
-            
JsonMetadataList.toJson(recursiveParserWrapperHandler.getMetadataList(), 
jsonBuffer);
+            List<Metadata> metadataList = 
recursiveParserWrapperHandler.getMetadataList();
+            metadataList = 
tikaConfig.getMetadataListFilter().filter(metadataList);
+            JsonMetadataList.toJson(metadataList, jsonBuffer);
             setText(json, jsonBuffer.toString());
         }
         layout.show(cards, "metadata");
diff --git a/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java 
b/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java
index e68ad10d6..63c72bfef 100644
--- a/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java
+++ b/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java
@@ -62,6 +62,8 @@ import org.apache.tika.language.translate.DefaultTranslator;
 import org.apache.tika.language.translate.Translator;
 import org.apache.tika.metadata.filter.MetadataFilter;
 import org.apache.tika.metadata.filter.NoOpFilter;
+import org.apache.tika.metadata.listfilter.MetadataListFilter;
+import org.apache.tika.metadata.listfilter.NoOpListFilter;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.mime.MediaTypeRegistry;
 import org.apache.tika.mime.MimeTypeException;
@@ -104,6 +106,7 @@ public class TikaConfig {
     private final EncodingDetector encodingDetector;
     private final Renderer renderer;
     private final MetadataFilter metadataFilter;
+    private final MetadataListFilter metadataListFilter;
     private final AutoDetectParserConfig autoDetectParserConfig;
 
     private static int MAX_JSON_STRING_FIELD_LENGTH = 
DEFAULT_MAX_JSON_STRING_FIELD_LENGTH;
@@ -177,6 +180,7 @@ public class TikaConfig {
         this.translator = translatorLoader.loadOverall(element, mimeTypes, 
loader);
         this.executorService = executorLoader.loadOverall(element, mimeTypes, 
loader);
         this.metadataFilter = MetadataFilter.load(element, true);
+        this.metadataListFilter = MetadataListFilter.load(element, true);
         this.autoDetectParserConfig = AutoDetectParserConfig.load(element);
         this.serviceLoader = loader;
         setMaxJsonStringFieldLength(element);
@@ -205,6 +209,7 @@ public class TikaConfig {
         this.translator = getDefaultTranslator(serviceLoader);
         this.executorService = getDefaultExecutorService();
         this.metadataFilter = new NoOpFilter();
+        this.metadataListFilter = new NoOpListFilter();
         this.autoDetectParserConfig = AutoDetectParserConfig.DEFAULT;
         TIMES_INSTANTIATED.incrementAndGet();
     }
@@ -251,6 +256,7 @@ public class TikaConfig {
             this.translator = getDefaultTranslator(serviceLoader);
             this.executorService = getDefaultExecutorService();
             this.metadataFilter = new NoOpFilter();
+            this.metadataListFilter = new NoOpListFilter();
             this.autoDetectParserConfig = AutoDetectParserConfig.DEFAULT;
         } else {
             ServiceLoader tmpServiceLoader = new ServiceLoader();
@@ -278,6 +284,7 @@ public class TikaConfig {
                 this.executorService =
                         executorLoader.loadOverall(element, mimeTypes, 
serviceLoader);
                 this.metadataFilter = MetadataFilter.load(element, true);
+                this.metadataListFilter = MetadataListFilter.load(element, 
true);
                 this.autoDetectParserConfig = 
AutoDetectParserConfig.load(element);
                 setMaxJsonStringFieldLength(element);
             } catch (SAXException e) {
@@ -629,6 +636,10 @@ public class TikaConfig {
         return metadataFilter;
     }
 
+    public MetadataListFilter getMetadataListFilter() {
+        return metadataListFilter;
+    }
+
     public AutoDetectParserConfig getAutoDetectParserConfig() {
         return autoDetectParserConfig;
     }
diff --git 
a/tika-core/src/main/java/org/apache/tika/metadata/listfilter/CompositeMetadataListFilter.java
 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/CompositeMetadataListFilter.java
new file mode 100644
index 000000000..cede25bd5
--- /dev/null
+++ 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/CompositeMetadataListFilter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+package org.apache.tika.metadata.listfilter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.metadata.Metadata;
+
+public class CompositeMetadataListFilter extends MetadataListFilter {
+
+    //no longer final to allow for no arg initialization during serialization
+    private List<MetadataListFilter> filters;
+
+    public CompositeMetadataListFilter() {
+        filters = new ArrayList<>();
+    }
+    public CompositeMetadataListFilter(List<MetadataListFilter> filters) {
+        this.filters = filters;
+    }
+
+    public void setFilters(List<MetadataListFilter> filters) {
+        this.filters.clear();
+        this.filters.addAll(filters);
+    }
+
+    public List<MetadataListFilter> getFilters() {
+        return filters;
+    }
+
+    @Override
+    public List<Metadata> filter(List<Metadata> metadataList) throws 
TikaException {
+        for (MetadataListFilter filter : filters) {
+            metadataList = filter.filter(metadataList);
+        }
+        return metadataList;
+    }
+
+    @Override
+    public String toString() {
+        return "CompositeMetadataListFilter{" + "filters=" + filters + '}';
+    }
+}
diff --git 
a/tika-core/src/main/java/org/apache/tika/metadata/listfilter/MetadataListFilter.java
 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/MetadataListFilter.java
new file mode 100644
index 000000000..93021da7c
--- /dev/null
+++ 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/MetadataListFilter.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.apache.tika.metadata.listfilter;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import org.apache.tika.config.ConfigBase;
+import org.apache.tika.exception.TikaConfigException;
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.filter.MetadataFilter;
+
+public abstract class MetadataListFilter extends ConfigBase implements 
Serializable {
+    /**
+     * Loads the metadata list filter from the config file if it exists, 
otherwise returns NoOpFilter
+     * @param root
+     * @return
+     * @throws TikaConfigException
+     * @throws IOException
+     */
+    public static MetadataListFilter load(Element root, boolean allowMissing) 
throws TikaConfigException,
+            IOException {
+        try {
+            return buildComposite("metadataListFilters", 
CompositeMetadataListFilter.class,
+                    "metadataListFilter", MetadataFilter.class, root);
+        } catch (TikaConfigException e) {
+            if (allowMissing && e.getMessage().contains("could not find 
metadataListFilters")) {
+                return new NoOpListFilter();
+            }
+            throw e;
+        }
+    }
+    public abstract List<Metadata> filter(List<Metadata> metadataList) throws 
TikaException;
+}
diff --git 
a/tika-core/src/main/java/org/apache/tika/metadata/listfilter/NoOpListFilter.java
 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/NoOpListFilter.java
new file mode 100644
index 000000000..68654e4f2
--- /dev/null
+++ 
b/tika-core/src/main/java/org/apache/tika/metadata/listfilter/NoOpListFilter.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+package org.apache.tika.metadata.listfilter;
+
+import java.util.List;
+
+import org.apache.tika.metadata.Metadata;
+
+public class NoOpListFilter extends MetadataListFilter {
+    @Override
+    public List<Metadata> filter(List<Metadata> metadataList) {
+        return metadataList;
+    }
+}
diff --git a/tika-core/src/main/java/org/apache/tika/pipes/PipesServer.java 
b/tika-core/src/main/java/org/apache/tika/pipes/PipesServer.java
index dffb7c9ce..e339b619f 100644
--- a/tika-core/src/main/java/org/apache/tika/pipes/PipesServer.java
+++ b/tika-core/src/main/java/org/apache/tika/pipes/PipesServer.java
@@ -58,6 +58,8 @@ import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.metadata.filter.MetadataFilter;
+import org.apache.tika.metadata.listfilter.MetadataListFilter;
+import org.apache.tika.metadata.listfilter.NoOpListFilter;
 import org.apache.tika.mime.MediaType;
 import org.apache.tika.parser.AutoDetectParser;
 import org.apache.tika.parser.DigestingParser;
@@ -400,11 +402,8 @@ public class PipesServer implements Runnable {
         long start = System.currentTimeMillis();
         String stack = getContainerStacktrace(t, parseData.getMetadataList());
         //we need to apply the metadata filter after we pull out the stacktrace
-        MetadataFilter filter = t.getParseContext().get(MetadataFilter.class);
-        if (filter == null) {
-            filter = tikaConfig.getMetadataFilter();
-        }
-        filterMetadata(filter, parseData.getMetadataList());
+        filterMetadata(t, parseData.getMetadataList());
+        filterMetadataList(t, parseData);
         ParseContext parseContext = t.getParseContext();
         FetchEmitTuple.ON_PARSE_EXCEPTION onParseException = 
t.getOnParseException();
         EmbeddedDocumentBytesConfig embeddedDocumentBytesConfig = 
parseContext.get(EmbeddedDocumentBytesConfig.class);
@@ -437,16 +436,35 @@ public class PipesServer implements Runnable {
         }
     }
 
-    private void filterMetadata(MetadataFilter metadataFilter, List<Metadata> 
metadataList) {
+    private void filterMetadata(FetchEmitTuple t, List<Metadata> metadataList) 
{
+        MetadataFilter filter = t.getParseContext().get(MetadataFilter.class);
+        if (filter == null) {
+            filter = tikaConfig.getMetadataFilter();
+        }
         for (Metadata m : metadataList) {
             try {
-                metadataFilter.filter(m);
+                filter.filter(m);
             } catch (TikaException e) {
                 LOG.warn("failed to filter metadata", e);
             }
         }
     }
 
+    private void filterMetadataList(FetchEmitTuple t, 
MetadataListAndEmbeddedBytes parseData) {
+        MetadataListFilter filter = 
t.getParseContext().get(MetadataListFilter.class);
+        if (filter == null) {
+            filter = tikaConfig.getMetadataListFilter();
+        }
+        if (filter instanceof NoOpListFilter) {
+            return;
+        }
+        try {
+            parseData.filter(filter);
+        } catch (TikaException e) {
+            LOG.warn("failed to filter metadata list", e);
+        }
+    }
+
     private Fetcher getFetcher(FetchEmitTuple t) {
         try {
             return fetcherManager.getFetcher(t.getFetchKey().getFetcherName());
@@ -830,7 +848,8 @@ public class PipesServer implements Runnable {
     }
 
     static class MetadataListAndEmbeddedBytes {
-        final List<Metadata> metadataList;
+
+        List<Metadata> metadataList;
         final Optional<EmbeddedDocumentBytesHandler> 
embeddedDocumentBytesHandler;
 
         public MetadataListAndEmbeddedBytes(List<Metadata> metadataList,
@@ -843,6 +862,10 @@ public class PipesServer implements Runnable {
             return metadataList;
         }
 
+        public void filter(MetadataListFilter filter) throws TikaException {
+            metadataList = filter.filter(metadataList);
+        }
+
         public EmbeddedDocumentBytesHandler getEmbeddedDocumentBytesHandler() {
             return embeddedDocumentBytesHandler.get();
         }
diff --git 
a/tika-core/src/test/java/org/apache/tika/metadata/listfilter/AttachmentCountingListFilter.java
 
b/tika-core/src/test/java/org/apache/tika/metadata/listfilter/AttachmentCountingListFilter.java
new file mode 100644
index 000000000..daa68c928
--- /dev/null
+++ 
b/tika-core/src/test/java/org/apache/tika/metadata/listfilter/AttachmentCountingListFilter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.apache.tika.metadata.listfilter;
+
+import java.util.List;
+
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.metadata.Metadata;
+
+public class AttachmentCountingListFilter extends MetadataListFilter {
+    @Override
+    public List<Metadata> filter(List<Metadata> metadataList) throws 
TikaException {
+        if (metadataList == null || metadataList.isEmpty()) {
+            return metadataList;
+        }
+        metadataList.get(0).set("X-TIKA:attachment_count", 
Integer.toString(metadataList.size() - 1));
+        return metadataList;
+    }
+}
diff --git a/tika-core/src/test/java/org/apache/tika/pipes/PipesClientTest.java 
b/tika-core/src/test/java/org/apache/tika/pipes/PipesClientTest.java
index 13b0dc312..35d52fc4a 100644
--- a/tika-core/src/test/java/org/apache/tika/pipes/PipesClientTest.java
+++ b/tika-core/src/test/java/org/apache/tika/pipes/PipesClientTest.java
@@ -32,6 +32,9 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.filter.CompositeMetadataFilter;
 import org.apache.tika.metadata.filter.MetadataFilter;
 import org.apache.tika.metadata.filter.MockUpperCaseFilter;
+import org.apache.tika.metadata.listfilter.AttachmentCountingListFilter;
+import org.apache.tika.metadata.listfilter.CompositeMetadataListFilter;
+import org.apache.tika.metadata.listfilter.MetadataListFilter;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.pipes.emitter.EmitKey;
 import org.apache.tika.pipes.fetcher.FetchKey;
@@ -76,4 +79,18 @@ public class PipesClientTest {
         Metadata metadata = pipesResult.getEmitData().getMetadataList().get(0);
         Assertions.assertEquals("TESTOVERLAPPINGTEXT.PDF", 
metadata.get("resourceName"));
     }
+
+    @Test
+    public void testMetadataListFilter() throws IOException, 
InterruptedException {
+        ParseContext parseContext = new ParseContext();
+        MetadataListFilter metadataFilter = new 
CompositeMetadataListFilter(List.of(new AttachmentCountingListFilter()));
+        parseContext.set(MetadataListFilter.class, metadataFilter);
+        PipesResult pipesResult = pipesClient.process(
+                new FetchEmitTuple("mock/embedded.xml", new 
FetchKey(fetcherName, "mock/embedded.xml"),
+                        new EmitKey(), new Metadata(), parseContext, 
FetchEmitTuple.ON_PARSE_EXCEPTION.SKIP));
+        Assertions.assertNotNull(pipesResult.getEmitData().getMetadataList());
+        Assertions.assertEquals(5, 
pipesResult.getEmitData().getMetadataList().size());
+        Metadata metadata = pipesResult.getEmitData().getMetadataList().get(0);
+        Assertions.assertEquals(4, 
Integer.parseInt(metadata.get("X-TIKA:attachment_count")));
+    }
 }
diff --git a/tika-core/src/test/resources/test-documents/mock/embedded.xml 
b/tika-core/src/test/resources/test-documents/mock/embedded.xml
new file mode 100644
index 000000000..c75c2fce6
--- /dev/null
+++ b/tika-core/src/test/resources/test-documents/mock/embedded.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+  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.
+-->
+
+<mock>
+
+  <metadata action="add" name="author">Nikolai Lobachevsky</metadata>
+  <write element="p">main_content</write>
+  <!-- auto detection wasn't working for some reason; add content-type as
+      is to trigger mock on the embedded -->
+  <embedded filename="embed1.xml" content-type="application/mock+xml">
+    &lt;mock&gt;
+    &lt;metadata action=&quot;add&quot; 
name=&quot;author&quot;&gt;embeddedAuthor&lt;/metadata&gt;
+    &lt;write element="p"&gt;some_embedded_content&lt;/write&gt;
+    &lt;/mock&gt;
+  </embedded>
+  <embedded filename="embed2.xml" content-type="application/mock+xml">
+    &lt;mock&gt;
+    &lt;metadata action=&quot;add&quot; 
name=&quot;author&quot;&gt;embeddedAuthor&lt;/metadata&gt;
+    &lt;write element="p"&gt;some_embedded_content&lt;/write&gt;
+    &lt;/mock&gt;
+  </embedded>
+  <embedded filename="embed3.xml" content-type="application/mock+xml">
+    &lt;mock&gt;
+    &lt;metadata action=&quot;add&quot; 
name=&quot;author&quot;&gt;embeddedAuthor&lt;/metadata&gt;
+    &lt;write element="p"&gt;some_embedded_content&lt;/write&gt;
+    &lt;/mock&gt;
+  </embedded>
+  <embedded filename="embed4.xml" content-type="application/mock+xml">
+    &lt;mock&gt;
+    &lt;metadata action=&quot;add&quot; 
name=&quot;author&quot;&gt;embeddedAuthor&lt;/metadata&gt;
+    &lt;write element="p"&gt;some_embedded_content&lt;/write&gt;
+    &lt;/mock&gt;
+  </embedded>
+
+</mock>
\ No newline at end of file
diff --git 
a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/RecursiveMetadataResource.java
 
b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/RecursiveMetadataResource.java
index a180ddfba..8b26a672a 100644
--- 
a/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/RecursiveMetadataResource.java
+++ 
b/tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/RecursiveMetadataResource.java
@@ -19,6 +19,7 @@ package org.apache.tika.server.core.resource;
 
 import static org.apache.tika.server.core.resource.TikaResource.fillMetadata;
 import static 
org.apache.tika.server.core.resource.TikaResource.fillParseContext;
+import static org.apache.tika.server.core.resource.TikaResource.getConfig;
 
 import java.io.InputStream;
 import java.util.List;
@@ -40,6 +41,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.tika.metadata.Metadata;
+import org.apache.tika.metadata.listfilter.MetadataListFilter;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.Parser;
 import org.apache.tika.parser.RecursiveParserWrapper;
@@ -84,8 +86,8 @@ public class RecursiveMetadataResource {
             //we shouldn't get here?
             LOG.error("something went seriously wrong", e);
         }
-
-        return handler.getMetadataList();
+        MetadataListFilter metadataListFilter = 
context.get(MetadataListFilter.class, getConfig().getMetadataListFilter());
+        return metadataListFilter.filter(handler.getMetadataList());
     }
 
     static HandlerConfig buildHandlerConfig(MultivaluedMap<String, String> 
httpHeaders, String handlerTypeName, HandlerConfig.PARSE_MODE parseMode) {

Reply via email to