1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.restapi;
20
21 import java.io.IOException;
22 import java.net.URI;
23 import java.util.Set;
24 import java.util.stream.Collectors;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.logging.log4j.LogManager;
28 import org.apache.logging.log4j.Logger;
29 import org.apache.solr.client.solrj.response.QueryResponse;
30 import org.apache.solr.client.solrj.util.ClientUtils;
31 import org.apache.solr.common.SolrDocumentList;
32 import org.apache.solr.common.params.ModifiableSolrParams;
33 import org.mycore.common.MCRException;
34 import org.mycore.common.config.MCRConfiguration2;
35 import org.mycore.datamodel.metadata.MCRObjectID;
36 import org.mycore.solr.MCRSolrClientFactory;
37
38 import jakarta.annotation.Priority;
39 import jakarta.servlet.http.HttpServletResponse;
40 import jakarta.ws.rs.BadRequestException;
41 import jakarta.ws.rs.NotFoundException;
42 import jakarta.ws.rs.Priorities;
43 import jakarta.ws.rs.container.ContainerRequestContext;
44 import jakarta.ws.rs.container.ContainerRequestFilter;
45 import jakarta.ws.rs.container.PreMatching;
46 import jakarta.ws.rs.container.ResourceInfo;
47 import jakarta.ws.rs.core.Context;
48 import jakarta.ws.rs.core.Response;
49 import jakarta.ws.rs.core.UriInfo;
50 import jakarta.ws.rs.ext.Provider;
51
52
53
54
55
56
57
58
59 @Provider
60 @PreMatching
61 @Priority(Priorities.AUTHORIZATION - 10)
62 public class MCRNormalizeMCRObjectIDsFilter implements ContainerRequestFilter {
63
64 private static final Logger LOGGER = LogManager.getLogger();
65
66 private static Set<String> SEARCHKEYS_FOR_OBJECTS = MCRConfiguration2
67 .getString("MCR.RestAPI.V2.AlternativeIdentifier.Objects.Keys").stream()
68 .flatMap(MCRConfiguration2::splitValue).collect(Collectors.toSet());
69
70 private static Set<String> SEARCHKEYS_FOR_DERIVATES = MCRConfiguration2
71 .getString("MCR.RestAPI.V2.AlternativeIdentifier.Derivates.Keys").stream()
72 .flatMap(MCRConfiguration2::splitValue).collect(Collectors.toSet());
73
74 @Context
75 ResourceInfo resourceInfo;
76
77 @Context
78 HttpServletResponse response;
79
80 @Override
81 public void filter(ContainerRequestContext requestContext) throws IOException {
82 UriInfo uriInfo = requestContext.getUriInfo();
83 String path = uriInfo.getPath().toString();
84 String[] pathParts = path.split("/", -1);
85 if (pathParts.length >= 2 && "objects".equals(pathParts[0])) {
86 String mcrid = pathParts[1];
87
88 String mcridExtension = "";
89 if (mcrid.endsWith(".xml")) {
90 mcridExtension = ".xml";
91 mcrid = mcrid.substring(0, mcrid.length() - 4);
92 }
93 if (mcrid.endsWith(".json")) {
94 mcridExtension = ".json";
95 mcrid = mcrid.substring(0, mcrid.length() - 5);
96 }
97 try {
98 if (!SEARCHKEYS_FOR_OBJECTS.isEmpty() && mcrid.contains(":")) {
99 pathParts[1] = retrieveMCRObjIDfromSOLR(mcrid) + mcridExtension;
100 } else {
101 MCRObjectID mcrObjID = MCRObjectID.getInstance(mcrid);
102
103 pathParts[1] = mcrObjID.toString() + mcridExtension;
104 }
105 } catch (MCRException ex) {
106
107
108 }
109
110 if (pathParts.length >= 4 && pathParts[2].equals("derivates")) {
111 String derid = pathParts[3];
112
113 String deridExtension = "";
114 if (derid.endsWith(".xml")) {
115 deridExtension = ".xml";
116 derid = derid.substring(0, mcrid.length() - 4);
117 }
118 if (derid.endsWith(".json")) {
119 deridExtension = ".json";
120 derid = derid.substring(0, mcrid.length() - 5);
121 }
122 try {
123 if (!SEARCHKEYS_FOR_DERIVATES.isEmpty() && derid.contains(":")) {
124 pathParts[3] = retrieveMCRDerIDfromSOLR(mcrid, derid) + deridExtension;
125 } else {
126 MCRObjectID mcrDerID = MCRObjectID.getInstance(derid);
127
128 pathParts[3] = mcrDerID.toString() + deridExtension;
129 }
130 } catch (MCRException ex) {
131
132 }
133 }
134 String newPath = StringUtils.join(pathParts, "/");
135 if (!newPath.equals(path)) {
136 String queryString = uriInfo.getRequestUri().getQuery();
137 URI uri = uriInfo.getBaseUri().resolve(queryString == null ? newPath : newPath + "?" + queryString);
138 requestContext.abortWith(Response.temporaryRedirect(uri).build());
139 }
140 }
141 }
142
143 private String retrieveMCRDerIDfromSOLR(String mcrid, String derid) {
144 String key = derid.substring(0, derid.indexOf(":"));
145 String value = derid.substring(derid.indexOf(":") + 1);
146 if (SEARCHKEYS_FOR_DERIVATES.contains(key)) {
147 ModifiableSolrParams params = new ModifiableSolrParams();
148 params.set("start", 0);
149 params.set("rows", 1);
150 params.set("fl", "id");
151 params.set("fq", "objectKind:mycorederivate");
152 params.set("fq", "returnId:" + mcrid);
153 params.set("q", key + ":" + ClientUtils.escapeQueryChars(value));
154 params.set("sort", "derivateOrder asc");
155 QueryResponse solrResponse = null;
156 try {
157 solrResponse = MCRSolrClientFactory.getMainSolrClient().query(params);
158 } catch (Exception e) {
159 LOGGER.error("Error retrieving derivate id from SOLR", e);
160 }
161 if (solrResponse != null) {
162 SolrDocumentList solrResults = solrResponse.getResults();
163 if (solrResults.getNumFound() == 1) {
164 return String.valueOf(solrResults.get(0).getFieldValue("id"));
165 }
166 if (solrResults.getNumFound() == 0) {
167 throw new NotFoundException("No MyCoRe Derivate ID found for query " + derid);
168 }
169 if (solrResults.getNumFound() > 1) {
170 throw new BadRequestException(
171 "The query " + derid + " does not return a unique MyCoRe Derivate ID");
172 }
173 }
174 }
175 return derid;
176 }
177
178 private String retrieveMCRObjIDfromSOLR(String mcrid) {
179 String key = mcrid.substring(0, mcrid.indexOf(":"));
180 String value = mcrid.substring(mcrid.indexOf(":") + 1);
181 if (SEARCHKEYS_FOR_OBJECTS.contains(key)) {
182 ModifiableSolrParams params = new ModifiableSolrParams();
183 params.set("start", 0);
184 params.set("rows", 1);
185 params.set("fl", "id");
186 params.set("fq", "objectKind:mycoreobject");
187 params.set("q", key + ":" + ClientUtils.escapeQueryChars(value));
188 QueryResponse solrResponse = null;
189 try {
190 solrResponse = MCRSolrClientFactory.getMainSolrClient().query(params);
191 } catch (Exception e) {
192 LOGGER.error("Error retrieving object id from SOLR", e);
193 }
194 if (solrResponse != null) {
195 SolrDocumentList solrResults = solrResponse.getResults();
196 if (solrResults.getNumFound() == 1) {
197 return String.valueOf(solrResults.get(0).getFieldValue("id"));
198 }
199 if (solrResults.getNumFound() == 0) {
200 throw new NotFoundException("No MyCoRe ID found for query " + mcrid);
201 }
202 if (solrResults.getNumFound() > 1) {
203 throw new BadRequestException("The query " + mcrid + " does not return a unique MyCoRe ID");
204 }
205 }
206 }
207 return mcrid;
208 }
209 }