This is an automated email from the ASF dual-hosted git repository. tballison pushed a commit to branch TIKA-4816-metadata-key-api in repository https://gitbox.apache.org/repos/asf/tika.git
commit 6acacb95e4b10f72a64a0cc93115c859f2574515 Author: tallison <[email protected]> AuthorDate: Tue Aug 11 15:36:22 2026 -0400 TIKA-4816 metadata-key stage 8: remove setAll, promote ClimateForcast (+strays), docs reconciliation --- .skills/metadata-schema.md | 3 ++ .../ROOT/pages/developers/metadata-keys.adoc | 9 ++++-- .../org/apache/tika/metadata/ClimateForcast.java | 34 ++++++++++++---------- .../org/apache/tika/metadata/CreativeCommons.java | 6 ++-- .../java/org/apache/tika/metadata/Metadata.java | 18 +----------- .../org/apache/tika/metadata/TikaMimeKeys.java | 28 ------------------ .../org/apache/tika/metadata/TestMetadata.java | 31 -------------------- .../apache/tika/metadata/metadata-key-fields.json | 18 ++++++++++++ .../org/apache/tika/metadata/metadata-keys.json | 18 ++++++++++++ .../metadata/schema/MetadataNoUnderscoreTest.java | 12 ++++++-- .../org/apache/tika/parser/grib/GribParser.java | 25 +++++++++++----- .../apache/tika/parser/netcdf/NetCDFParser.java | 25 +++++++++++----- .../main/java/org/apache/tika/xmp/XMPMetadata.java | 9 +++--- 13 files changed, 116 insertions(+), 120 deletions(-) diff --git a/.skills/metadata-schema.md b/.skills/metadata-schema.md index a31c02cc74..88a1351d00 100644 --- a/.skills/metadata-schema.md +++ b/.skills/metadata-schema.md @@ -65,6 +65,9 @@ Failures with stale `X-TIKA:`/underscore/`SHA256` keys usually mean *regenerate* ## Naming conventions (frozen for 4.0, TIKA-4794) - All keys are `Property` constants — no bare `String` keys (`metadata-string-keys.json` retired). + Exception: a few deprecated `String` fields (`IPTC.*_WRONG_CASE`, + `TikaCoreProperties.EMBEDDED_RESOURCE_TYPE_KEY`) exist only to construct a real `Property`'s + name and aren't independent keys. - Tika-coined prefix is `tk:` (`X-TIKA:` is legacy); kebab-case, no underscores. - External-standard names verbatim, *including* the standard's prefix: `dc:`, `xmp:`, `cp:`, `extended-properties:`. - HTTP has no namespace → `Content-Type`, `Content-Encoding`, `Location` stay bare (no `http:`). diff --git a/docs/modules/ROOT/pages/developers/metadata-keys.adoc b/docs/modules/ROOT/pages/developers/metadata-keys.adoc index 71ca570b70..90fd19ed1b 100644 --- a/docs/modules/ROOT/pages/developers/metadata-keys.adoc +++ b/docs/modules/ROOT/pages/developers/metadata-keys.adoc @@ -16,9 +16,12 @@ = Adding a Metadata Key Every metadata key Tika can emit is a `Property` constant (or, for runtime-minted names like scraped -HTML `<meta>` tags, a `KeyPrefix`) — there are no bare `String` keys. That closed/open key -space is tracked in a generated, build-gated registry, so adding a key involves one extra step beyond -writing the Java. +HTML `<meta>` tags, a `KeyPrefix`) — there are no bare `String` keys naming a population of writable +metadata. (A handful of `String` constants remain, e.g. `IPTC`'s four `*_WRONG_CASE` fields and +`TikaCoreProperties.EMBEDDED_RESOURCE_TYPE_KEY`; these are deprecated/internal building blocks that +construct a real `Property`'s name — not independent keys — and are excluded from the registry's key +count for that reason.) That closed/open key space is tracked in a generated, build-gated registry, so +adding a key involves one extra step beyond writing the Java. == Add the constant diff --git a/tika-core/src/main/java/org/apache/tika/metadata/ClimateForcast.java b/tika-core/src/main/java/org/apache/tika/metadata/ClimateForcast.java index 9ad1632837..ccffa8c980 100644 --- a/tika-core/src/main/java/org/apache/tika/metadata/ClimateForcast.java +++ b/tika-core/src/main/java/org/apache/tika/metadata/ClimateForcast.java @@ -18,38 +18,40 @@ package org.apache.tika.metadata; /** * Met keys from NCAR CCSM files in the <a - * href="http://cf-pcmdi.llnl.gov/">Climate Forecast Convention</a>. + * href="http://cf-pcmdi.llnl.gov/">Climate Forecast Convention</a>. Key spellings are the + * external convention's own attribute names, verbatim (not Tika-coined) — some contain + * underscores per that convention. */ public interface ClimateForcast { - String PROGRAM_ID = "prg_ID"; + Property PROGRAM_ID = Property.externalText("prg_ID"); - String COMMAND_LINE = "cmd_ln"; + Property COMMAND_LINE = Property.externalText("cmd_ln"); - String HISTORY = "history"; + Property HISTORY = Property.externalText("history"); - String TABLE_ID = "table_id"; + Property TABLE_ID = Property.externalText("table_id"); - String INSTITUTION = "institution"; + Property INSTITUTION = Property.externalText("institution"); - String SOURCE = "source"; + Property SOURCE = Property.externalText("source"); - String CONTACT = "contact"; + Property CONTACT = Property.externalText("contact"); - String PROJECT_ID = "project_id"; + Property PROJECT_ID = Property.externalText("project_id"); - String CONVENTIONS = "Conventions"; + Property CONVENTIONS = Property.externalText("Conventions"); - String REFERENCES = "references"; + Property REFERENCES = Property.externalText("references"); - String ACKNOWLEDGEMENT = "acknowledgement"; + Property ACKNOWLEDGEMENT = Property.externalText("acknowledgement"); - String REALIZATION = "realization"; + Property REALIZATION = Property.externalText("realization"); - String EXPERIMENT_ID = "experiment_id"; + Property EXPERIMENT_ID = Property.externalText("experiment_id"); - String COMMENT = "comment"; + Property COMMENT = Property.externalText("comment"); - String MODEL_NAME_ENGLISH = "model_name_english"; + Property MODEL_NAME_ENGLISH = Property.externalText("model_name_english"); } diff --git a/tika-core/src/main/java/org/apache/tika/metadata/CreativeCommons.java b/tika-core/src/main/java/org/apache/tika/metadata/CreativeCommons.java index 122a1fc578..2491d5e1a6 100644 --- a/tika-core/src/main/java/org/apache/tika/metadata/CreativeCommons.java +++ b/tika-core/src/main/java/org/apache/tika/metadata/CreativeCommons.java @@ -23,10 +23,10 @@ package org.apache.tika.metadata; */ public interface CreativeCommons { - String LICENSE_URL = "License-Url"; + Property LICENSE_URL = Property.externalText("License-Url"); - String LICENSE_LOCATION = "License-Location"; + Property LICENSE_LOCATION = Property.externalText("License-Location"); - String WORK_TYPE = "Work-Type"; + Property WORK_TYPE = Property.externalText("Work-Type"); } 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 9ea8385850..2a6dd56a1e 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 @@ -25,13 +25,11 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import java.util.Properties; import java.util.TimeZone; import org.slf4j.Logger; @@ -48,7 +46,7 @@ import org.apache.tika.utils.DateUtils; */ public class Metadata implements CreativeCommons, Geographic, HttpHeaders, Message, ClimateForcast, TIFF, - TikaMimeKeys, Serializable { + Serializable { private static final Logger LOG = LoggerFactory.getLogger(Metadata.class); @@ -448,20 +446,6 @@ public class Metadata } } - /** - * Copy All key-value pairs from properties. - * - * @param properties properties to copy from - */ - @SuppressWarnings("unchecked") - public void setAll(Properties properties) { - Enumeration<String> names = (Enumeration<String>) properties.propertyNames(); - while (names.hasMoreElements()) { - String name = names.nextElement(); - metadata.put(name, new String[]{properties.getProperty(name)}); - } - } - /** * Set metadata name/value. Associate the specified value to the specified * metadata name. If some previous values were associated to this name, diff --git a/tika-core/src/main/java/org/apache/tika/metadata/TikaMimeKeys.java b/tika-core/src/main/java/org/apache/tika/metadata/TikaMimeKeys.java deleted file mode 100644 index 7ae685e05e..0000000000 --- a/tika-core/src/main/java/org/apache/tika/metadata/TikaMimeKeys.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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; - -/** - * A collection of Tika metadata keys used in Mime Type resolution - */ -public interface TikaMimeKeys { - - String TIKA_MIME_FILE = "tika.mime.file"; - - String MIME_TYPE_MAGIC = "mime.type.magic"; - -} diff --git a/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java b/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java index 2ce1b8b6c6..e92fe4c3f0 100644 --- a/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java +++ b/tika-core/src/test/java/org/apache/tika/metadata/TestMetadata.java @@ -27,7 +27,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; -import java.util.Properties; import java.util.Random; import java.util.TimeZone; import java.util.concurrent.Callable; @@ -120,36 +119,6 @@ public class TestMetadata extends TikaTest { assertEquals("new value 2", values[1]); } - /** - * Test for <code>setAll(Properties)</code> method. - */ - @Test - public void testSetProperties() { - String[] values = null; - Metadata meta = new Metadata(); - Properties props = new Properties(); - - meta.setAll(props); - assertEquals(0, meta.size()); - - props.setProperty("name-one", "value1.1"); - meta.setAll(props); - assertEquals(1, meta.size()); - values = meta.getValues("name-one"); - assertEquals(1, values.length); - assertEquals("value1.1", values[0]); - - props.setProperty("name-two", "value2.1"); - meta.setAll(props); - assertEquals(2, meta.size()); - values = meta.getValues("name-one"); - assertEquals(1, values.length); - assertEquals("value1.1", values[0]); - values = meta.getValues("name-two"); - assertEquals(1, values.length); - assertEquals("value2.1", values[0]); - } - /** * Test for <code>get(String)</code> method. */ diff --git a/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-key-fields.json b/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-key-fields.json index 94488c9af7..a778b9909b 100644 --- a/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-key-fields.json +++ b/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-key-fields.json @@ -17,6 +17,24 @@ {"class":"org.apache.tika.metadata.Audio","field":"RAW_DISC_NUMBER","key":"audio:raw-disc-number"}, {"class":"org.apache.tika.metadata.Audio","field":"RAW_TRACK_NUMBER","key":"audio:raw-track-number"}, {"class":"org.apache.tika.metadata.Audio","field":"TRACK_COUNT","key":"audio:track-count"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"ACKNOWLEDGEMENT","key":"acknowledgement"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"COMMAND_LINE","key":"cmd_ln"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"COMMENT","key":"comment"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"CONTACT","key":"contact"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"CONVENTIONS","key":"Conventions"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"EXPERIMENT_ID","key":"experiment_id"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"HISTORY","key":"history"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"INSTITUTION","key":"institution"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"MODEL_NAME_ENGLISH","key":"model_name_english"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"PROGRAM_ID","key":"prg_ID"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"PROJECT_ID","key":"project_id"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"REALIZATION","key":"realization"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"REFERENCES","key":"references"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"SOURCE","key":"source"}, + {"class":"org.apache.tika.metadata.ClimateForcast","field":"TABLE_ID","key":"table_id"}, + {"class":"org.apache.tika.metadata.CreativeCommons","field":"LICENSE_LOCATION","key":"License-Location"}, + {"class":"org.apache.tika.metadata.CreativeCommons","field":"LICENSE_URL","key":"License-Url"}, + {"class":"org.apache.tika.metadata.CreativeCommons","field":"WORK_TYPE","key":"Work-Type"}, {"class":"org.apache.tika.metadata.DWG","field":"APPLICATION_COMMENT","key":"dwg:application-comment"}, {"class":"org.apache.tika.metadata.DWG","field":"APPLICATION_NAME","key":"dwg:application-name"}, {"class":"org.apache.tika.metadata.DWG","field":"APPLICATION_VERSION","key":"dwg:application-version"}, diff --git a/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-keys.json b/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-keys.json index f601ddfc8f..4297dd26ef 100644 --- a/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-keys.json +++ b/tika-metadata-schema/src/main/resources/org/apache/tika/metadata/metadata-keys.json @@ -13,6 +13,7 @@ {"key":"Content-Location","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Content-MD5","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Content-Type","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"Conventions","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Iptc4xmpCore:CiAdrCity","namespace":"Iptc4xmpCore","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Iptc4xmpCore:CiAdrCtry","namespace":"Iptc4xmpCore","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Iptc4xmpCore:CiAdrExtadr","namespace":"Iptc4xmpCore","valueType":"TEXT","cardinality":"BAG"}, @@ -64,7 +65,10 @@ {"key":"Iptc4xmpExt:RegItemId","namespace":"Iptc4xmpExt","valueType":"TEXT","cardinality":"BAG"}, {"key":"Iptc4xmpExt:RegOrgId","namespace":"Iptc4xmpExt","valueType":"TEXT","cardinality":"BAG"}, {"key":"Iptc4xmpExt:RegistryId","namespace":"Iptc4xmpExt","valueType":"TEXT","cardinality":"BAG"}, + {"key":"License-Location","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"License-Url","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"Location","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"Work-Type","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"access-permission:assemble-document","namespace":"access-permission","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"access-permission:can-modify","namespace":"access-permission","valueType":"TEXT","cardinality":"BAG"}, {"key":"access-permission:can-print","namespace":"access-permission","valueType":"TEXT","cardinality":"SIMPLE"}, @@ -73,6 +77,7 @@ {"key":"access-permission:extract-for-accessibility","namespace":"access-permission","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"access-permission:fill-in-form","namespace":"access-permission","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"access-permission:modify-annotations","namespace":"access-permission","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"acknowledgement","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"audio:bitrate","namespace":"audio","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"audio:bits-per-sample","namespace":"audio","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"audio:channels","namespace":"audio","valueType":"INTEGER","cardinality":"SIMPLE"}, @@ -86,6 +91,9 @@ {"key":"aux:LensID","namespace":"aux","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"aux:LensInfo","namespace":"aux","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"aux:SerialNumber","namespace":"aux","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"cmd_ln","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"comment","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"contact","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"cp:category","namespace":"cp","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"cp:contentStatus","namespace":"cp","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"cp:lastModifiedBy","namespace":"cp","valueType":"TEXT","cardinality":"SIMPLE"}, @@ -132,6 +140,7 @@ {"key":"exif:FocalLength","namespace":"exif","valueType":"RATIONAL","cardinality":"SIMPLE"}, {"key":"exif:IsoSpeedRatings","namespace":"exif","valueType":"INTEGER","cardinality":"SEQ"}, {"key":"exif:PageCount","namespace":"exif","valueType":"INTEGER","cardinality":"SIMPLE"}, + {"key":"experiment_id","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"extended-properties:AppVersion","namespace":"extended-properties","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"extended-properties:Application","namespace":"extended-properties","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"extended-properties:Company","namespace":"extended-properties","valueType":"TEXT","cardinality":"SIMPLE"}, @@ -160,7 +169,9 @@ {"key":"geo:lat","namespace":"geo","valueType":"REAL","cardinality":"SIMPLE"}, {"key":"geo:long","namespace":"geo","valueType":"REAL","cardinality":"SIMPLE"}, {"key":"geo:timestamp","namespace":"geo","valueType":"DATE","cardinality":"SIMPLE"}, + {"key":"history","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"html:scriptSrc","namespace":"html","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"institution","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"iworks:build-version-history","namespace":"iworks","valueType":"TEXT","cardinality":"BAG"}, {"key":"iworks:document-id","namespace":"iworks","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"machine:architectureBits","namespace":"machine","valueType":"CLOSED_CHOICE","cardinality":"SIMPLE"}, @@ -244,6 +255,7 @@ {"key":"meta:slide-count","namespace":"meta","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"meta:table-count","namespace":"meta","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"meta:word-count","namespace":"meta","valueType":"INTEGER","cardinality":"SIMPLE"}, + {"key":"model_name_english","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"msoffice:comment-person-display-name","namespace":"msoffice","valueType":"TEXT","cardinality":"BAG"}, {"key":"msoffice:doc:has-attached-template","namespace":"msoffice","valueType":"BOOLEAN","cardinality":"SIMPLE"}, {"key":"msoffice:doc:has-framesets","namespace":"msoffice","valueType":"BOOLEAN","cardinality":"SIMPLE"}, @@ -386,6 +398,8 @@ {"key":"plus:PropertyReleaseID","namespace":"plus","valueType":"TEXT","cardinality":"BAG"}, {"key":"plus:PropertyReleaseStatus","namespace":"plus","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"plus:Version","namespace":"plus","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"prg_ID","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"project_id","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"pst:discriptor-node-id","namespace":"pst","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"pst:is-valid","namespace":"pst","valueType":"BOOLEAN","cardinality":"SIMPLE"}, {"key":"quattropro:build","namespace":"quattropro","valueType":"INTEGER","cardinality":"SIMPLE"}, @@ -393,12 +407,16 @@ {"key":"quattropro:lowest-version","namespace":"quattropro","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"quattropro:version","namespace":"quattropro","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"quicktime:still-image-time","namespace":"quicktime","valueType":"REAL","cardinality":"SIMPLE"}, + {"key":"realization","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"references","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"rtf:contains-encapsulated-html","namespace":"rtf","valueType":"BOOLEAN","cardinality":"SIMPLE"}, {"key":"rtf:embedded-app-version","namespace":"rtf","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"rtf:embedded-class","namespace":"rtf","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"rtf:embedded-item","namespace":"rtf","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"rtf:embedded-topic","namespace":"rtf","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"rtf:thumbnail","namespace":"rtf","valueType":"BOOLEAN","cardinality":"SIMPLE"}, + {"key":"source","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, + {"key":"table_id","namespace":"","valueType":"TEXT","cardinality":"SIMPLE"}, {"key":"tess:image-magick-processed","namespace":"tess","valueType":"BOOLEAN","cardinality":"SEQ"}, {"key":"tess:orientation","namespace":"tess","valueType":"INTEGER","cardinality":"SIMPLE"}, {"key":"tess:orientation-confidence","namespace":"tess","valueType":"REAL","cardinality":"SIMPLE"}, diff --git a/tika-metadata-schema/src/test/java/org/apache/tika/metadata/schema/MetadataNoUnderscoreTest.java b/tika-metadata-schema/src/test/java/org/apache/tika/metadata/schema/MetadataNoUnderscoreTest.java index 7ee7600fab..ee799d7d0f 100644 --- a/tika-metadata-schema/src/test/java/org/apache/tika/metadata/schema/MetadataNoUnderscoreTest.java +++ b/tika-metadata-schema/src/test/java/org/apache/tika/metadata/schema/MetadataNoUnderscoreTest.java @@ -34,8 +34,16 @@ import org.junit.jupiter.api.Test; */ public class MetadataNoUnderscoreTest { - /** Keys/prefixes whose underscore is an external standard's spelling (verbatim). Empty today. */ - private static final Set<String> ALLOWLIST = Set.of(); + /** + * Keys/prefixes whose underscore is an external standard's spelling (verbatim). + * {@code ClimateForcast} (tika-core) mints its 15 constants from the NCAR CCSM / + * Climate Forecast convention (http://cf-pcmdi.llnl.gov/) attribute names as-is; 6 of + * them carry the convention's own underscores. These are not Tika-coined, so renaming + * them is out of scope here (it would also change the keys Tika has emitted since 0.x). + */ + private static final Set<String> ALLOWLIST = Set.of( + "prg_ID", "cmd_ln", "table_id", "project_id", "experiment_id", + "model_name_english"); @Test public void noUnderscoreInTikaCoinedKeys() throws Exception { diff --git a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/grib/GribParser.java b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/grib/GribParser.java index 94f819f9f2..2649b0dd20 100644 --- a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/grib/GribParser.java +++ b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/grib/GribParser.java @@ -21,7 +21,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Collections; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.io.FileUtils; import org.xml.sax.ContentHandler; @@ -38,6 +41,7 @@ import org.apache.tika.io.TikaInputStream; import org.apache.tika.metadata.ClimateForcast; import org.apache.tika.metadata.KeyPrefix; import org.apache.tika.metadata.Metadata; +import org.apache.tika.metadata.Property; import org.apache.tika.metadata.TikaCoreProperties; import org.apache.tika.mime.MediaType; import org.apache.tika.parser.ParseContext; @@ -124,18 +128,23 @@ public class GribParser implements Parser { } } - private static final Set<String> CF_GLOBAL_ATTRIBUTES = Set.of( - ClimateForcast.PROGRAM_ID, ClimateForcast.COMMAND_LINE, ClimateForcast.HISTORY, - ClimateForcast.TABLE_ID, ClimateForcast.INSTITUTION, ClimateForcast.SOURCE, - ClimateForcast.CONTACT, ClimateForcast.PROJECT_ID, ClimateForcast.CONVENTIONS, - ClimateForcast.REFERENCES, ClimateForcast.ACKNOWLEDGEMENT, ClimateForcast.REALIZATION, - ClimateForcast.EXPERIMENT_ID, ClimateForcast.COMMENT, ClimateForcast.MODEL_NAME_ENGLISH); + private static final Map<String, Property> CF_GLOBAL_ATTRIBUTES = Stream.of( + ClimateForcast.PROGRAM_ID, ClimateForcast.COMMAND_LINE, ClimateForcast.HISTORY, + ClimateForcast.TABLE_ID, ClimateForcast.INSTITUTION, ClimateForcast.SOURCE, + ClimateForcast.CONTACT, ClimateForcast.PROJECT_ID, ClimateForcast.CONVENTIONS, + ClimateForcast.REFERENCES, ClimateForcast.ACKNOWLEDGEMENT, + ClimateForcast.REALIZATION, ClimateForcast.EXPERIMENT_ID, ClimateForcast.COMMENT, + ClimateForcast.MODEL_NAME_ENGLISH) + .collect(Collectors.toMap(Property::getName, p -> p)); private static void addGlobalAttribute(Metadata metadata, String name, String value) { if ("title".equals(name)) { metadata.add(TikaCoreProperties.TITLE, value); - } else if (CF_GLOBAL_ATTRIBUTES.contains(name)) { - metadata.add(name, value); + return; + } + Property cfProperty = CF_GLOBAL_ATTRIBUTES.get(name); + if (cfProperty != null) { + metadata.add(cfProperty, value); } else { metadata.add(GRIB.key(name), value); } diff --git a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/netcdf/NetCDFParser.java b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/netcdf/NetCDFParser.java index 1cc2cef3e2..364e7cd522 100644 --- a/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/netcdf/NetCDFParser.java +++ b/tika-parsers/tika-parsers-extended/tika-parser-scientific-module/src/main/java/org/apache/tika/parser/netcdf/NetCDFParser.java @@ -21,7 +21,10 @@ package org.apache.tika.parser.netcdf; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; @@ -36,6 +39,7 @@ import org.apache.tika.io.TikaInputStream; import org.apache.tika.metadata.ClimateForcast; import org.apache.tika.metadata.KeyPrefix; import org.apache.tika.metadata.Metadata; +import org.apache.tika.metadata.Property; import org.apache.tika.metadata.TikaCoreProperties; import org.apache.tika.mime.MediaType; import org.apache.tika.parser.ParseContext; @@ -133,18 +137,23 @@ public class NetCDFParser implements Parser { } } - private static final Set<String> CF_GLOBAL_ATTRIBUTES = Set.of( - ClimateForcast.PROGRAM_ID, ClimateForcast.COMMAND_LINE, ClimateForcast.HISTORY, - ClimateForcast.TABLE_ID, ClimateForcast.INSTITUTION, ClimateForcast.SOURCE, - ClimateForcast.CONTACT, ClimateForcast.PROJECT_ID, ClimateForcast.CONVENTIONS, - ClimateForcast.REFERENCES, ClimateForcast.ACKNOWLEDGEMENT, ClimateForcast.REALIZATION, - ClimateForcast.EXPERIMENT_ID, ClimateForcast.COMMENT, ClimateForcast.MODEL_NAME_ENGLISH); + private static final Map<String, Property> CF_GLOBAL_ATTRIBUTES = Stream.of( + ClimateForcast.PROGRAM_ID, ClimateForcast.COMMAND_LINE, ClimateForcast.HISTORY, + ClimateForcast.TABLE_ID, ClimateForcast.INSTITUTION, ClimateForcast.SOURCE, + ClimateForcast.CONTACT, ClimateForcast.PROJECT_ID, ClimateForcast.CONVENTIONS, + ClimateForcast.REFERENCES, ClimateForcast.ACKNOWLEDGEMENT, + ClimateForcast.REALIZATION, ClimateForcast.EXPERIMENT_ID, ClimateForcast.COMMENT, + ClimateForcast.MODEL_NAME_ENGLISH) + .collect(Collectors.toMap(Property::getName, p -> p)); private static void addGlobalAttribute(Metadata metadata, String name, String value) { if ("title".equals(name)) { metadata.add(TikaCoreProperties.TITLE, value); - } else if (CF_GLOBAL_ATTRIBUTES.contains(name)) { - metadata.add(name, value); + return; + } + Property cfProperty = CF_GLOBAL_ATTRIBUTES.get(name); + if (cfProperty != null) { + metadata.add(cfProperty, value); } else { metadata.add(NETCDF.key(name), value); } diff --git a/tika-xmp/src/main/java/org/apache/tika/xmp/XMPMetadata.java b/tika-xmp/src/main/java/org/apache/tika/xmp/XMPMetadata.java index 888ca95e71..a89fa2cfbb 100644 --- a/tika-xmp/src/main/java/org/apache/tika/xmp/XMPMetadata.java +++ b/tika-xmp/src/main/java/org/apache/tika/xmp/XMPMetadata.java @@ -484,11 +484,12 @@ public class XMPMetadata extends Metadata { } /** - * It will set all simple and array properties that have QName keys in registered namespaces. - * - * @see org.apache.tika.metadata.Metadata#setAll(java.util.Properties) + * Sets all simple and array properties that have QName keys in registered namespaces. + * XMPMetadata-specific: no longer overrides a parent method (the raw-map + * {@code Metadata#setAll(Properties)} it used to override was removed as an + * unguarded write route; this method is a full reimplementation and never + * called {@code super}, so removal doesn't change its behavior). */ - @Override public void setAll(Properties properties) { @SuppressWarnings("unchecked") Enumeration<String> names = (Enumeration<String>) properties.propertyNames();
