Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rest api for handle resolution with metadata #761

Merged
merged 23 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions dspace-api/src/main/java/org/dspace/handle/HandlePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, String> 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);
vidiecan marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -166,13 +169,28 @@ public ResponseEntity<String> 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));
vidiecan marked this conversation as resolved.
Show resolved Hide resolved
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<String, String> 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";
Paurikova2 marked this conversation as resolved.
Show resolved Hide resolved
}

protected String mapAsJson(final String resolvedUrl) {
Expand All @@ -183,6 +201,19 @@ protected String mapAsJson(final String resolvedUrl) {
return json;
}

protected String mapAsJson(final Map<String, String> 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<String> jsonList) {
String json = "null";
if (jsonList != null && !jsonList.isEmpty()) {
Expand All @@ -194,5 +225,4 @@ protected String mapAsJson(final List<String> jsonList) {
}
return json;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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("[email protected]")))
.andExpect(jsonPath("$.SUBMITDATE").exists());
}

@Test
Expand Down
Loading