This is an automated email from the ASF dual-hosted git repository. tballison pushed a commit to branch TIKA-4872 in repository https://gitbox.apache.org/repos/asf/tika.git
commit 6a68b07cc10d08e5f0bcf52cdb054ca8514f27d6 Author: tallison <[email protected]> AuthorDate: Wed Sep 2 16:04:17 2026 -0400 improve documentation --- docs/modules/ROOT/pages/configuration/index.adoc | 10 ++-- .../parser/enricher/CompositeContentEnricher.java | 32 +++++-------- .../tika/parser/enricher/ContentEnrichers.java | 56 +++++++--------------- .../tika/parser/enricher/EnrichingParser.java | 4 +- .../parser/enricher/LegacyDispatchEnricher.java | 22 ++++----- .../tika/parser/enricher/ContentEnrichersTest.java | 8 ++-- .../apache/tika/parser/image/ImageParserTest.java | 10 ++-- .../apache/tika/parser/ocr/TesseractOCRParser.java | 2 +- .../org/apache/tika/parser/pdf/PDFParserTest.java | 5 +- .../org/apache/tika/pipes/core/MockEnricher.java | 5 +- .../apache/tika/pipes/core/PipesClientTest.java | 5 +- .../tika/config/loader/ContentEnricherLoader.java | 12 ++--- .../apache/tika/config/loader/ParserLoader.java | 12 ++--- .../config/loader/ContentEnricherLoaderTest.java | 3 +- .../tika/config/loader/EnrichingTestParser.java | 5 +- .../apache/tika/config/loader/TestPngEnricher.java | 5 +- .../config/loader/TestUnavailableEnricher.java | 5 +- 17 files changed, 72 insertions(+), 129 deletions(-) diff --git a/docs/modules/ROOT/pages/configuration/index.adoc b/docs/modules/ROOT/pages/configuration/index.adoc index 8a1c25f468..dc90e9fee9 100644 --- a/docs/modules/ROOT/pages/configuration/index.adoc +++ b/docs/modules/ROOT/pages/configuration/index.adoc @@ -149,11 +149,11 @@ order listed — so an OCR engine followed by a VLM that tags images is two entr per image. The list is authoritative: a media type no configured enricher matches gets no enrichment — never a classpath engine you did not name — and a named engine that reports no media types at startup (missing native binary, unreachable inference server) fails config load -rather than going silently inert. Failures are best-effort: one enricher failing does not stop the others, and every -failure is still reported through the parser's normal exception handling (timeouts abort the -chain immediately). With no `content-enrichers` configured, behavior is unchanged — whichever -OCR engine is on the classpath is used, exactly as before, and a WARN is logged at startup when -several engines collide. Engine names: `tesseract-ocr-parser`, `tess4j-parser`, `openai-vlm-parser`, +rather than going silently inert. Failures are best-effort: one enricher failing does not stop +the others, and every failure is still reported through the parser's normal exception handling +(timeouts abort the chain immediately). With no `content-enrichers` configured, behavior is +unchanged — whichever OCR engine is on the classpath is used, exactly as before, and a WARN is +logged at startup when several engines collide. Engine names: `tesseract-ocr-parser`, `tess4j-parser`, `openai-vlm-parser`, `claude-vlm-parser`, `gemini-vlm-parser`. == Windows file paths diff --git a/tika-core/src/main/java/org/apache/tika/parser/enricher/CompositeContentEnricher.java b/tika-core/src/main/java/org/apache/tika/parser/enricher/CompositeContentEnricher.java index 767ab9d3cf..398b3fb225 100644 --- a/tika-core/src/main/java/org/apache/tika/parser/enricher/CompositeContentEnricher.java +++ b/tika-core/src/main/java/org/apache/tika/parser/enricher/CompositeContentEnricher.java @@ -29,24 +29,15 @@ import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; /** - * Media-type-keyed registry of content enrichers: ordinary {@link Parser}s that a - * container parser <em>invokes</em> on bytes it has already parsed to obtain derived - * content (OCR text for an image, for a rendered PDF page, ...), rather than being - * dispatched to by the composite parser. + * Media-type-keyed registry of content enrichers: ordinary {@link Parser}s that a container + * parser <em>invokes</em> on bytes it has already parsed (OCR text for an image or a + * rendered PDF page), rather than being dispatched to by the composite parser. Configured + * as the top-level {@code "content-enrichers"} list, mirroring {@code "renderers"}. * <p> - * Configured as the top-level {@code "content-enrichers"} list, mirroring - * {@code "renderers"}; members advertise their <em>real</em> media types - * ({@code image/png}). Legacy OCR engines that still advertise the {@code image/ocr-*} - * pseudo-types are keyed under the corresponding real type, so they are nameable here - * without modification. An enricher registered here does not - * compete with the parser registered for the same type: the parser still runs and calls - * the enricher. - * <p> - * <b>Every</b> enricher matching a media type runs, in config order — e.g. an OCR engine - * followed by a VLM tagger for the same image. Output lands at the caller's chosen - * position in that order. Failures are best-effort: one enricher's failure does not stop - * the others; the first failure is rethrown after the chain completes with later ones - * suppressed. Timeouts, SecurityException and SAXException abort the chain immediately. + * Members advertise their <em>real</em> media types ({@code image/png}); legacy engines + * still advertising the {@code image/ocr-*} pseudo-types are keyed under the real type, so + * they are nameable here unmodified. An enricher does not compete with the parser + * registered for the same type: that parser still runs and calls the enricher. * * @since Apache Tika 4.1 */ @@ -61,8 +52,7 @@ public class CompositeContentEnricher implements Serializable { ParseContext empty = new ParseContext(); for (Parser enricher : enrichers) { for (MediaType mediaType : enricher.getSupportedTypes(empty)) { - // legacy engines (Tesseract, VLM, ...) still advertise the image/ocr-* - // pseudo-types; key them under the real type so they are nameable here + // legacy engines advertise image/ocr-*; key under the real type MediaType keyType = stripLegacyOcrPrefix(mediaType.getBaseType()); List<Parser> forType = tmp.computeIfAbsent(keyType, k -> new ArrayList<>()); if (!forType.contains(enricher)) { @@ -84,8 +74,8 @@ public class CompositeContentEnricher implements Serializable { } /** - * @return the enrichers configured for this media type (parameters ignored; alias - * normalization is the caller's job), in config order; empty when none + * @return the enrichers for this media type in config order, empty when none; + * parameters are ignored, alias normalization is the caller's job */ public List<Parser> getEnrichers(MediaType mediaType) { List<Parser> enrichers = enricherMap.get(mediaType.getBaseType()); diff --git a/tika-core/src/main/java/org/apache/tika/parser/enricher/ContentEnrichers.java b/tika-core/src/main/java/org/apache/tika/parser/enricher/ContentEnrichers.java index 81abc69863..62db23d9a6 100644 --- a/tika-core/src/main/java/org/apache/tika/parser/enricher/ContentEnrichers.java +++ b/tika-core/src/main/java/org/apache/tika/parser/enricher/ContentEnrichers.java @@ -37,22 +37,11 @@ import org.apache.tika.parser.Parser; /** * Resolves the content enricher for a media type. * <p> - * Contract for call sites: - * <ul> - * <li>The caller owns placement: wrap the handler (e.g. an - * {@code EmbeddedContentHandler} over a {@code BodyContentHandler}) so the enricher - * cannot emit its own document structure or metadata dump into the caller's XHTML.</li> - * <li>The caller owns invocation granularity: once per image, per rendered page, per - * segment; the slot does not dictate.</li> - * <li>Resolve against the <em>detected</em> media type, captured at parse entry before - * the parser can refine Content-Type (e.g. a PDF re-typed to Illustrator mid-parse - * must still fire the enricher selected for the type it was dispatched on).</li> - * <li>The enricher writes into the caller's {@link Metadata}; the caller must not assume - * the metadata is untouched beyond the derived content.</li> - * <li>An enricher that re-enters parsing must propagate the caller's - * {@link ParseContext}: the recursion guard (like Tika's other in-parse limits) - * rides the context, so a fresh context defeats it.</li> - * </ul> + * Call sites: wrap the handler (an {@code EmbeddedContentHandler} over a + * {@code BodyContentHandler}) so the enricher cannot dump structure or metadata into the + * caller's XHTML; resolve on the <em>detected</em> type, captured before a parser can + * refine Content-Type mid-parse; and pass the caller's own {@link ParseContext} through -- + * the recursion guard rides it, so a fresh context defeats it. * * @since Apache Tika 4.1 */ @@ -63,18 +52,14 @@ public final class ContentEnrichers { /** * Returns the enricher to invoke for one media type, or null when none applies. - * A configured {@code "content-enrichers"} list is authoritative: every configured - * enricher matching the type runs, in config order, behind the single Parser - * returned here, and a type no configured enricher matches gets no enrichment -- - * never a classpath engine the user did not name. Only when no list is configured - * at all does the legacy {@code image/ocr-*} dispatch through the composite parser - * apply. Returns null while an enrichment is already in progress in this context, - * so an enricher that is (or invokes) a container parser cannot recurse into - * enrichment. + * A configured list is authoritative: every matching enricher runs, in config order, + * behind the Parser returned here, and an uncovered type gets no enrichment -- never a + * classpath engine nobody named. Legacy {@code image/ocr-*} dispatch applies only when + * no list is configured. Null while an enrichment is already in progress in this + * context, so an enricher that is (or invokes) a container parser cannot recurse. * - * @param enrichers the injected composite; may be null when none is configured + * @param enrichers the injected composite; may be null when none is configured * @param mediaType the real, normalized media type of the bytes; may be null - * @param context the parse context */ public static Parser get(CompositeContentEnricher enrichers, MediaType mediaType, ParseContext context) { @@ -102,13 +87,10 @@ public final class ContentEnrichers { } /** - * Runs each enricher in config order, best-effort: one enricher's failure does not - * stop the others. The first failure is rethrown after the chain completes, with - * later failures attached as suppressed, so call sites report every failure through - * their existing exception handling. Timeouts, SecurityException, SAXException - * (incl. write-limit aborts) and other runtime exceptions propagate immediately -- - * a spent budget or a suspect handler must not fund further enrichments -- with any - * earlier recorded failure attached as suppressed. + * Runs each enricher in config order, best-effort: the first failure is rethrown once + * the chain completes, later ones suppressed onto it. Timeouts, SecurityException, + * SAXException (incl. write-limit aborts) and runtime exceptions abort immediately, + * carrying any earlier failure -- a spent budget must not fund more enrichments. */ private static final class SequentialEnricher implements Parser { @@ -167,9 +149,8 @@ public final class ContentEnrichers { } /** - * Marks enrichment in progress around the delegate so {@link #get} refuses re-entry, - * and restores Content-Type afterwards: an enricher derives content, it does not get - * to re-type the caller's document. + * Marks enrichment in progress so {@link #get} refuses re-entry, and restores + * Content-Type: an enricher derives content, it does not re-type the document. */ private static final class GuardedEnricher implements Parser { @@ -195,8 +176,7 @@ public final class ContentEnrichers { context.set(ActiveEnrichment.class, active); } String contentType = metadata.get(HttpHeaders.CONTENT_TYPE); - // restore rather than clear: a nested invocation must not strip the - // outer enrichment's re-entry protection when it completes + // restore, don't clear: a nested call must not lift the outer guard boolean wasActive = active.active; active.active = true; try { diff --git a/tika-core/src/main/java/org/apache/tika/parser/enricher/EnrichingParser.java b/tika-core/src/main/java/org/apache/tika/parser/enricher/EnrichingParser.java index 087f34e184..f1b542e47a 100644 --- a/tika-core/src/main/java/org/apache/tika/parser/enricher/EnrichingParser.java +++ b/tika-core/src/main/java/org/apache/tika/parser/enricher/EnrichingParser.java @@ -17,8 +17,8 @@ package org.apache.tika.parser.enricher; /** - * A parser that invokes content enrichers (e.g. OCR on its images or rendered pages). - * The configured {@link CompositeContentEnricher} is injected at load time, the way + * A parser that invokes content enrichers (OCR on its images or rendered pages). The + * configured {@link CompositeContentEnricher} is injected at load time, as * {@link org.apache.tika.parser.RenderingParser} receives its renderer. * * @since Apache Tika 4.1 diff --git a/tika-core/src/main/java/org/apache/tika/parser/enricher/LegacyDispatchEnricher.java b/tika-core/src/main/java/org/apache/tika/parser/enricher/LegacyDispatchEnricher.java index f880250e2a..1f32bff1e0 100644 --- a/tika-core/src/main/java/org/apache/tika/parser/enricher/LegacyDispatchEnricher.java +++ b/tika-core/src/main/java/org/apache/tika/parser/enricher/LegacyDispatchEnricher.java @@ -34,15 +34,12 @@ import org.apache.tika.parser.Parser; /** * Reproduces the pre-4.1 {@code image/ocr-*} dispatch when no {@code "content-enrichers"} - * list is configured: mints the synthetic {@code ocr-} media type, sets - * {@link TikaCoreProperties#CONTENT_TYPE_PARSER_OVERRIDE} and re-enters the composite - * parser, restoring the metadata afterwards. Whichever engine won the {@code ocr-*} - * registration in the composite still wins here, so precedence-by-presence (adding - * e.g. tika-parser-tess4j-module to the classpath) is preserved exactly. - * <p> - * This confines the pseudo-mime dance formerly hand-rolled in both - * {@code AbstractImageParser} and {@code AbstractPDF2XHTML} to one class, to be retired - * once OCR engines are selected by name. + * list is configured: mints the synthetic {@code ocr-} type, sets + * {@link TikaCoreProperties#CONTENT_TYPE_PARSER_OVERRIDE}, re-enters the composite parser + * and restores the metadata. Whichever engine won the {@code ocr-*} registration still wins, + * so precedence-by-presence is preserved exactly. Confines the pseudo-mime dance formerly + * hand-rolled in {@code AbstractImageParser} and {@code AbstractPDF2XHTML} to one class; + * retire it once every engine is selected by name. * * @since Apache Tika 4.1 */ @@ -57,10 +54,9 @@ public class LegacyDispatchEnricher implements Parser { private final Parser composite; /** - * @param mediaType the real (already normalized) media type of the bytes to derive from - * @param composite the composite parser to re-enter; the caller has already verified - * it claims the synthetic {@code ocr-} type (re-verifying here would - * rebuild the composite's full supported-types map per invocation) + * @param mediaType the real (already normalized) media type of the bytes + * @param composite the composite to re-enter; the caller has already verified it claims + * the {@code ocr-} type -- re-checking rebuilds its full type map */ public LegacyDispatchEnricher(MediaType mediaType, Parser composite) { this.mediaType = mediaType; diff --git a/tika-core/src/test/java/org/apache/tika/parser/enricher/ContentEnrichersTest.java b/tika-core/src/test/java/org/apache/tika/parser/enricher/ContentEnrichersTest.java index 884a9972b5..416e08993e 100644 --- a/tika-core/src/test/java/org/apache/tika/parser/enricher/ContentEnrichersTest.java +++ b/tika-core/src/test/java/org/apache/tika/parser/enricher/ContentEnrichersTest.java @@ -124,8 +124,7 @@ public class ContentEnrichersTest { @Test public void testConfiguredListIsAuthoritative() throws Exception { - // the composite claims ocr-tiff, but a configured list that doesn't cover tiff - // must yield no enricher -- never a classpath engine the user did not name + // the composite claims ocr-tiff, but a list that doesn't cover tiff wins anyway RecordingParser explicit = new RecordingParser(Collections.singleton(PNG)); RecordingParser composite = new RecordingParser(Collections.singleton(MediaType.image("ocr-tiff"))); @@ -299,9 +298,8 @@ public class ContentEnrichersTest { } /** - * Legacy engines (Tesseract, the VLM parsers) advertise image/ocr-* pseudo-types; - * naming one as an enricher must still match the real type — and an engine - * advertising both the real and the pseudo form of a type must run once, not twice. + * A legacy engine's image/ocr-* advertisement must match the real type, and an engine + * advertising both forms must run once, not twice. */ @Test public void testLegacyOcrTypeAdvertisementsMatchRealTypes() throws Exception { diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-image-module/src/test/java/org/apache/tika/parser/image/ImageParserTest.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-image-module/src/test/java/org/apache/tika/parser/image/ImageParserTest.java index c8549f31d3..dd0596bdf9 100644 --- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-image-module/src/test/java/org/apache/tika/parser/image/ImageParserTest.java +++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-image-module/src/test/java/org/apache/tika/parser/image/ImageParserTest.java @@ -227,9 +227,8 @@ public class ImageParserTest extends TikaTest { } /** - * A content enricher selected by name advertises real types and is invoked by the - * image parser, which keeps extracting its own metadata -- the enricher does not - * displace it (TIKA-4872). + * A named enricher is invoked by the image parser, which keeps extracting its own + * metadata -- the enricher does not displace it (TIKA-4872). */ @Test public void testExplicitContentEnricher() throws Exception { @@ -261,9 +260,8 @@ public class ImageParserTest extends TikaTest { } /** - * The enricher is selected on the DETECTED media type, captured before the parser - * can refine Content-Type mid-parse (TIKA-4872): a parser that re-types the document - * during metadata extraction must still fire the enricher chosen at dispatch. + * A parser that re-types the document mid-parse must still fire the enricher chosen + * for the DETECTED type it was dispatched on (TIKA-4872). */ @Test public void testEnricherSelectedOnDetectedTypeNotRefinedType() throws Exception { diff --git a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java index 266abd7df8..6312df608c 100644 --- a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java +++ b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRParser.java @@ -96,7 +96,7 @@ import org.apache.tika.utils.XMLReaderUtils; * parseContext.set(TesseractOCRConfig.class, config);<br> * </p> */ -// name pinned: it is the documented "content-enrichers" selector for this engine +// name pinned: the documented "content-enrichers" selector for this engine @TikaComponent(name = "tesseract-ocr-parser") public class TesseractOCRParser extends AbstractExternalProcessParser implements Initializable { 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 02ebd1ffe0..8fd7eabd64 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 @@ -1662,9 +1662,8 @@ public class PDFParserTest extends TikaTest { } /** - * A content enricher selected by name -- advertising real image types, never the - * ocr- pseudo types, with no composite-parser registration at all -- receives every - * rendered page when OCR runs (TIKA-4872). + * A named enricher advertising real image types, with no composite registration at all, + * receives every rendered page when OCR runs (TIKA-4872). */ @Test public void testExplicitContentEnricherReceivesRenderedPages() throws Exception { diff --git a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/MockEnricher.java b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/MockEnricher.java index c51cf77238..73b499b270 100644 --- a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/MockEnricher.java +++ b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/MockEnricher.java @@ -30,10 +30,7 @@ import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; import org.apache.tika.sax.XHTMLContentHandler; -/** - * A content enricher selectable by name in "content-enrichers": proves the invocation - * and config path (is it run, does its output arrive) with no OCR binary installed. - */ +/** Fixture: proves the invocation and config path with no OCR binary installed. */ @TikaComponent(name = "mock-enricher", spi = false) public class MockEnricher implements Parser { diff --git a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java index ec1b7dc8ad..8233f939eb 100644 --- a/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java +++ b/tika-pipes/tika-pipes-integration-tests/src/test/java/org/apache/tika/pipes/core/PipesClientTest.java @@ -84,9 +84,8 @@ public class PipesClientTest { } /** - * Wire test for the content-enrichers slot (TIKA-4872): a config-named enricher must - * be injected into the fork's parsers and its output must survive the fork boundary. - * Uses MockEnricher, so no OCR binary is needed. + * Wire test for the content-enrichers slot (TIKA-4872): a config-named enricher is + * injected into the fork's parsers and its output survives the fork boundary. */ @Test public void testContentEnricherInFork(@TempDir Path tmp) throws Exception { diff --git a/tika-serialization/src/main/java/org/apache/tika/config/loader/ContentEnricherLoader.java b/tika-serialization/src/main/java/org/apache/tika/config/loader/ContentEnricherLoader.java index 98aeb535cf..781b3feb93 100644 --- a/tika-serialization/src/main/java/org/apache/tika/config/loader/ContentEnricherLoader.java +++ b/tika-serialization/src/main/java/org/apache/tika/config/loader/ContentEnricherLoader.java @@ -29,10 +29,9 @@ import org.apache.tika.parser.Parser; import org.apache.tika.parser.enricher.CompositeContentEnricher; /** - * Loads the top-level {@code "content-enrichers"} list: ordinary parsers, selected by - * component name, that container parsers invoke for derived content (OCR, ...). Members - * come from the same registry as {@code "parsers"} entries but do not join the composite - * parser's media-type dispatch. + * Loads the top-level {@code "content-enrichers"} list: parsers selected by component name + * that container parsers invoke for derived content (OCR, ...). Members come from the same + * registry as {@code "parsers"} entries but never join the composite's media-type dispatch. */ class ContentEnricherLoader implements ComponentLoader<CompositeContentEnricher> { @@ -55,9 +54,8 @@ class ContentEnricherLoader implements ComponentLoader<CompositeContentEnricher> throw new TikaConfigException( "Failed to load content enricher: " + entry.getKey(), e); } - // engines report no types when unusable (missing binary, unreachable server); - // the media-type snapshot taken here lasts the life of the process, so an - // explicitly named engine that can never run must fail load, not go silent + // this type snapshot lasts the life of the process, so an engine reporting + // nothing (missing binary, dead server) must fail load, not go silently inert if (enricher.getSupportedTypes(empty).isEmpty()) { throw new TikaConfigException("Content enricher \"" + entry.getKey() + "\" advertises no media types. Is the engine unavailable " diff --git a/tika-serialization/src/main/java/org/apache/tika/config/loader/ParserLoader.java b/tika-serialization/src/main/java/org/apache/tika/config/loader/ParserLoader.java index 9fb1cdbf64..383e908552 100644 --- a/tika-serialization/src/main/java/org/apache/tika/config/loader/ParserLoader.java +++ b/tika-serialization/src/main/java/org/apache/tika/config/loader/ParserLoader.java @@ -133,7 +133,6 @@ public class ParserLoader extends AbstractSpiComponentLoader<Parser> { @Override protected Parser postProcess(Parser parser, LoaderContext context) throws TikaConfigException { - // Inject EncodingDetector, Renderer and content enrichers into parsers that need them EncodingDetector encodingDetector = context.getEncodingDetector(); Renderer renderer = context.getRenderer(); CompositeContentEnricher contentEnrichers = context.getContentEnrichers(); @@ -170,12 +169,11 @@ public class ParserLoader extends AbstractSpiComponentLoader<Parser> { } /** - * The image/ocr-* pseudo-types are claimed by several OCR engines whose availability - * is environmental, and the composite resolves a collision by last registration with - * no warning. Name the collision and the winner once at load so engine selection is - * debuggable; select an engine explicitly with "content-enrichers". Skipped when - * content-enrichers is configured: the list is authoritative and legacy ocr-* - * dispatch never runs, so the collision is moot and the advice already taken. + * Several OCR engines can claim the same image/ocr-* pseudo-type -- availability is + * environmental -- and the composite resolves the collision silently by last + * registration; name the collision and the winner once at load. The caller skips this + * when content-enrichers is configured: that list is authoritative, so legacy dispatch + * never runs and the advice is already taken. */ private void warnOnAmbiguousOcrRegistrations(Parser parser) { if (!(parser instanceof CompositeParser cp)) { diff --git a/tika-serialization/src/test/java/org/apache/tika/config/loader/ContentEnricherLoaderTest.java b/tika-serialization/src/test/java/org/apache/tika/config/loader/ContentEnricherLoaderTest.java index 372987f348..49acce1070 100644 --- a/tika-serialization/src/test/java/org/apache/tika/config/loader/ContentEnricherLoaderTest.java +++ b/tika-serialization/src/test/java/org/apache/tika/config/loader/ContentEnricherLoaderTest.java @@ -69,8 +69,7 @@ public class ContentEnricherLoaderTest { @Test public void testZeroTypeEnricherFailsLoad() throws Exception { - // an explicitly named engine that cannot run (missing binary, unreachable - // server) must fail config load, not become a silent no-op + // a named engine that cannot run must fail load, not become a silent no-op TikaLoader loader = load(""" { "content-enrichers": [ {"test-unavailable-enricher": {}} ] diff --git a/tika-serialization/src/test/java/org/apache/tika/config/loader/EnrichingTestParser.java b/tika-serialization/src/test/java/org/apache/tika/config/loader/EnrichingTestParser.java index f3cbc2fe8b..aca501d486 100644 --- a/tika-serialization/src/test/java/org/apache/tika/config/loader/EnrichingTestParser.java +++ b/tika-serialization/src/test/java/org/apache/tika/config/loader/EnrichingTestParser.java @@ -30,10 +30,7 @@ import org.apache.tika.parser.Parser; import org.apache.tika.parser.enricher.CompositeContentEnricher; import org.apache.tika.parser.enricher.EnrichingParser; -/** - * Fixture for asserting that ParserLoader injects the configured content enrichers - * into parsers implementing {@link EnrichingParser}. - */ +/** Fixture: asserts ParserLoader injects the enrichers into an {@link EnrichingParser}. */ @TikaComponent(name = "enriching-test-parser", spi = false) public class EnrichingTestParser implements Parser, EnrichingParser { diff --git a/tika-serialization/src/test/java/org/apache/tika/config/loader/TestPngEnricher.java b/tika-serialization/src/test/java/org/apache/tika/config/loader/TestPngEnricher.java index 6dee97ef65..8e76753420 100644 --- a/tika-serialization/src/test/java/org/apache/tika/config/loader/TestPngEnricher.java +++ b/tika-serialization/src/test/java/org/apache/tika/config/loader/TestPngEnricher.java @@ -28,10 +28,7 @@ import org.apache.tika.mime.MediaType; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; -/** - * Content-enricher fixture: an ordinary parser advertising a real media type, - * selectable by name in the "content-enrichers" list. - */ +/** Fixture: an ordinary parser advertising a real media type, nameable in "content-enrichers". */ @TikaComponent(name = "test-png-enricher", spi = false) public class TestPngEnricher implements Parser { diff --git a/tika-serialization/src/test/java/org/apache/tika/config/loader/TestUnavailableEnricher.java b/tika-serialization/src/test/java/org/apache/tika/config/loader/TestUnavailableEnricher.java index 4f3f28d02e..313413e2e4 100644 --- a/tika-serialization/src/test/java/org/apache/tika/config/loader/TestUnavailableEnricher.java +++ b/tika-serialization/src/test/java/org/apache/tika/config/loader/TestUnavailableEnricher.java @@ -28,10 +28,7 @@ import org.apache.tika.mime.MediaType; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; -/** - * Content-enricher fixture mimicking an engine that is unusable at load time - * (missing binary, unreachable server): it advertises no media types. - */ +/** Fixture: an engine unusable at load time (missing binary, dead server) advertises nothing. */ @TikaComponent(name = "test-unavailable-enricher", spi = false) public class TestUnavailableEnricher implements Parser {
