From 6e72da2d827d90e82ccb5ecbd250e12d0f3d073f Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 12:31:02 -0400 Subject: [PATCH 1/7] Local Contexts notice and label support in DataCite XML --- .../pidproviders/doi/XmlMetadataTemplate.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java index 1d14b89e11a..3cd2177e94f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java @@ -1287,9 +1287,127 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X ; } xmlw.writeEndElement(); // + for (DatasetField dsf : dv.getDatasetFields()) { + if ("LCProjectUrl".equals(dsf.getDatasetFieldType().getName())) { + if (!dsf.isEmpty()) { + String projectUrl = dsf.getValue(); + if (projectUrl != null) { + JsonObject evv = getExternalVocabularyValue(projectUrl); + if (evv != null) { + if (evv.containsKey("notice")) { + JsonValue notices = evv.get("notice"); + if (notices.getValueType() == ValueType.ARRAY) { + for (JsonValue notice : notices.asJsonArray()) { + if (notice.getValueType() == ValueType.OBJECT) { + JsonObject noticeObject = notice.asJsonObject(); + writeLocalContextNoticeRightsElement(xmlw, projectUrl, noticeObject); + + } + } + } + } + if (evv.containsKey("tk_labels")) { + JsonValue tkLabels = evv.get("tk_labels"); + if (tkLabels.getValueType() == ValueType.ARRAY) { + for (JsonValue tkLabel : tkLabels.asJsonArray()) { + if (tkLabel.getValueType() == ValueType.OBJECT) { + JsonObject tkLabelObject = tkLabel.asJsonObject(); + writeLocalContextLabelRightsElement(xmlw, projectUrl, tkLabelObject); + + } + } + } + } + if (evv.containsKey("bc_labels")) { + JsonValue bcLabels = evv.get("bc_labels"); + if (bcLabels.getValueType() == ValueType.ARRAY) { + for (JsonValue bcLabel : bcLabels.asJsonArray()) { + if (bcLabel.getValueType() == ValueType.OBJECT) { + JsonObject bcLabelObject = bcLabel.asJsonObject(); + writeLocalContextLabelRightsElement(xmlw, projectUrl, bcLabelObject); + + } + } + } + } + + } else { + + // No label or notice info - we'll still add a pointer to the project + xmlw.writeStartElement("rights"); // + xmlw.writeAttribute("rightsURI", projectUrl); // repeated in @id in evv + xmlw.writeAttribute("rightsIdentifierScheme", "Local Contexts"); + xmlw.writeAttribute("schemeURI", "https://localcontexts.org"); + xmlw.writeEndElement(); // + } + + } + + } + } + + } xmlw.writeEndElement(); // } + private void writeLocalContextNoticeRightsElement(XMLStreamWriter xmlw, String projectUrl, JsonObject noticeObject) throws XMLStreamException { + xmlw.writeStartElement("rights"); // + xmlw.writeAttribute("rightsURI", projectUrl); // repeated in @id in evv + xmlw.writeAttribute("rightsIdentifierScheme", "Local Contexts"); + xmlw.writeAttribute("schemeURI", "https://localcontexts.org"); + String rightsValue = null; + String lang = null; + if (noticeObject.containsKey("name")) { + String name = noticeObject.getString("name"); + xmlw.writeAttribute("rightsIdentifier", name); + rightsValue = "Local Contexts " + name; + } + if (noticeObject.containsKey("notice_page")) { + rightsValue = rightsValue + " " + noticeObject.getString("notice_page"); + } + if (noticeObject.containsKey("default_text")) { + rightsValue = rightsValue + ": " + noticeObject.getString("default_text"); + } + if (noticeObject.containsKey("language_tag")) { + lang = noticeObject.getString("language_tag"); + } + if (rightsValue != null) { + if (lang != null) { + xmlw.writeAttribute("xml:lang", lang); + } + xmlw.writeCharacters(rightsValue); + } + xmlw.writeEndElement(); // + } + + private void writeLocalContextLabelRightsElement(XMLStreamWriter xmlw, String projectUrl, JsonObject labelObject) throws XMLStreamException { + xmlw.writeStartElement("rights"); // + xmlw.writeAttribute("rightsURI", projectUrl); // repeated in @id in evv + xmlw.writeAttribute("rightsIdentifierScheme", "Local Contexts"); + xmlw.writeAttribute("schemeURI", "https://localcontexts.org"); + String rightsValue = null; + String lang = null; + if (labelObject.containsKey("name")) { + String name = labelObject.getString("name"); + xmlw.writeAttribute("rightsIdentifier", name); + rightsValue = "Local Contexts " + name; + } + if (labelObject.containsKey("default_text")) { + rightsValue = rightsValue + ": " + labelObject.getString("default_text"); + } + if (labelObject.containsKey("language_tag")) { + lang = labelObject.getString("language_tag"); + } + if (rightsValue != null) { + if (lang != null) { + xmlw.writeAttribute("xml:lang", lang); + } + xmlw.writeCharacters(rightsValue); + } + xmlw.writeEndElement(); // + } + + private void writeDescriptions(XMLStreamWriter xmlw, DvObject dvObject, boolean deaccessioned) throws XMLStreamException { // descriptions -> description with descriptionType attribute boolean descriptionsWritten = false; From 622853952d5c792d40ac0ce93e2215c520efb46d Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 13:42:38 -0400 Subject: [PATCH 2/7] notices key, use if else --- .../pidproviders/doi/XmlMetadataTemplate.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java index 3cd2177e94f..ce260501e9a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java @@ -48,7 +48,6 @@ import edu.harvard.iq.dataverse.dataset.DatasetUtil; import edu.harvard.iq.dataverse.license.License; import edu.harvard.iq.dataverse.pidproviders.AbstractPidProvider; -import edu.harvard.iq.dataverse.pidproviders.PidProvider; import edu.harvard.iq.dataverse.pidproviders.PidUtil; import edu.harvard.iq.dataverse.pidproviders.handle.HandlePidProvider; import edu.harvard.iq.dataverse.pidproviders.perma.PermaLinkPidProvider; @@ -1294,8 +1293,8 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X if (projectUrl != null) { JsonObject evv = getExternalVocabularyValue(projectUrl); if (evv != null) { - if (evv.containsKey("notice")) { - JsonValue notices = evv.get("notice"); + if (evv.containsKey("notices")) { + JsonValue notices = evv.get("notices"); if (notices.getValueType() == ValueType.ARRAY) { for (JsonValue notice : notices.asJsonArray()) { if (notice.getValueType() == ValueType.OBJECT) { @@ -1305,8 +1304,7 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X } } } - } - if (evv.containsKey("tk_labels")) { + } else if (evv.containsKey("tk_labels")) { JsonValue tkLabels = evv.get("tk_labels"); if (tkLabels.getValueType() == ValueType.ARRAY) { for (JsonValue tkLabel : tkLabels.asJsonArray()) { @@ -1317,8 +1315,7 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X } } } - } - if (evv.containsKey("bc_labels")) { + } else if (evv.containsKey("bc_labels")) { JsonValue bcLabels = evv.get("bc_labels"); if (bcLabels.getValueType() == ValueType.ARRAY) { for (JsonValue bcLabel : bcLabels.asJsonArray()) { @@ -1330,7 +1327,6 @@ private void writeAccessRights(XMLStreamWriter xmlw, DvObject dvObject) throws X } } } - } else { // No label or notice info - we'll still add a pointer to the project From 985d25c3188fe88c4c56cbff1d876aa185fa8037 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 14:39:21 -0400 Subject: [PATCH 3/7] doc and release note --- doc/release-notes/12224-local-contexts-rights-info-in-DataCite | 3 +++ doc/sphinx-guides/source/installation/localcontexts.rst | 1 + 2 files changed, 4 insertions(+) create mode 100644 doc/release-notes/12224-local-contexts-rights-info-in-DataCite diff --git a/doc/release-notes/12224-local-contexts-rights-info-in-DataCite b/doc/release-notes/12224-local-contexts-rights-info-in-DataCite new file mode 100644 index 00000000000..b806db36797 --- /dev/null +++ b/doc/release-notes/12224-local-contexts-rights-info-in-DataCite @@ -0,0 +1,3 @@ +For instances enabling use of Local Contexts integration, Dataverse will now add rights information +related to the Notices and Labels from a Local Contexts Project associated with a dataset to the metadata +sent to DataCite (when using DataCite DOIs) and available in metadata exports (DataCite, OAI-ORE, and JSON). diff --git a/doc/sphinx-guides/source/installation/localcontexts.rst b/doc/sphinx-guides/source/installation/localcontexts.rst index 2bafc2524d9..f1738cec091 100644 --- a/doc/sphinx-guides/source/installation/localcontexts.rst +++ b/doc/sphinx-guides/source/installation/localcontexts.rst @@ -27,6 +27,7 @@ There are several steps to LocalContexts integration. The metadatablock contains one field allowing Dataverse to store the URL of an associated Local Contexts Hub project. Be sure to update the Solr schema after installing the metadatablock (see :ref:`update-solr-schema`). The external vocabulary script interacts with the Local Contexts Hub (via the Dataverse server) to display the Labels and Notices associated with the proect and provide a link to it. The script also supports adding/removing such a link from the dataset's metadata. Note that only a project that references the dataset's PID in its `Optional Project Information` field can be linked to a dataset. + Note that the Local Contexts script configuration JSON must be edited to include your Dataverse server's URL and the Local Contexts api key you use in Dataverse. (The latter is optional but is must be included for Dataverse to add information about Notices and Labels to exported metadata and the metadata sent to DataCite for DOIs.) - Lastly, to show Local Contexts information in the summary section of the dataset page, as shown in the image above, you should add `LCProjectUrl` to list of custom summary fields via use of the :ref:`:CustomDatasetSummaryFields` setting. - Optionally, one can also set the dataverse.feature.add-local-contexts-permission-check FeatureFlag to true. This assures that only users editing datasets can use the LocalContexts search functionality (e.g. via API). This is not recommended unless problematic use is seen. From cce5fac94e2619481709266221c573cfef72f49d Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 15:42:39 -0400 Subject: [PATCH 4/7] allow objects in context for LC --- .../java/edu/harvard/iq/dataverse/util/bagit/OREMap.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java index 0d99a5bddd1..e8fcff795da 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java @@ -9,6 +9,7 @@ import edu.harvard.iq.dataverse.util.json.JsonLDNamespace; import edu.harvard.iq.dataverse.util.json.JsonLDTerm; import edu.harvard.iq.dataverse.util.json.JsonPrinter; +import edu.harvard.iq.dataverse.util.json.JsonUtil; import java.io.OutputStream; import java.nio.charset.StandardCharsets; @@ -26,6 +27,7 @@ import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; import jakarta.json.JsonValue; +import jakarta.json.JsonValue.ValueType; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -504,7 +506,12 @@ private static void addCvocValue(String val, JsonArrayBuilder vals, JsonObject c JsonObject filtering = cvocEntry.getJsonObject("retrieval-filtering"); JsonObject context = filtering.getJsonObject("@context"); for (String prefix : context.keySet()) { - localContext.putIfAbsent(prefix, context.getString(prefix)); + JsonValue prefixVal = context.get(prefix); + if (prefixVal.getValueType() == ValueType.STRING) { + localContext.putIfAbsent(prefix, context.getString(prefix)); + } else if (prefixVal.getValueType() == ValueType.OBJECT) { + localContext.putIfAbsent(prefix, JsonUtil.prettyPrint(prefixVal.asJsonObject())); + } } JsonObject cachedValue = datasetFieldService.getExternalVocabularyValue(val); if (cachedValue != null) { From fe098b074f0947ba9d08e6a18cb9b22286929879 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 16:21:50 -0400 Subject: [PATCH 5/7] allow any type of value --- .../iq/dataverse/util/bagit/OREMap.java | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java index e8fcff795da..00bdab35f4e 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java @@ -9,8 +9,6 @@ import edu.harvard.iq.dataverse.util.json.JsonLDNamespace; import edu.harvard.iq.dataverse.util.json.JsonLDTerm; import edu.harvard.iq.dataverse.util.json.JsonPrinter; -import edu.harvard.iq.dataverse.util.json.JsonUtil; - import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.time.LocalDate; @@ -27,8 +25,6 @@ import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; import jakarta.json.JsonValue; -import jakarta.json.JsonValue.ValueType; - import org.apache.commons.lang3.exception.ExceptionUtils; /** @@ -57,7 +53,7 @@ public class OREMap { private static final String DATAVERSE_SOFTWARE_URL = "https://github.com/iqss/dataverse"; - private Map localContext = new TreeMap(); + private Map localContext = new TreeMap(); private DatasetVersion version; private Boolean excludeEmail = null; @@ -65,7 +61,7 @@ public OREMap(DatasetVersion version) { this.version = version; } - //Used when the ExcludeEmailFromExport needs to be overriden, i.e. for archiving + //Used when the ExcludeEmailFromExport needs to be overridden, i.e. for archiving public OREMap(DatasetVersion dv, boolean exclude) { this.version = dv; this.excludeEmail = exclude; @@ -93,10 +89,10 @@ public JsonObjectBuilder getOREMapBuilder(boolean aggregationOnly) { // Add namespaces we'll definitely use to Context // Additional namespaces are added as needed below - localContext.putIfAbsent(JsonLDNamespace.ore.getPrefix(), JsonLDNamespace.ore.getUrl()); - localContext.putIfAbsent(JsonLDNamespace.dcterms.getPrefix(), JsonLDNamespace.dcterms.getUrl()); - localContext.putIfAbsent(JsonLDNamespace.dvcore.getPrefix(), JsonLDNamespace.dvcore.getUrl()); - localContext.putIfAbsent(JsonLDNamespace.schema.getPrefix(), JsonLDNamespace.schema.getUrl()); + localContext.putIfAbsent(JsonLDNamespace.ore.getPrefix(), Json.createValue(JsonLDNamespace.ore.getUrl())); + localContext.putIfAbsent(JsonLDNamespace.dcterms.getPrefix(), Json.createValue(JsonLDNamespace.dcterms.getUrl())); + localContext.putIfAbsent(JsonLDNamespace.dvcore.getPrefix(), Json.createValue(JsonLDNamespace.dvcore.getUrl())); + localContext.putIfAbsent(JsonLDNamespace.schema.getPrefix(), Json.createValue(JsonLDNamespace.schema.getUrl())); Dataset dataset = version.getDataset(); String id = dataset.getGlobalId().asURL(); @@ -299,7 +295,7 @@ public JsonObjectBuilder getOREMapBuilder(boolean aggregationOnly) { } // Build the '@context' object for json-ld based on the localContext entries JsonObjectBuilder contextBuilder = Json.createObjectBuilder(); - for (Entry e : localContext.entrySet()) { + for (Entry e : localContext.entrySet()) { contextBuilder.add(e.getKey(), e.getValue()); } if (aggregationOnly) { @@ -384,7 +380,7 @@ private void addIfNotNull(JsonObjectBuilder builder, JsonLDTerm key, Long value) private void addToContextMap(JsonLDTerm key) { if (!key.inNamespace()) { - localContext.putIfAbsent(key.getLabel(), key.getUrl()); + localContext.putIfAbsent(key.getLabel(), Json.createValue(key.getUrl())); } } @@ -420,7 +416,7 @@ private JsonLDTerm getTermFor(String fieldTypeName) { } public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEmail, Map cvocMap, - Map localContext) { + Map localContext2) { DatasetFieldType dfType = field.getDatasetFieldType(); if (excludeEmail && DatasetFieldType.FieldType.EMAIL.equals(dfType.getFieldType())) { @@ -429,15 +425,15 @@ public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEma JsonLDTerm fieldName = dfType.getJsonLDTerm(); if (fieldName.inNamespace()) { - localContext.putIfAbsent(fieldName.getNamespace().getPrefix(), fieldName.getNamespace().getUrl()); + localContext2.putIfAbsent(fieldName.getNamespace().getPrefix(), Json.createValue(fieldName.getNamespace().getUrl())); } else { - localContext.putIfAbsent(fieldName.getLabel(), fieldName.getUrl()); + localContext2.putIfAbsent(fieldName.getLabel(), Json.createValue(fieldName.getUrl())); } JsonArrayBuilder vals = Json.createArrayBuilder(); if (!dfType.isCompound()) { for (String val : field.getValues_nondisplay()) { if (cvocMap.containsKey(dfType.getId())) { - addCvocValue(val, vals, cvocMap.get(dfType.getId()), localContext); + addCvocValue(val, vals, cvocMap.get(dfType.getId()), localContext2); } else { vals.add(val); } @@ -453,7 +449,7 @@ public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEma JsonLDTerm subFieldName = dsft.getJsonLDTerm(); if (dsft.isCompound()) { - JsonValue compoundChildVals = getJsonLDForField(dsf, excludeEmail, cvocMap, localContext); + JsonValue compoundChildVals = getJsonLDForField(dsf, excludeEmail, cvocMap, localContext2); child.add(subFieldName.getLabel(), compoundChildVals); } else { if (excludeEmail && DatasetFieldType.FieldType.EMAIL.equals(dsft.getFieldType())) { @@ -464,10 +460,10 @@ public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEma // Add context entry // ToDo - also needs to recurse here? if (subFieldName.inNamespace()) { - localContext.putIfAbsent(subFieldName.getNamespace().getPrefix(), - subFieldName.getNamespace().getUrl()); + localContext2.putIfAbsent(subFieldName.getNamespace().getPrefix(), + Json.createValue(subFieldName.getNamespace().getUrl())); } else { - localContext.putIfAbsent(subFieldName.getLabel(), subFieldName.getUrl()); + localContext2.putIfAbsent(subFieldName.getLabel(), Json.createValue(subFieldName.getUrl())); } List values = dsf.getValues_nondisplay(); @@ -478,7 +474,7 @@ public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEma logger.fine("Child name: " + dsft.getName()); if (cvocMap.containsKey(dsft.getId())) { logger.fine("Calling addcvocval for: " + dsft.getName()); - addCvocValue(val, childVals, cvocMap.get(dsft.getId()), localContext); + addCvocValue(val, childVals, cvocMap.get(dsft.getId()), localContext2); } else { childVals.add(val); } @@ -500,18 +496,13 @@ public static JsonValue getJsonLDForField(DatasetField field, Boolean excludeEma } private static void addCvocValue(String val, JsonArrayBuilder vals, JsonObject cvocEntry, - Map localContext) { + Map localContext2) { try { if (cvocEntry.containsKey("retrieval-filtering")) { JsonObject filtering = cvocEntry.getJsonObject("retrieval-filtering"); JsonObject context = filtering.getJsonObject("@context"); for (String prefix : context.keySet()) { - JsonValue prefixVal = context.get(prefix); - if (prefixVal.getValueType() == ValueType.STRING) { - localContext.putIfAbsent(prefix, context.getString(prefix)); - } else if (prefixVal.getValueType() == ValueType.OBJECT) { - localContext.putIfAbsent(prefix, JsonUtil.prettyPrint(prefixVal.asJsonObject())); - } + localContext2.putIfAbsent(prefix, context.get(prefix)); } JsonObject cachedValue = datasetFieldService.getExternalVocabularyValue(val); if (cachedValue != null) { From 06c67c4ade4d3c20a8b7b3cad063737325d71623 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 16:28:34 -0400 Subject: [PATCH 6/7] fix COAR step, update ore version --- src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java | 2 +- .../internalspi/COARNotifyRelationshipAnnouncementStep.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java index 00bdab35f4e..1e8fe184566 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/bagit/OREMap.java @@ -47,7 +47,7 @@ public class OREMap { public static final String NAME = "OREMap"; //NOTE: Update this value whenever the output of this class is changed - private static final String DATAVERSE_ORE_FORMAT_VERSION = "Dataverse OREMap Format v1.0.2"; + private static final String DATAVERSE_ORE_FORMAT_VERSION = "Dataverse OREMap Format v1.0.3"; //v1.0.1 - added versionNote private static final String DATAVERSE_SOFTWARE_NAME = "Dataverse"; private static final String DATAVERSE_SOFTWARE_URL = "https://github.com/iqss/dataverse"; diff --git a/src/main/java/edu/harvard/iq/dataverse/workflow/internalspi/COARNotifyRelationshipAnnouncementStep.java b/src/main/java/edu/harvard/iq/dataverse/workflow/internalspi/COARNotifyRelationshipAnnouncementStep.java index c96e79f47e4..939858f9386 100644 --- a/src/main/java/edu/harvard/iq/dataverse/workflow/internalspi/COARNotifyRelationshipAnnouncementStep.java +++ b/src/main/java/edu/harvard/iq/dataverse/workflow/internalspi/COARNotifyRelationshipAnnouncementStep.java @@ -205,7 +205,7 @@ public void rollback(WorkflowContext context, Failure reason) { */ JsonArray getObjects(WorkflowContext ctxt, Map fields) { JsonArrayBuilder jab = Json.createArrayBuilder(); - Map localContext = new HashMap(); + Map localContext = new HashMap<>(); Map emptyCvocMap = new HashMap(); Dataset d = ctxt.getDataset(); @@ -238,7 +238,7 @@ JsonArray getObjects(WorkflowContext ctxt, Map fields) { } private JsonObject getRelationshipObject(DatasetFieldType dft, JsonValue jval, Dataset d, - Map localContext) { + Map localContext) { if (logger.isLoggable(Level.FINE)) { if (jval.getValueType().equals(jakarta.json.JsonValue.ValueType.OBJECT)) { logger.fine("Parsing : " + JsonUtil.prettyPrint(jval.asJsonObject())); From 4ab728888de3203af2dac8247cad4ae3703c75ad Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Wed, 18 Mar 2026 16:42:57 -0400 Subject: [PATCH 7/7] update r note --- .../12224-local-contexts-rights-info-in-DataCite | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release-notes/12224-local-contexts-rights-info-in-DataCite b/doc/release-notes/12224-local-contexts-rights-info-in-DataCite index b806db36797..c0a4c7b4d7a 100644 --- a/doc/release-notes/12224-local-contexts-rights-info-in-DataCite +++ b/doc/release-notes/12224-local-contexts-rights-info-in-DataCite @@ -1,3 +1,8 @@ For instances enabling use of Local Contexts integration, Dataverse will now add rights information related to the Notices and Labels from a Local Contexts Project associated with a dataset to the metadata sent to DataCite (when using DataCite DOIs) and available in metadata exports (DataCite, OAI-ORE, and JSON). + +It is now possible to use non-string values in the retrieval-filtering context entries for external vocabulary scripts. +This can be used to allow filtered JSON that is not valid JSON-LD to be included in the OAI_ORE JSON-LD metadata export + in a way that JSON-LD parsers will accept (and not ignore/drop). The OAI_ORE export version has been updated to 1.0.3 with this change. + \ No newline at end of file