/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.identifier; import java.io.IOException; import java.sql.SQLException; import java.util.List; import org.apache.logging.log4j.Logger; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.MetadataValue; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.DSpaceObjectService; import org.dspace.core.Context; import org.dspace.core.LogHelper; import org.dspace.handle.service.HandleService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * The old DSpace handle identifier service, used to create handles or retrieve objects based on their handle * * @author Fabio Bolognesi (fabio at atmire dot com) * @author Mark Diggory (markd at atmire dot com) * @author Ben Bosman (ben at atmire dot com) */ @Component public class HandleIdentifierProvider extends IdentifierProvider { /** * log4j category */ private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(HandleIdentifierProvider.class); /** * Prefix registered to no one */ protected static final String EXAMPLE_PREFIX = "123456789"; @Autowired(required = true) protected HandleService handleService; @Autowired(required = true) protected ContentServiceFactory contentServiceFactory; @Override public boolean supports(Class identifier) { return Handle.class.isAssignableFrom(identifier); } @Override public boolean supports(String identifier) { return handleService.parseHandle(identifier) != null; } @Override public String register(Context context, DSpaceObject dso) { try { String id = mint(context, dso); // Populate metadata if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) { populateHandleMetadata(context, dso, id); } return id; } catch (IOException | SQLException | AuthorizeException e) { log.error(LogHelper.getHeader(context, "Error while attempting to create handle", "Item id: " + dso.getID()), e); throw new RuntimeException("Error while attempting to create identifier for Item id: " + dso.getID(), e); } } @Override public void register(Context context, DSpaceObject dso, String identifier) { try { handleService.createHandle(context, dso, identifier); if (dso instanceof Item || dso instanceof Collection || dso instanceof Community) { populateHandleMetadata(context, dso, identifier); } } catch (IOException | IllegalStateException | SQLException | AuthorizeException e) { log.error(LogHelper.getHeader(context, "Error while attempting to create handle", "Item id: " + dso.getID()), e); throw new RuntimeException("Error while attempting to create identifier for Item id: " + dso.getID(), e); } } @Override public void reserve(Context context, DSpaceObject dso, String identifier) { try { handleService.createHandle(context, dso, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogHelper.getHeader(context, "Error while attempting to create handle", "Item id: " + dso.getID()), e); throw new RuntimeException("Error while attempting to create identifier for Item id: " + dso.getID()); } } /** * Creates a new handle in the database. * * @param context DSpace context * @param dso The DSpaceObject to create a handle for * @return The newly created handle */ @Override public String mint(Context context, DSpaceObject dso) { if (dso.getHandle() != null) { return dso.getHandle(); } try { return handleService.createHandle(context, dso); } catch (SQLException e) { log.error(LogHelper.getHeader(context, "Error while attempting to create handle", "Item id: " + dso.getID()), e); throw new RuntimeException("Error while attempting to create identifier for Item id: " + dso.getID()); } } @Override public DSpaceObject resolve(Context context, String identifier, String... attributes) { // We can do nothing with this, return null try { identifier = handleService.parseHandle(identifier); return handleService.resolveToObject(context, identifier); } catch (IllegalStateException | SQLException e) { log.error(LogHelper.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), e); } // throw new IllegalStateException("Unsupported Handle Type " // + Constants.typeText[handletypeid]); return null; } @Override public String lookup(Context context, DSpaceObject dso) throws IdentifierNotFoundException, IdentifierNotResolvableException { try { return handleService.findHandle(context, dso); } catch (SQLException sqe) { throw new IdentifierNotResolvableException(sqe.getMessage(), sqe); } } @Override public void delete(Context context, DSpaceObject dso, String identifier) throws IdentifierException { delete(context, dso); } @Override public void delete(Context context, DSpaceObject dso) throws IdentifierException { try { handleService.unbindHandle(context, dso); } catch (SQLException sqe) { throw new IdentifierException(sqe.getMessage(), sqe); } } public static String retrieveHandleOutOfUrl(String url) throws SQLException { // We can do nothing with this, return null if (!url.contains("/")) { return null; } String[] splitUrl = url.split("/"); return splitUrl[splitUrl.length - 2] + "/" + splitUrl[splitUrl.length - 1]; } /** * Get the configured Handle prefix string, or a default * * @return configured prefix or "123456789" */ public static String getPrefix() { ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); String prefix = configurationService.getProperty("handle.prefix"); if (null == prefix) { prefix = EXAMPLE_PREFIX; // XXX no good way to exit cleanly log.error("handle.prefix is not configured; using " + prefix); } return prefix; } protected void populateHandleMetadata(Context context, DSpaceObject dso, String handle) throws SQLException, IOException, AuthorizeException { String handleref = handleService.getCanonicalForm(handle); DSpaceObjectService dsoService = contentServiceFactory.getDSpaceObjectService(dso); // Add handle as identifier.uri DC value. // First check that identifier doesn't already exist. boolean identifierExists = false; List identifiers = dsoService .getMetadata(dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", Item.ANY); for (MetadataValue identifier : identifiers) { if (handleref.equals(identifier.getValue())) { identifierExists = true; } } if (!identifierExists) { dsoService.addMetadata(context, dso, MetadataSchemaEnum.DC.getName(), "identifier", "uri", null, handleref); } } }