diff --git a/doc/release-notes/12331-multi-PID-support-in-external-vocabs.md b/doc/release-notes/12331-multi-PID-support-in-external-vocabs.md new file mode 100644 index 00000000000..fb528197d59 --- /dev/null +++ b/doc/release-notes/12331-multi-PID-support-in-external-vocabs.md @@ -0,0 +1,2 @@ +Dataverse now allows use of multiple PIDs/PID services per field when using external vocabulary scripts. +One example of this is allowing ORCID and ROR values in the author or contact field. \ No newline at end of file diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java index e6b2711b443..04eb8079e98 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java @@ -406,10 +406,11 @@ public void registerExternalVocabValues(DatasetField df) { public Set getIndexableStringsByTermUri(String termUri, JsonObject cvocEntry, String indexingField) { Set strings = new HashSet<>(); JsonObject jo = getExternalVocabularyValue(termUri); - JsonObject filtering = cvocEntry.getJsonObject("retrieval-filtering"); - String termUriField = cvocEntry.getJsonString("term-uri-field").getString(); if (jo != null) { + JsonObject filtering = getRetrievalFilteringObject(cvocEntry, termUri); + String termUriField = cvocEntry.getJsonString("term-uri-field").getString(); + try { for (String key : jo.keySet()) { String indexIn = filtering.getJsonObject(key).getString("indexIn", null); @@ -467,6 +468,24 @@ public Set getIndexableStringsByTermUri(String termUri, JsonObject cvocE return strings; } + private JsonObject getRetrievalFilteringObject(JsonObject cvocEntry, String termUri) { + JsonObject filtering = cvocEntry.getJsonObject("retrieval-filtering"); + //Check for per-vocab filtering + JsonObject vocabs = cvocEntry.getJsonObject("vocabs"); + for (String key : vocabs.keySet()) { + JsonObject vocab = vocabs.getJsonObject(key); + if (vocab.containsKey("uriSpace")) { + if (termUri.startsWith(vocab.getString("uriSpace"))) { + if (vocab.containsKey("retrieval-filtering")) { + filtering = vocab.getJsonObject("retrieval-filtering"); + } + break; + } + } + } + return filtering; + } + /** * Perform a query to retrieve a cached value from the externalvocabularvalue table * @param termUri @@ -499,7 +518,7 @@ public JsonObject getExternalVocabularyValue(String termUri) { * @param relatedDatasetFields - siblings or childs of the term */ public void registerExternalTerm(JsonObject cvocEntry, String term, List relatedDatasetFields) { - String retrievalUri = cvocEntry.getString("retrieval-uri"); + String retrievalUri = cvocEntry.getString("retrieval-uri", null); String termUriFieldName = cvocEntry.getString("term-uri-field"); String prefix = cvocEntry.getString("prefix", null); if(StringUtils.isBlank(term)) { @@ -514,6 +533,13 @@ public void registerExternalTerm(JsonObject cvocEntry, String term, List vals = new ArrayList(); - for (int i = 0; i < params.size(); i++) { - String param = params.getString(i); - if (param.startsWith("/")) { - // Remove leading / - param = param.substring(1); - String[] pathParts = param.split("/"); - logger.fine("PP: " + String.join(", ", pathParts)); - var foundPart = processPathSegment(0, pathParts, readObject, termUri); - if (foundPart == null) { - nrOfNotFound ++ ; - logger.warning("External Vocabulary: no value found for %s - %s".formatted(filterKey, param)); - } else { - vals.add(i, foundPart); - logger.fine("Added param value: " + i + ": " + vals.get(i)); - } - } else { - logger.fine("Param is: " + param); - // param is not a path - either a reference to the term URI - if (param.equals("@id")) { - logger.fine("Adding id param: " + termUri); - vals.add(i, termUri); - } else { - // or a hardcoded value - logger.fine("Adding hardcoded param: " + param); - vals.add(i, param); - } + JsonObject filtering = getRetrievalFilteringObject(cvocEntry, termUri); + if(filtering != null) { + logger.fine("RF: " + filtering.toString()); + int nrOfNotFound = 0; + for (String filterKey : filtering.keySet()) { + if (!filterKey.equals("@context")) { + try { + JsonObject filter = filtering.getJsonObject(filterKey); + logger.fine("F: " + filter.toString()); + JsonArray params = filter.getJsonArray("params"); + if (params == null) { + params = Json.createArrayBuilder().build(); } - } - // Shortcut: nominally using a pattern of {0} and a param that is @id or - // hardcoded value allows the same options as letting the pattern itself be @id - // or a hardcoded value - String pattern = filter.getString("pattern"); - logger.fine("Pattern: " + pattern); - if (pattern.equals("@id")) { - logger.fine("Added #id pattern: " + filterKey + ": " + termUri); - job.add(filterKey, termUri); - } else if (pattern.contains("{")) { - if (vals.isEmpty()) { - if (nrOfNotFound == 0) { - logger.warning("External Vocabulary: " + termUri + " - No value found for " + filterKey); + logger.fine("Params: " + params.toString()); + List vals = new ArrayList(); + for (int i = 0; i < params.size(); i++) { + String param = params.getString(i); + if (param.startsWith("/")) { + // Remove leading / + param = param.substring(1); + String[] pathParts = param.split("/"); + logger.fine("PP: " + String.join(", ", pathParts)); + var foundPart = processPathSegment(0, pathParts, readObject, termUri); + if (foundPart == null) { + nrOfNotFound++; + logger.warning("External Vocabulary: no value found for %s - %s".formatted(filterKey, param)); + } else { + vals.add(i, foundPart); + logger.fine("Added param value: " + i + ": " + vals.get(i)); + } + } else { + logger.fine("Param is: " + param); + // param is not a path - either a reference to the term URI + if (param.equals("@id")) { + logger.fine("Adding id param: " + termUri); + vals.add(i, termUri); + } else { + // or a hardcoded value + logger.fine("Adding hardcoded param: " + param); + vals.add(i, param); + } } } - else { - if (pattern.equals("{0}")) { - if (vals.get(0) instanceof JsonArray) { - job.add(filterKey, (JsonArray) vals.get(0)); + // Shortcut: nominally using a pattern of {0} and a param that is @id or + // hardcoded value allows the same options as letting the pattern itself be @id + // or a hardcoded value + String pattern = filter.getString("pattern"); + logger.fine("Pattern: " + pattern); + if (pattern.equals("@id")) { + logger.fine("Added #id pattern: " + filterKey + ": " + termUri); + job.add(filterKey, termUri); + } else if (pattern.contains("{")) { + if (vals.isEmpty()) { + if (nrOfNotFound == 0) { + logger.warning("External Vocabulary: " + termUri + " - No value found for " + filterKey); } - else if (vals.get(0) instanceof JsonObject) { - job.add(filterKey, (JsonObject) vals.get(0)); - } - else { - job.add(filterKey, (String) vals.get(0)); + } else { + if (pattern.equals("{0}")) { + if (vals.get(0) instanceof JsonArray) { + job.add(filterKey, (JsonArray) vals.get(0)); + } else if (vals.get(0) instanceof JsonObject) { + job.add(filterKey, (JsonObject) vals.get(0)); + } else { + job.add(filterKey, (String) vals.get(0)); + } + } else { + String result = MessageFormat.format(pattern, vals.toArray()); + logger.fine("Result: " + result); + job.add(filterKey, result); + logger.fine("Added : " + filterKey + ": " + result); } } - else { - String result = MessageFormat.format(pattern, vals.toArray()); - logger.fine("Result: " + result); - job.add(filterKey, result); - logger.fine("Added : " + filterKey + ": " + result); - } + } else { + logger.fine("Added hardcoded pattern: " + filterKey + ": " + pattern); + job.add(filterKey, pattern); } - } else { - logger.fine("Added hardcoded pattern: " + filterKey + ": " + pattern); - job.add(filterKey, pattern); + } catch (Exception e) { + logger.warning("External Vocabulary: " + termUri + " - Failed to find value for " + filterKey + ": " + + e.getMessage()); + e.printStackTrace(); } - } catch (Exception e) { - logger.warning("External Vocabulary: " + termUri + " - Failed to find value for " + filterKey + ": " - + e.getMessage()); - e.printStackTrace(); } } - } - if(nrOfNotFound>0) { - logger.warning("External Vocabulary: " + termUri + " - Failed to find value(s) reported above in " +readObject); + + if (nrOfNotFound > 0) { + logger.warning("External Vocabulary: " + termUri + " - Failed to find value(s) reported above in " + readObject); + } } JsonObject filteredResponse = job.build(); if(filteredResponse.isEmpty()) {