diff --git a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java index 1275ef81d695..a22736c179bb 100644 --- a/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java +++ b/dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java @@ -254,6 +254,54 @@ public void scanNAs(ScanCallback callback) throws HandleException { // Resolving methods //////////////////////////////////////// + /** + * Resolve the given handle to DSpace object. + * + * @param context the context + * @param handle the handle to resolve + * @return the resolved DSpaceObject + * @throws HandleException if an error occurs during resolution + */ + private static DSpaceObject resolveHandleToObject(Context context, String handle) throws HandleException { + try { + return handleClarinService.resolveToObject(context, handle); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("Exception in resolveHandleToObject", e); + } + throw new HandleException(HandleException.INTERNAL_ERROR); + } + } + + /** + * Retrieves handle values as a map. + * + * @param handle the handle to resolve + * @return a map containing the handle values + * @throws HandleException if an error occurs during handle resolution + */ + public static Map getMapHandleValues(String handle) throws HandleException { + if (log.isInfoEnabled()) { + log.info("Called getMapHandleValues"); + } + loadServices(); + Context context = new Context(); + try { + DSpaceObject dso = null; + boolean resolveMetadata = configurationService.getBooleanProperty("lr.pid.resolvemetadata", true); + if (resolveMetadata) { + dso = resolveHandleToObject(context, handle); + } + return extractMetadata(dso); + } finally { + try { + context.complete(); + } catch (SQLException sqle) { + // ignore + } + } + } + /** * Return the raw values for this handle. This implementation returns a * single URL value. @@ -285,15 +333,7 @@ public byte[][] getRawHandleValues(byte[] theHandle, int[] indexList, String handle = Util.decodeString(theHandle); context = new Context(); - - DSpaceObject dso = null; String url = handleClarinService.resolveToURL(context, handle); - - boolean resolveMetadata = configurationService.getBooleanProperty("lr.pid.resolvemetadata", true); - if (resolveMetadata) { - dso = handleClarinService.resolveToObject(context, handle); - } - if (Objects.isNull(url)) { // try with old prefix @@ -332,6 +372,11 @@ public byte[][] getRawHandleValues(byte[] theHandle, int[] indexList, rh = new ResolvedHandle(url, splits[1], splits[2], splits[3], splits[4], splits[5], splits[6], splits[7]); } else { + DSpaceObject dso = null; + boolean resolveMetadata = configurationService.getBooleanProperty("lr.pid.resolvemetadata", true); + if (resolveMetadata) { + dso = resolveHandleToObject(context, handle); + } rh = new ResolvedHandle(url, dso); } log.info(String.format("Handle [%s] resolved to [%s]", handle, url)); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/hdlresolver/HdlResolverRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/hdlresolver/HdlResolverRestController.java index 540c3fd17243..ac2a4a1f7df6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/hdlresolver/HdlResolverRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/hdlresolver/HdlResolverRestController.java @@ -9,15 +9,18 @@ import java.text.MessageFormat; import java.util.List; +import java.util.Map; import java.util.Optional; import javax.servlet.http.HttpServletRequest; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import net.handle.hdllib.HandleException; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.handle.HandlePlugin; import org.dspace.handle.hdlresolver.HdlResolverDTO; import org.dspace.handle.hdlresolver.HdlResolverService; import org.springframework.beans.factory.annotation.Autowired; @@ -166,13 +169,28 @@ public ResponseEntity listHandles(HttpServletRequest request, @PathVaria /** * Maps the handle to a correct response. + * If the metadata parameter is provided, return additional handle values. * * @param request HttpServletRequest * @param handleResolver HdlResolverDTO - Handle resolver - * @return One element list using String if found, else null String. + * @return One element list using String if found, else map of metadata if param is entered, + * else "null" in case of an error */ private String resolveToURL(HttpServletRequest request, HdlResolverDTO handleResolver) { - return mapAsJson(this.hdlResolverService.resolveToURL(ContextUtil.obtainContext(request), handleResolver)); + String url = this.hdlResolverService.resolveToURL(ContextUtil.obtainContext(request), handleResolver); + String param = request.getParameter("metadata"); + if (StringUtils.isBlank(param)) { + return mapAsJson(url); + } + String handle = handleResolver.getHandle(); + try { + Map metadata = HandlePlugin.getMapHandleValues(handle); + metadata.put("URL", url); + return mapAsJson(metadata); + } catch (HandleException e) { + log.error("Failed to resolve handle values for handle: " + handle, e); + } + return "null"; } protected String mapAsJson(final String resolvedUrl) { @@ -183,6 +201,19 @@ protected String mapAsJson(final String resolvedUrl) { return json; } + protected String mapAsJson(final Map resolvedMap) { + ObjectMapper objectMapper = new ObjectMapper(); + String json = "null"; + try { + if (resolvedMap != null && !resolvedMap.isEmpty()) { + json = objectMapper.writeValueAsString(resolvedMap); + } + } catch (JsonProcessingException e) { + log.error("Error during conversion of response!", e); + } + return json; + } + protected String mapAsJson(final List jsonList) { String json = "null"; if (jsonList != null && !jsonList.isEmpty()) { @@ -194,5 +225,4 @@ protected String mapAsJson(final List jsonList) { } return json; } - } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/hdlresolver/HdlResolverRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/hdlresolver/HdlResolverRestControllerIT.java index 8227caffe616..f19f4944478e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/hdlresolver/HdlResolverRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/hdlresolver/HdlResolverRestControllerIT.java @@ -9,6 +9,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -84,7 +85,36 @@ public void givenMappedIdentifierWhenCallHdlresolverThenReturnsMappedURL() throw getClient() .perform(get("/wrongController/" + publicItem1.getHandle())) .andExpect(status().isNotFound()); + } + + @Test + public void givenMappedIdentifierWhenCallHdlresolverThenReturnsMappedParams() throws Exception { + context.turnOffAuthorisationSystem(); + + // ** START GIVEN ** + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1") + .withLogo("TestingContentForLogo").build(); + Item publicItem1 = ItemBuilder.createItem(context, col1).withTitle("Public item 1").withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John").withSubject("ExtraEntry") + .withHandle("123456789/testHdlResolver").build(); + + context.restoreAuthSystemState(); + + // ** END GIVEN ** + getClient() + .perform(get(HdlResolverRestController.RESOLVE + publicItem1.getHandle()) + .param("metadata", "true")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.URL", + StringContains.containsString("123456789/testHdlResolver"))) + .andExpect(jsonPath("$.TITLE", StringContains.containsString("Public item 1"))) + .andExpect(jsonPath("$.REPOSITORY", is(configurationService.getProperty("dspace.name")))) + .andExpect(jsonPath("$.REPORTEMAIL", + StringContains.containsString("dspace-help@ufal.mff.cuni.cz"))) + .andExpect(jsonPath("$.SUBMITDATE").exists()); } @Test