77582: Add HandleService#formatHandle to strip prefixes from handle

This commit is contained in:
Yura Bondarenko
2021-03-16 12:20:31 +01:00
parent 2b4f22be65
commit 315e29d2b1
6 changed files with 89 additions and 80 deletions

View File

@@ -10,6 +10,8 @@ package org.dspace.handle;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -57,6 +59,13 @@ public class HandleServiceImpl implements HandleService {
@Autowired
protected SiteService siteService;
private static final Pattern[] IDENTIFIER_PATTERNS = {
Pattern.compile("^hdl:(.*)$"),
Pattern.compile("^info:hdl/(.*)$"),
Pattern.compile("^https?://hdl\\.handle\\.net/(.*)$"),
Pattern.compile("^https?://.+/handle/(.*)$")
};
/**
* Public Constructor
*/
@@ -376,4 +385,38 @@ public class HandleServiceImpl implements HandleService {
public int countTotal(Context context) throws SQLException {
return handleDAO.countRows(context);
}
public String formatHandle(String identifier) {
if (identifier == null) {
return null;
}
if (identifier.startsWith(getPrefix() + "/")) {
// prefix is the equivalent of 123456789 in 123456789/???; don't strip
return identifier;
}
String canonicalPrefix = configurationService.getProperty("handle.canonical.prefix");
if (identifier.startsWith(canonicalPrefix + "/")) {
// prefix is the equivalent of https://hdl.handle.net/ in https://hdl.handle.net/123456789/???; strip
return StringUtils.stripStart(identifier, canonicalPrefix);
}
for (Pattern pattern : IDENTIFIER_PATTERNS) {
Matcher matcher = pattern.matcher(identifier);
if (matcher.matches()) {
return matcher.group(1);
}
}
// Check additional prefixes supported in the config file
String[] additionalPrefixes = configurationService.getArrayProperty("handle.additional.prefixes");
for (String additionalPrefix : additionalPrefixes) {
if (identifier.startsWith(additionalPrefix + "/")) {
// prefix is the equivalent of 123456789 in 123456789/???; don't strip
return identifier;
}
}
return null;
}
}

View File

@@ -181,4 +181,15 @@ public interface HandleService {
public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException;
int countTotal(Context context) throws SQLException;
/**
* Format a handle ~
* - hdl:123456789/1 -> 123456789/1
* - info:hdl/123456789/1 -> 123456789/1
* - https://hdl.handle.net/123456789/1 -> 123456789/1
*
* @param identifier
* @return
*/
String formatHandle(String identifier);
}

View File

@@ -60,32 +60,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
@Override
public boolean supports(String identifier) {
String prefix = handleService.getPrefix();
String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("handle.canonical.prefix");
if (identifier == null) {
return false;
}
// return true if handle has valid starting pattern
if (identifier.startsWith(prefix + "/")
|| identifier.startsWith(canonicalPrefix)
|| identifier.startsWith("hdl:")
|| identifier.startsWith("info:hdl")
|| identifier.matches("^https?://hdl\\.handle\\.net/.*")
|| identifier.matches("^https?://.+/handle/.*")) {
return true;
}
//Check additional prefixes supported in the config file
String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService()
.getArrayProperty("handle.additional.prefixes");
for (String additionalPrefix : additionalPrefixes) {
if (identifier.startsWith(additionalPrefix + "/")) {
return true;
}
}
return false;
return handleService.formatHandle(identifier) != null;
}
@Override
@@ -161,6 +136,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
// We can do nothing with this, return null
try {
identifier = handleService.formatHandle(identifier);
return handleService.resolveToObject(context, identifier);
} catch (IllegalStateException | SQLException e) {
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),

View File

@@ -78,33 +78,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
@Override
public boolean supports(String identifier) {
String prefix = handleService.getPrefix();
String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("handle.canonical.prefix");
if (identifier == null) {
return false;
}
// return true if handle has valid starting pattern
if (identifier.startsWith(prefix + "/")
|| identifier.startsWith(canonicalPrefix)
|| identifier.startsWith("hdl:")
|| identifier.startsWith("info:hdl")
|| identifier.matches("^https?://hdl\\.handle\\.net/.*")
|| identifier.matches("^https?://.+/handle/.*")) {
return true;
}
//Check additional prefixes supported in the config file
String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService()
.getArrayProperty("handle.additional.prefixes");
for (String additionalPrefix : additionalPrefixes) {
if (identifier.startsWith(additionalPrefix + "/")) {
return true;
}
}
// otherwise, assume invalid handle
return false;
return handleService.formatHandle(identifier) != null;
}
@Override
@@ -310,6 +284,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
// We can do nothing with this, return null
try {
identifier = handleService.formatHandle(identifier);
return handleService.resolveToObject(context, identifier);
} catch (IllegalStateException | SQLException e) {
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),

View File

@@ -72,33 +72,7 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
@Override
public boolean supports(String identifier) {
String prefix = handleService.getPrefix();
String canonicalPrefix = DSpaceServicesFactory.getInstance().getConfigurationService()
.getProperty("handle.canonical.prefix");
if (identifier == null) {
return false;
}
// return true if handle has valid starting pattern
if (identifier.startsWith(prefix + "/")
|| identifier.startsWith(canonicalPrefix)
|| identifier.startsWith("hdl:")
|| identifier.startsWith("info:hdl")
|| identifier.matches("^https?://hdl\\.handle\\.net/.*")
|| identifier.matches("^https?://.+/handle/.*")) {
return true;
}
//Check additional prefixes supported in the config file
String[] additionalPrefixes = DSpaceServicesFactory.getInstance().getConfigurationService()
.getArrayProperty("handle.additional.prefixes");
for (String additionalPrefix : additionalPrefixes) {
if (identifier.startsWith(additionalPrefix + "/")) {
return true;
}
}
// otherwise, assume invalid handle
return false;
return handleService.formatHandle(identifier) != null;
}
@Override

View File

@@ -12,7 +12,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -50,6 +54,32 @@ public class IdentifierRestControllerIT extends AbstractControllerIntegrationTes
.andExpect(header().string("Location", communityDetail));
}
@Test
public void testValidIdentifierItemHandlePrefix() throws Exception {
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
// Create an item with a handle identifier
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection owningCollection = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Owning Collection")
.build();
Item item = ItemBuilder.createItem(context, owningCollection)
.withTitle("Test item")
.build();
String handle = item.getHandle();
String itemLocation = REST_SERVER_URL + "core/items/" + item.getID();
getClient().perform(get("/api/pid/find?id=hdl:{handle}", handle))
.andExpect(status().isFound())
// We expect a Location header to redirect to the item's page
.andExpect(header().string("Location", itemLocation));
}
@Test
public void testUnexistentIdentifier() throws Exception {
getClient().perform(get("/api/pid/find?id={id}","fakeIdentifier"))