From bc98f941974b30d94044e212ce2cf345cb59db8f Mon Sep 17 00:00:00 2001 From: Robert Stephan Date: Sat, 13 Apr 2024 18:49:34 +0200 Subject: [PATCH] enable MCRObjectIDNormalization in Servlet #77 --- jspdocportal-diskcache/pom.xml | 14 +- .../MCRDiskcacheDownloadServlet.java | 9 +- .../MCRTemporaryObjectIDNormalizer.java | 143 ++++++++++++++++++ .../jspdocportal-diskcache/mycore.properties | 2 + 4 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRTemporaryObjectIDNormalizer.java diff --git a/jspdocportal-diskcache/pom.xml b/jspdocportal-diskcache/pom.xml index b5bcc629..29ca607c 100644 --- a/jspdocportal-diskcache/pom.xml +++ b/jspdocportal-diskcache/pom.xml @@ -14,10 +14,22 @@ 13 + + + org.apache.solr + solr-solrj + org.mycore mycore-base + + + org.mycore + mycore-solr + jakarta.servlet jakarta.servlet-api @@ -44,7 +56,7 @@ - + diff --git a/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRDiskcacheDownloadServlet.java b/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRDiskcacheDownloadServlet.java index cd579749..d6e39c35 100644 --- a/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRDiskcacheDownloadServlet.java +++ b/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRDiskcacheDownloadServlet.java @@ -5,6 +5,7 @@ import java.util.Map.Entry; import java.util.Optional; +import org.mycore.datamodel.metadata.MCRObjectID; import org.mycore.jspdocportal.diskcache.servlet.FileServlet; import org.mycore.jspdocportal.diskcache.servlet.FileServletData; @@ -36,9 +37,11 @@ protected FileServletData getFileData(HttpServletRequest request) { if (oCache.isPresent()) { MCRDiskcacheConfig cache = oCache.get().getValue(); String objectId = pathInfo.substring(1, pathInfo.length() - cache.getFileName().length()); - Path file = MCRDiskcacheManager.instance().retrieveCachedFile(cache.getId(), objectId); - - return new FileServletData(file, cache.getMimeType(), pathInfo.substring(pathInfo.lastIndexOf("/")+1)); + MCRObjectID mcrObjId = MCRTemporaryObjectIDNormalizer.retrieveMCRObjIDfromSOLR(objectId); + if(mcrObjId!=null) { + Path file = MCRDiskcacheManager.instance().retrieveCachedFile(cache.getId(), mcrObjId.toString()); + return new FileServletData(file, cache.getMimeType(), pathInfo.substring(pathInfo.lastIndexOf("/")+1)); + } } return null; } diff --git a/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRTemporaryObjectIDNormalizer.java b/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRTemporaryObjectIDNormalizer.java new file mode 100644 index 00000000..ef76c7ec --- /dev/null +++ b/jspdocportal-diskcache/src/main/java/org/mycore/jspdocportal/diskcache/MCRTemporaryObjectIDNormalizer.java @@ -0,0 +1,143 @@ +/* + * This file is part of *** M y C o R e *** + * See http://www.mycore.de/ for details. + * + * MyCoRe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MyCoRe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MyCoRe. If not, see . + */ + +package org.mycore.jspdocportal.diskcache; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.util.ClientUtils; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.mycore.common.config.MCRConfiguration2; +import org.mycore.datamodel.metadata.MCRObjectID; +import org.mycore.solr.MCRSolrClientFactory; + +import jakarta.ws.rs.BadRequestException; +import jakarta.ws.rs.NotFoundException; + +/** + * This is duplicated code from org.mycore.restapi.MCRNormalizeMCRObjectIDsFilter + * I will clean that up later and create a configurable instance + * The SOLR implementation can than be moved to the mycore-solr module. to reduce dependencies between modules + * This will reduce compile dependencies between modules. + * A minimal default implementation will go into mycore-base. + * Idea for name: MCRObjectIDDetector / MCRDefaultObjectIDDetector / MCRSOLRObjecIDDetector; + * + * TODO: Migrate / Rename Properties (via deprecated properties) + * + * @author Robert Stephan + * + */ + +public class MCRTemporaryObjectIDNormalizer { + + private static final Logger LOGGER = LogManager.getLogger(); + + private static Set SEARCHKEYS_FOR_OBJECTS = MCRConfiguration2 + .getString("MCR.RestAPI.V2.AlternativeIdentifier.Objects.Keys").stream() + .flatMap(MCRConfiguration2::splitValue).collect(Collectors.toSet()); + + private static Set SEARCHKEYS_FOR_DERIVATES = MCRConfiguration2 + .getString("MCR.RestAPI.V2.AlternativeIdentifier.Derivates.Keys").stream() + .flatMap(MCRConfiguration2::splitValue).collect(Collectors.toSet()); + + public static MCRObjectID retrieveMCRDerIDfromSOLR(MCRObjectID mcrObjId, String derid) { + String result = derid; + if (derid.contains(":") && !SEARCHKEYS_FOR_DERIVATES.isEmpty()) { + String key = derid.substring(0, derid.indexOf(":")); + String value = derid.substring(derid.indexOf(":") + 1); + if (SEARCHKEYS_FOR_DERIVATES.contains(key)) { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("start", 0); + params.set("rows", 1); + params.set("fl", "id"); + params.set("fq", "objectKind:mycorederivate"); + params.set("fq", "returnId:" + mcrObjId.toString()); + params.set("q", key + ":" + ClientUtils.escapeQueryChars(value)); + params.set("sort", "derivateOrder asc"); + QueryResponse solrResponse = null; + try { + solrResponse = MCRSolrClientFactory.getMainSolrClient().query(params); + } catch (Exception e) { + LOGGER.error("Error retrieving derivate id from SOLR", e); + } + if (solrResponse != null) { + SolrDocumentList solrResults = solrResponse.getResults(); + if (solrResults.getNumFound() == 1) { + result = String.valueOf(solrResults.get(0).getFieldValue("id")); + } + if (solrResults.getNumFound() == 0) { + throw new NotFoundException("No MyCoRe Derivate ID found for query " + derid); + } + if (solrResults.getNumFound() > 1) { + throw new BadRequestException( + "The query " + derid + " does not return a unique MyCoRe Derivate ID"); + } + } + } + } + if (MCRObjectID.isValid(result)) { + return MCRObjectID.getInstance(result); + } + return null; + } + + public static MCRObjectID retrieveMCRObjIDfromSOLR(String mcrid) { + String result = mcrid; + if (mcrid.contains(":") && !SEARCHKEYS_FOR_OBJECTS.isEmpty()) { + String key = mcrid.substring(0, mcrid.indexOf(":")); + String value = URLDecoder.decode(mcrid.substring(mcrid.indexOf(":") + 1), StandardCharsets.UTF_8); + if (SEARCHKEYS_FOR_OBJECTS.contains(key)) { + ModifiableSolrParams params = new ModifiableSolrParams(); + params.set("start", 0); + params.set("rows", 1); + params.set("fl", "id"); + params.set("fq", "objectKind:mycoreobject"); + params.set("q", key + ":" + ClientUtils.escapeQueryChars(value)); + QueryResponse solrResponse = null; + try { + solrResponse = MCRSolrClientFactory.getMainSolrClient().query(params); + } catch (Exception e) { + LOGGER.error("Error retrieving object id from SOLR", e); + } + if (solrResponse != null) { + SolrDocumentList solrResults = solrResponse.getResults(); + if (solrResults.getNumFound() == 1) { + result = String.valueOf(solrResults.get(0).getFieldValue("id")); + } + if (solrResults.getNumFound() == 0) { + throw new NotFoundException("No MyCoRe ID found for query " + mcrid); + } + if (solrResults.getNumFound() > 1) { + throw new BadRequestException("The query " + mcrid + " does not return a unique MyCoRe ID"); + } + } + } + } + if (MCRObjectID.isValid(result)) { + return MCRObjectID.getInstance(result); + } + return null; + } +} diff --git a/jspdocportal-diskcache/src/main/resources/config/jspdocportal-diskcache/mycore.properties b/jspdocportal-diskcache/src/main/resources/config/jspdocportal-diskcache/mycore.properties index 730f355d..61295405 100644 --- a/jspdocportal-diskcache/src/main/resources/config/jspdocportal-diskcache/mycore.properties +++ b/jspdocportal-diskcache/src/main/resources/config/jspdocportal-diskcache/mycore.properties @@ -24,4 +24,6 @@ MCR.Diskcache.Cache.hello.Class=org.mycore.jspdocportal.diskcache.MCRDiskcacheCo MCR.Diskcache.Cache.hello.FileName=/hello MCR.Diskcache.Cache.hello.MimeType=text/plain MCR.Diskcache.Cache.hello.Generator.Class=org.mycore.jspdocportal.diskcache.generator.SimpleGenerator + +MCR.RestAPI.V2.AlternativeIdentifier.Objects.Keys=doi,derivates,id,recordIdentifier \ No newline at end of file