DSpace refactored service api

This commit is contained in:
KevinVdV
2014-11-08 09:19:09 +01:00
parent fcb3717aad
commit 54222f3c1d
1145 changed files with 52233 additions and 57064 deletions

View File

@@ -10,19 +10,22 @@ package org.dspace.identifier;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.*;
import org.dspace.content.service.ItemService;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.utils.DSpace;
import org.dspace.handle.service.HandleService;
import org.dspace.versioning.*;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
/**
*
@@ -43,8 +46,17 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
private String[] supportedPrefixes = new String[]{"info:hdl", "hdl", "http://"};
private VersionDAO versionDAO;
private VersionHistoryDAO versionHistoryDAO;
@Autowired(required = true)
private VersioningService versionService;
@Autowired(required = true)
private VersionHistoryService versionHistoryService;
@Autowired(required = true)
private HandleService handleService;
@Autowired(required = true)
private ItemService itemService;
@Override
public boolean supports(Class<? extends Identifier> identifier)
@@ -52,6 +64,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
return Handle.class.isAssignableFrom(identifier);
}
@Override
public boolean supports(String identifier)
{
for(String prefix : supportedPrefixes)
@@ -75,6 +88,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
return false;
}
@Override
public String register(Context context, DSpaceObject dso)
{
try
@@ -85,30 +99,29 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
if(dso != null && dso.getType() == Constants.ITEM)
{
Item item = (Item)dso;
VersionHistory history = retrieveVersionHistory(context, (Item)dso);
VersionHistory history = versionHistoryService.findByItem(context, (Item) dso);
if(history!=null)
{
String canonical = getCanonical(item);
String canonical = getCanonical(context, item);
// Modify Canonical: 12345/100 will point to the new item
TableRow canonicalRecord = findHandleInternal(context, canonical);
modifyHandleRecord(context, dso, canonicalRecord, canonical);
handleService.modifyHandleDSpaceObject(context, canonical, item);
// in case of first version we have to modify the previous metadata to be xxxx.1
Version version = history.getVersion(item);
Version previous = history.getPrevious(version);
if (history.isFirstVersion(previous))
Version version = versionService.getVersion(context, item);
Version previous = versionHistoryService.getPrevious(history, version);
if (versionHistoryService.isFirstVersion(history, previous))
{
modifyHandleMetadata(previous.getItem(), (canonical + DOT + 1));
modifyHandleMetadata(context, previous.getItem(), (canonical + DOT + 1));
}
// Check if our previous item hasn't got a handle anymore.
// This only occurs when a switch has been made from the standard handle identifier provider
// to the versioned one, in this case no "versioned handle" is reserved so we need to create one
if(previous != null && getHandleInternal(context, Constants.ITEM, previous.getItemID()) == null){
if(previous != null && handleService.findHandle(context, previous.getItem()) == null){
makeIdentifierBasedOnHistory(context, previous.getItem(), canonical, history);
}
}
populateHandleMetadata(item);
populateHandleMetadata(context, item);
}
return id;
@@ -118,6 +131,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
}
}
@Override
public void register(Context context, DSpaceObject dso, String identifier)
{
try
@@ -132,7 +146,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
VersionHistory itemHistory = getHistory(context, identifier);
if(!identifier.matches(".*/.*\\.\\d+") && itemHistory!=null){
int newVersionNumber = itemHistory.getLatestVersion().getVersionNumber()+1;
int newVersionNumber = versionHistoryService.getLatestVersion(itemHistory).getVersionNumber()+1;
String canonical = identifier;
identifier = identifier.concat(".").concat("" + newVersionNumber);
restoreItAsVersion(context, dso, identifier, item, canonical, itemHistory);
@@ -148,7 +162,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
restoreItAsCanonical(context, dso, identifier, item, canonical);
}
else{
VersionHistory history = retrieveVersionHistory(context, (Item)canonicalItem);
VersionHistory history = versionHistoryService.findByItem(context, (Item) canonicalItem);
if(history==null){
restoreItAsCanonical(context, dso, identifier, item, canonical);
}
@@ -165,7 +179,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
createNewIdentifier(context, dso, identifier);
if(dso instanceof Item)
{
populateHandleMetadata(item);
populateHandleMetadata(context, item);
}
}
}catch (Exception e){
@@ -174,53 +188,50 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
}
}
private VersionHistory getHistory(Context context, String identifier)
{
protected VersionHistory getHistory(Context context, String identifier) throws SQLException {
DSpaceObject item = this.resolve(context, identifier);
if(item!=null){
VersionHistory history = retrieveVersionHistory(context, (Item)item);
VersionHistory history = versionHistoryService.findByItem(context, (Item) item);
return history;
}
return null;
}
private void restoreItAsVersion(Context context, DSpaceObject dso, String identifier, Item item, String canonical, VersionHistory history) throws SQLException, IOException, AuthorizeException
protected void restoreItAsVersion(Context context, DSpaceObject dso, String identifier, Item item, String canonical, VersionHistory history) throws SQLException, IOException, AuthorizeException
{
createNewIdentifier(context, dso, identifier);
populateHandleMetadata(item);
populateHandleMetadata(context, item);
int versionNumber = Integer.parseInt(identifier.substring(identifier.lastIndexOf(".") + 1));
createVersion(context, history, item, "Restoring from AIP Service", new Date(), versionNumber);
Version latest = history.getLatestVersion();
versionService.createNewVersion(context, history, item, "Restoring from AIP Service", new Date(), versionNumber);
Version latest = versionHistoryService.getLatestVersion(history);
// if restoring the lastest version: needed to move the canonical
if(latest.getVersionNumber() < versionNumber){
TableRow canonicalRecord = findHandleInternal(context, canonical);
modifyHandleRecord(context, dso, canonicalRecord, canonical);
handleService.modifyHandleDSpaceObject(context, canonical, dso);
}
}
private void restoreItAsCanonical(Context context, DSpaceObject dso, String identifier, Item item, String canonical) throws SQLException, IOException, AuthorizeException
protected void restoreItAsCanonical(Context context, DSpaceObject dso, String identifier, Item item, String canonical) throws SQLException, IOException, AuthorizeException
{
createNewIdentifier(context, dso, identifier);
populateHandleMetadata(item);
populateHandleMetadata(context, item);
int versionNumber = Integer.parseInt(identifier.substring(identifier.lastIndexOf(".")+1));
VersionHistory history=versionHistoryDAO.create(context);
createVersion(context, history, item, "Restoring from AIP Service", new Date(), versionNumber);
VersionHistory history=versionHistoryService.create(context);
versionService.createNewVersion(context, history, item, "Restoring from AIP Service", new Date(), versionNumber);
TableRow canonicalRecord = findHandleInternal(context, canonical);
modifyHandleRecord(context, dso, canonicalRecord, canonical);
handleService.modifyHandleDSpaceObject(context, canonical, dso);
}
@Override
public void reserve(Context context, DSpaceObject dso, String identifier)
{
try{
TableRow handle = DatabaseManager.create(context, "Handle");
modifyHandleRecord(context, dso, handle, identifier);
handleService.createHandle(context, dso, identifier);
}catch(Exception e){
log.error(LogManager.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());
@@ -235,6 +246,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
* @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)
@@ -247,7 +259,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
VersionHistory history = null;
if(dso instanceof Item)
{
history = retrieveVersionHistory(context, (Item)dso);
history = versionHistoryService.findByItem(context, (Item) dso);
}
if(history!=null)
@@ -263,78 +275,15 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
}
}
@Override
public DSpaceObject resolve(Context context, String identifier, String... attributes)
{
// We can do nothing with this, return null
try{
TableRow dbhandle = findHandleInternal(context, identifier);
if (dbhandle == null)
{
//Check for an url
identifier = retrieveHandleOutOfUrl(identifier);
if(identifier != null)
{
dbhandle = findHandleInternal(context, identifier);
}
if(dbhandle == null)
{
return null;
}
}
if ((dbhandle.isColumnNull("resource_type_id"))
|| (dbhandle.isColumnNull("resource_id")))
{
throw new IllegalStateException("No associated resource type");
}
// What are we looking at here?
int handletypeid = dbhandle.getIntColumn("resource_type_id");
int resourceID = dbhandle.getIntColumn("resource_id");
if (handletypeid == Constants.ITEM)
{
Item item = Item.find(context, resourceID);
if (log.isDebugEnabled())
{
log.debug("Resolved handle " + identifier + " to item "
+ ((item == null) ? (-1) : item.getID()));
}
return item;
}
else if (handletypeid == Constants.COLLECTION)
{
Collection collection = Collection.find(context, resourceID);
if (log.isDebugEnabled()) {
log.debug("Resolved handle " + identifier + " to collection "
+ ((collection == null) ? (-1) : collection.getID()));
}
return collection;
}
else if (handletypeid == Constants.COMMUNITY)
{
Community community = Community.find(context, resourceID);
if (log.isDebugEnabled()) {
log.debug("Resolved handle " + identifier + " to community "
+ ((community == null) ? (-1) : community.getID()));
}
return community;
}
return handleService.resolveToObject(context, identifier);
}catch (Exception e){
log.error(LogManager.getHeader(context, "Error while resolving handle to item", "handle: " + identifier), e);
}
// throw new IllegalStateException("Unsupported Handle Type "
// + Constants.typeText[handletypeid]);
return null;
}
@@ -343,22 +292,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
try
{
TableRow row = getHandleInternal(context, dso.getType(), dso.getID());
if (row == null)
{
if (dso.getType() == Constants.SITE)
{
return Site.getSiteHandle();
}
else
{
return null;
}
}
else
{
return row.getStringColumn("handle");
}
return handleService.findHandle(context, dso);
}catch(SQLException sqe){
throw new IdentifierNotResolvableException(sqe.getMessage(),sqe);
}
@@ -369,6 +303,7 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
delete(context, dso);
}
@Override
public void delete(Context context, DSpaceObject dso) throws IdentifierException {
try {
@@ -377,15 +312,14 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
Item item = (Item) dso;
// If it is the most current version occurs to move the canonical to the previous version
VersionHistory history = retrieveVersionHistory(context, item);
if(history!=null && history.getLatestVersion().getItem().equals(item) && history.size() > 1)
VersionHistory history = versionHistoryService.findByItem(context, item);
if(history!=null && versionHistoryService.getLatestVersion(history).getItem().equals(item) && history.getVersions().size() > 1)
{
Item previous = history.getPrevious(history.getLatestVersion()).getItem();
Item previous = versionHistoryService.getPrevious(history, versionHistoryService.getLatestVersion(history)).getItem();
// Modify Canonical: 12345/100 will point to the new item
String canonical = getCanonical(previous);
TableRow canonicalRecord = findHandleInternal(context, canonical);
modifyHandleRecord(context, previous, canonicalRecord, canonical);
String canonical = getCanonical(context, previous);
handleService.modifyHandleDSpaceObject(context, canonical, previous);
}
}
} catch (Exception e) {
@@ -437,57 +371,12 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
}
protected String createNewIdentifier(Context context, DSpaceObject dso, String handleId) throws SQLException {
TableRow handle=null;
if(handleId != null)
if(handleId == null)
{
handle = findHandleInternal(context, handleId);
if(handle!=null && !handle.isColumnNull("resource_id"))
{
//Check if this handle is already linked up to this specified DSpace Object
int resourceID = handle.getIntColumn("resource_id");
int resourceType = handle.getIntColumn("resource_type_id");
if(resourceID==dso.getID() && resourceType ==dso.getType())
{
//This handle already links to this DSpace Object -- so, there's nothing else we need to do
return handleId;
}
else
{
//handle found in DB table & already in use by another existing resource
throw new IllegalStateException("Attempted to create a handle which is already in use: " + handleId);
}
}
return handleService.createHandle(context, dso);
}else{
return handleService.createHandle(context, dso, handleId);
}
else if(handle!=null && !handle.isColumnNull("resource_type_id"))
{
//If there is a 'resource_type_id' (but 'resource_id' is empty), then the object using
// this handle was previously unbound (see unbindHandle() method) -- likely because object was deleted
int previousType = handle.getIntColumn("resource_type_id");
//Since we are restoring an object to a pre-existing handle, double check we are restoring the same *type* of object
// (e.g. we will not allow an Item to be restored to a handle previously used by a Collection)
if(previousType != dso.getType())
{
throw new IllegalStateException("Attempted to reuse a handle previously used by a " +
Constants.typeText[previousType] + " for a new " +
Constants.typeText[dso.getType()]);
}
}
if(handle==null){
handle = DatabaseManager.create(context, "Handle");
}
if(handleId==null)
handleId = createId(handle.getIntColumn("handle_id"));
modifyHandleRecord(context, dso, handle, handleId);
return handleId;
}
protected String makeIdentifierBasedOnHistory(Context context, DSpaceObject dso, String handleId, VersionHistory history) throws AuthorizeException, SQLException
@@ -497,18 +386,17 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
// FIRST time a VERSION is created 2 identifiers will be minted and the canonical will be updated to point to the newer URL:
// - id.1-->old URL
// - id.2-->new URL
Version version = history.getVersion(item);
Version previous = history.getPrevious(version);
String canonical = getCanonical(previous.getItem());
if (history.isFirstVersion(previous))
Version version = versionService.getVersion(context, item);
Version previous = versionHistoryService.getPrevious(history, version);
String canonical = getCanonical(context, previous.getItem());
if (versionHistoryService.isFirstVersion(history, previous))
{
// add a new Identifier for previous item: 12345/100.1
String identifierPreviousItem=canonical + DOT + 1;
String identifierPreviousItem=canonical + DOT + previous.getVersionNumber();
//Make sure that this hasn't happened already
if(findHandleInternal(context, identifierPreviousItem) == null)
if(handleService.resolveToObject(context, identifierPreviousItem) == null)
{
TableRow handle = DatabaseManager.create(context, "Handle");
modifyHandleRecord(context, previous.getItem(), handle, identifierPreviousItem);
handleService.createHandle(context, previous.getItem(), identifierPreviousItem, true);
}
}
@@ -516,34 +404,19 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
// add a new Identifier for this item: 12345/100.x
String idNew = canonical + DOT + version.getVersionNumber();
//Make sure we don't have an old handle hanging around (if our previous version was deleted in the workspace)
TableRow handleRow = findHandleInternal(context, idNew);
if(handleRow == null)
if(handleService.resolveToObject(context, idNew) == null)
{
handleRow = DatabaseManager.create(context, "Handle");
handleService.createHandle(context, dso, idNew);
}else{
handleService.modifyHandleDSpaceObject(context, idNew, dso);
}
modifyHandleRecord(context, dso, handleRow, idNew);
return handleId;
}
protected String modifyHandleRecord(Context context, DSpaceObject dso, TableRow handle, String handleId) throws SQLException
{
handle.setColumn("handle", handleId);
handle.setColumn("resource_type_id", dso.getType());
handle.setColumn("resource_id", dso.getID());
DatabaseManager.update(context, handle);
if (log.isDebugEnabled())
{
log.debug("Created new handle for "
+ Constants.typeText[dso.getType()] + " " + handleId);
}
return handleId;
}
protected String getCanonical(Item item)
{
protected String getCanonical(Context context, Item item) throws SQLException {
String canonical = item.getHandle();
if( canonical.matches(".*/.*\\.\\d+") && canonical.lastIndexOf(DOT)!=-1)
{
@@ -564,138 +437,35 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
return canonical;
}
/**
* Find the database row corresponding to handle.
*
* @param context DSpace context
* @param handle The handle to resolve
* @return The database row corresponding to the handle
* @exception java.sql.SQLException If a database error occurs
*/
protected static TableRow findHandleInternal(Context context, String handle)
throws SQLException {
if (handle == null)
{
throw new IllegalArgumentException("Handle is null");
}
return DatabaseManager.findByUnique(context, "Handle", "handle", handle);
}
/**
* Return the handle for an Object, or null if the Object has no handle.
*
* @param context
* DSpace context
* @param type
* The type of object
* @param id
* The id of object
* @return The handle for object, or null if the object has no handle.
* @exception java.sql.SQLException
* If a database error occurs
*/
protected static TableRow getHandleInternal(Context context, int type, int id)
throws SQLException
{
String sql = "SELECT * FROM Handle WHERE resource_type_id = ? AND resource_id = ?";
return DatabaseManager.querySingleTable(context, "Handle", sql, type, id);
}
/**
* Create a new handle id. The implementation uses the PK of the RDBMS
* Handle table.
*
* @return A new handle id
* @exception java.sql.SQLException
* If a database error occurs
*/
protected static String createId(int id) throws SQLException
{
String handlePrefix = getPrefix();
return handlePrefix + (handlePrefix.endsWith("/") ? "" : "/") + id;
}
protected VersionHistory retrieveVersionHistory(Context c, Item item)
{
VersioningService versioningService = new DSpace().getSingletonService(VersioningService.class);
return versioningService.findVersionHistory(c, item.getID());
}
protected void populateHandleMetadata(Item item)
protected void populateHandleMetadata(Context context, Item item)
throws SQLException, IOException, AuthorizeException
{
String handleref = getCanonicalForm(getCanonical(item));
String handleref = getCanonicalForm(getCanonical(context, item));
// Add handle as identifier.uri DC value.
// First check that identifier doesn't already exist.
boolean identifierExists = false;
Metadatum[] identifiers = item.getDC("identifier", "uri", Item.ANY);
for (Metadatum identifier : identifiers)
List<MetadataValue> identifiers = itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "identifier", "uri", Item.ANY);
for (MetadataValue identifier : identifiers)
{
if (handleref.equals(identifier.value))
if (handleref.equals(identifier.getValue()))
{
identifierExists = true;
}
}
if (!identifierExists)
{
item.addDC("identifier", "uri", null, handleref);
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "identifier", "uri", null, handleref);
}
}
protected void modifyHandleMetadata(Item item, String handle)
protected void modifyHandleMetadata(Context context, Item item, String handle)
throws SQLException, IOException, AuthorizeException
{
String handleref = getCanonicalForm(handle);
item.clearMetadata("dc", "identifier", "uri", Item.ANY);
item.addDC("identifier", "uri", null, handleref);
item.update();
}
protected VersionImpl createVersion(Context c, VersionHistory vh, Item item, String summary, Date date, int versionNumber) {
try {
VersionImpl version = versionDAO.create(c);
// check if an equals versionNumber is already present in the DB (at this point it should never happen).
if(vh!=null && vh.getVersions()!=null){
for(Version v : vh.getVersions()){
if(v.getVersionNumber()==versionNumber){
throw new RuntimeException("A Version for this versionNumber is already present. Impossible complete the operation.");
}
}
}
version.setVersionNumber(versionNumber);
version.setVersionDate(date);
version.setEperson(item.getSubmitter());
version.setItemID(item.getID());
version.setSummary(summary);
version.setVersionHistory(vh.getVersionHistoryId());
versionDAO.update(version);
return version;
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
protected int getNextVersionNumer(Version latest){
if(latest==null) return 1;
return latest.getVersionNumber()+1;
}
public void setVersionDAO(VersionDAO versionDAO)
{
this.versionDAO = versionDAO;
}
public void setVersionHistoryDAO(VersionHistoryDAO versionHistoryDAO)
{
this.versionHistoryDAO = versionHistoryDAO;
itemService.clearMetadata(context, item, MetadataSchema.DC_SCHEMA, "identifier", "uri", Item.ANY);
itemService.addMetadata(context, item, MetadataSchema.DC_SCHEMA, "identifier", "uri", null, handleref);
itemService.update(context, item);
}
}