mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 07:23:08 +00:00
77582: Add HandleService#formatHandle to strip prefixes from handle
This commit is contained in:
@@ -10,6 +10,8 @@ package org.dspace.handle;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -57,6 +59,13 @@ public class HandleServiceImpl implements HandleService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected SiteService siteService;
|
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
|
* Public Constructor
|
||||||
*/
|
*/
|
||||||
@@ -376,4 +385,38 @@ public class HandleServiceImpl implements HandleService {
|
|||||||
public int countTotal(Context context) throws SQLException {
|
public int countTotal(Context context) throws SQLException {
|
||||||
return handleDAO.countRows(context);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -181,4 +181,15 @@ public interface HandleService {
|
|||||||
public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException;
|
public void modifyHandleDSpaceObject(Context context, String handle, DSpaceObject newOwner) throws SQLException;
|
||||||
|
|
||||||
int countTotal(Context context) 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);
|
||||||
}
|
}
|
||||||
|
@@ -60,32 +60,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(String identifier) {
|
public boolean supports(String identifier) {
|
||||||
String prefix = handleService.getPrefix();
|
return handleService.formatHandle(identifier) != null;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -161,6 +136,7 @@ public class HandleIdentifierProvider extends IdentifierProvider {
|
|||||||
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
|
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
|
||||||
// We can do nothing with this, return null
|
// We can do nothing with this, return null
|
||||||
try {
|
try {
|
||||||
|
identifier = handleService.formatHandle(identifier);
|
||||||
return handleService.resolveToObject(context, identifier);
|
return handleService.resolveToObject(context, identifier);
|
||||||
} catch (IllegalStateException | SQLException e) {
|
} catch (IllegalStateException | SQLException e) {
|
||||||
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),
|
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),
|
||||||
|
@@ -78,33 +78,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(String identifier) {
|
public boolean supports(String identifier) {
|
||||||
String prefix = handleService.getPrefix();
|
return handleService.formatHandle(identifier) != null;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -310,6 +284,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
|
|||||||
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
|
public DSpaceObject resolve(Context context, String identifier, String... attributes) {
|
||||||
// We can do nothing with this, return null
|
// We can do nothing with this, return null
|
||||||
try {
|
try {
|
||||||
|
identifier = handleService.formatHandle(identifier);
|
||||||
return handleService.resolveToObject(context, identifier);
|
return handleService.resolveToObject(context, identifier);
|
||||||
} catch (IllegalStateException | SQLException e) {
|
} catch (IllegalStateException | SQLException e) {
|
||||||
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),
|
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier),
|
||||||
|
@@ -72,33 +72,7 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(String identifier) {
|
public boolean supports(String identifier) {
|
||||||
String prefix = handleService.getPrefix();
|
return handleService.formatHandle(identifier) != null;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -12,7 +12,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.builder.CollectionBuilder;
|
||||||
import org.dspace.builder.CommunityBuilder;
|
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.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -50,6 +54,32 @@ public class IdentifierRestControllerIT extends AbstractControllerIntegrationTes
|
|||||||
.andExpect(header().string("Location", communityDetail));
|
.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
|
@Test
|
||||||
public void testUnexistentIdentifier() throws Exception {
|
public void testUnexistentIdentifier() throws Exception {
|
||||||
getClient().perform(get("/api/pid/find?id={id}","fakeIdentifier"))
|
getClient().perform(get("/api/pid/find?id={id}","fakeIdentifier"))
|
||||||
|
Reference in New Issue
Block a user