DS-1990: Events should contain all identifiers, not only handles.

This commit is contained in:
Pascal-Nicolas Becker
2014-05-15 21:29:53 +02:00
parent 2dec016ed2
commit b1e822a87f
13 changed files with 299 additions and 49 deletions

View File

@@ -201,6 +201,9 @@ public class Bundle extends DSpaceObject
log.info(LogManager.getHeader(context, "create_bundle", "bundle_id=" log.info(LogManager.getHeader(context, "create_bundle", "bundle_id="
+ row.getIntColumn("bundle_id"))); + row.getIntColumn("bundle_id")));
// if we ever use the identifier service for bundles, we should
// create the bundle before we create the Event and should add all
// identifiers to it.
context.addEvent(new Event(Event.CREATE, Constants.BUNDLE, row.getIntColumn("bundle_id"), null)); context.addEvent(new Event(Event.CREATE, Constants.BUNDLE, row.getIntColumn("bundle_id"), null));
return new Bundle(context, row); return new Bundle(context, row);
@@ -443,7 +446,9 @@ public class Bundle extends DSpaceObject
// Add the bitstream object // Add the bitstream object
bitstreams.add(b); bitstreams.add(b);
ourContext.addEvent(new Event(Event.ADD, Constants.BUNDLE, getID(), Constants.BITSTREAM, b.getID(), String.valueOf(b.getSequenceID()))); ourContext.addEvent(new Event(Event.ADD, Constants.BUNDLE, getID(),
Constants.BITSTREAM, b.getID(), String.valueOf(b.getSequenceID()),
lookupIdentifiers(ourContext)));
// copy authorization policies from bundle to bitstream // copy authorization policies from bundle to bitstream
// FIXME: multiple inclusion is affected by this... // FIXME: multiple inclusion is affected by this...
@@ -546,7 +551,9 @@ public class Bundle extends DSpaceObject
} }
} }
ourContext.addEvent(new Event(Event.REMOVE, Constants.BUNDLE, getID(), Constants.BITSTREAM, b.getID(), String.valueOf(b.getSequenceID()))); ourContext.addEvent(new Event(Event.REMOVE, Constants.BUNDLE, getID(),
Constants.BITSTREAM, b.getID(), String.valueOf(b.getSequenceID()),
lookupIdentifiers(ourContext)));
//Ensure that the last modified from the item is triggered ! //Ensure that the last modified from the item is triggered !
Item owningItem = (Item) getParentObject(); Item owningItem = (Item) getParentObject();
@@ -606,12 +613,14 @@ public class Bundle extends DSpaceObject
if (modified) if (modified)
{ {
ourContext.addEvent(new Event(Event.MODIFY, Constants.BUNDLE, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.BUNDLE, getID(),
null, lookupIdentifiers(ourContext)));
modified = false; modified = false;
} }
if (modifiedMetadata) if (modifiedMetadata)
{ {
ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.BUNDLE, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.BUNDLE,
getID(), null, lookupIdentifiers(ourContext)));
modifiedMetadata = false; modifiedMetadata = false;
} }
@@ -628,7 +637,8 @@ public class Bundle extends DSpaceObject
log.info(LogManager.getHeader(ourContext, "delete_bundle", "bundle_id=" log.info(LogManager.getHeader(ourContext, "delete_bundle", "bundle_id="
+ getID())); + getID()));
ourContext.addEvent(new Event(Event.DELETE, Constants.BUNDLE, getID(), getName())); ourContext.addEvent(new Event(Event.DELETE, Constants.BUNDLE, getID(),
getName(), lookupIdentifiers(ourContext)));
// Remove from cache // Remove from cache
ourContext.removeCached(this, getID()); ourContext.removeCached(this, getID());

View File

@@ -279,7 +279,8 @@ public class Collection extends DSpaceObject
myPolicy.setGroup(anonymousGroup); myPolicy.setGroup(anonymousGroup);
myPolicy.update(); myPolicy.update();
context.addEvent(new Event(Event.CREATE, Constants.COLLECTION, c.getID(), c.handle)); context.addEvent(new Event(Event.CREATE, Constants.COLLECTION,
c.getID(), c.handle, c.lookupIdentifiers(context)));
log.info(LogManager.getHeader(context, "create_collection", log.info(LogManager.getHeader(context, "create_collection",
"collection_id=" + row.getIntColumn("collection_id")) "collection_id=" + row.getIntColumn("collection_id"))
@@ -969,7 +970,8 @@ public class Collection extends DSpaceObject
template = null; template = null;
} }
ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION, getID(), "remove_template_item")); ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION,
getID(), "remove_template_item", lookupIdentifiers(ourContext)));
} }
/** /**
@@ -999,7 +1001,9 @@ public class Collection extends DSpaceObject
DatabaseManager.insert(ourContext, row); DatabaseManager.insert(ourContext, row);
ourContext.addEvent(new Event(Event.ADD, Constants.COLLECTION, getID(), Constants.ITEM, item.getID(), item.getHandle())); ourContext.addEvent(new Event(Event.ADD, Constants.COLLECTION, getID(),
Constants.ITEM, item.getID(), item.getHandle(),
lookupIdentifiers(ourContext)));
} }
/** /**
@@ -1037,7 +1041,9 @@ public class Collection extends DSpaceObject
getID(), item.getID()); getID(), item.getID());
DatabaseManager.setConstraintImmediate(ourContext, "coll2item_item_fk"); DatabaseManager.setConstraintImmediate(ourContext, "coll2item_item_fk");
ourContext.addEvent(new Event(Event.REMOVE, Constants.COLLECTION, getID(), Constants.ITEM, item.getID(), item.getHandle())); ourContext.addEvent(new Event(Event.REMOVE, Constants.COLLECTION,
getID(), Constants.ITEM, item.getID(), item.getHandle(),
lookupIdentifiers(ourContext)));
} }
/** /**
@@ -1060,12 +1066,15 @@ public class Collection extends DSpaceObject
if (modified) if (modified)
{ {
ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION,
getID(), null, lookupIdentifiers(ourContext)));
modified = false; modified = false;
} }
if (modifiedMetadata) if (modifiedMetadata)
{ {
ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.COLLECTION, getID(), getDetails())); ourContext.addEvent(new Event(Event.MODIFY_METADATA,
Constants.COLLECTION, getID(), getDetails(),
lookupIdentifiers(ourContext)));
modifiedMetadata = false; modifiedMetadata = false;
clearDetails(); clearDetails();
} }
@@ -1131,7 +1140,8 @@ public class Collection extends DSpaceObject
log.info(LogManager.getHeader(ourContext, "delete_collection", log.info(LogManager.getHeader(ourContext, "delete_collection",
"collection_id=" + getID())); "collection_id=" + getID()));
ourContext.addEvent(new Event(Event.DELETE, Constants.COLLECTION, getID(), getHandle())); ourContext.addEvent(new Event(Event.DELETE, Constants.COLLECTION,
getID(), getHandle(), lookupIdentifiers(ourContext)));
// Remove from cache // Remove from cache
ourContext.removeCached(this, getID()); ourContext.removeCached(this, getID());
@@ -1566,6 +1576,7 @@ public class Collection extends DSpaceObject
public void updateLastModified() public void updateLastModified()
{ {
//Also fire a modified event since the collection HAS been modified //Also fire a modified event since the collection HAS been modified
ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.COLLECTION,
getID(), null, lookupIdentifiers(ourContext)));
} }
} }

View File

@@ -232,12 +232,15 @@ public class Community extends DSpaceObject
myPolicy.setGroup(anonymousGroup); myPolicy.setGroup(anonymousGroup);
myPolicy.update(); myPolicy.update();
context.addEvent(new Event(Event.CREATE, Constants.COMMUNITY, c.getID(), c.handle)); context.addEvent(new Event(Event.CREATE, Constants.COMMUNITY, c.getID(),
c.handle, c.lookupIdentifiers(context)));
// if creating a top-level Community, simulate an ADD event at the Site. // if creating a top-level Community, simulate an ADD event at the Site.
if (parent == null) if (parent == null)
{ {
context.addEvent(new Event(Event.ADD, Constants.SITE, Site.SITE_ID, Constants.COMMUNITY, c.getID(), c.handle)); context.addEvent(new Event(Event.ADD, Constants.SITE, Site.SITE_ID,
Constants.COMMUNITY, c.getID(), c.handle,
c.lookupIdentifiers(context)));
} }
log.info(LogManager.getHeader(context, "create_community", log.info(LogManager.getHeader(context, "create_community",
@@ -527,12 +530,15 @@ public class Community extends DSpaceObject
if (modified) if (modified)
{ {
ourContext.addEvent(new Event(Event.MODIFY, Constants.COMMUNITY, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.COMMUNITY,
getID(), null, lookupIdentifiers(ourContext)));
modified = false; modified = false;
} }
if (modifiedMetadata) if (modifiedMetadata)
{ {
ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.COMMUNITY, getID(), getDetails())); ourContext.addEvent(new Event(Event.MODIFY_METADATA,
Constants.COMMUNITY, getID(), getDetails(),
lookupIdentifiers(ourContext)));
modifiedMetadata = false; modifiedMetadata = false;
clearDetails(); clearDetails();
} }
@@ -903,7 +909,9 @@ public class Community extends DSpaceObject
mappingRow.setColumn("community_id", getID()); mappingRow.setColumn("community_id", getID());
mappingRow.setColumn("collection_id", c.getID()); mappingRow.setColumn("collection_id", c.getID());
ourContext.addEvent(new Event(Event.ADD, Constants.COMMUNITY, getID(), Constants.COLLECTION, c.getID(), c.getHandle())); ourContext.addEvent(new Event(Event.ADD, Constants.COMMUNITY,
getID(), Constants.COLLECTION, c.getID(), c.getHandle(),
lookupIdentifiers(ourContext)));
DatabaseManager.insert(ourContext, mappingRow); DatabaseManager.insert(ourContext, mappingRow);
} }
@@ -978,7 +986,9 @@ public class Community extends DSpaceObject
mappingRow.setColumn("parent_comm_id", getID()); mappingRow.setColumn("parent_comm_id", getID());
mappingRow.setColumn("child_comm_id", c.getID()); mappingRow.setColumn("child_comm_id", c.getID());
ourContext.addEvent(new Event(Event.ADD, Constants.COMMUNITY, getID(), Constants.COMMUNITY, c.getID(), c.getHandle())); ourContext.addEvent(new Event(Event.ADD, Constants.COMMUNITY,
getID(), Constants.COMMUNITY, c.getID(), c.getHandle(),
lookupIdentifiers(ourContext)));
DatabaseManager.insert(ourContext, mappingRow); DatabaseManager.insert(ourContext, mappingRow);
} }
@@ -1016,6 +1026,7 @@ public class Community extends DSpaceObject
// Capture ID & Handle of Collection we are removing, so we can trigger events later // Capture ID & Handle of Collection we are removing, so we can trigger events later
int removedId = c.getID(); int removedId = c.getID();
String removedHandle = c.getHandle(); String removedHandle = c.getHandle();
String[] removedIdentifiers = c.lookupIdentifiers(ourContext);
// How many parent(s) does this collection have? // How many parent(s) does this collection have?
TableRow trow = DatabaseManager.querySingle(ourContext, TableRow trow = DatabaseManager.querySingle(ourContext,
@@ -1041,7 +1052,8 @@ public class Community extends DSpaceObject
log.info(LogManager.getHeader(ourContext, "remove_collection", log.info(LogManager.getHeader(ourContext, "remove_collection",
"community_id=" + getID() + ",collection_id=" + removedId)); "community_id=" + getID() + ",collection_id=" + removedId));
ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(), Constants.COLLECTION, removedId, removedHandle)); ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(),
Constants.COLLECTION, removedId, removedHandle, removedIdentifiers));
} }
catch(SQLException|IOException e) catch(SQLException|IOException e)
{ {
@@ -1075,6 +1087,7 @@ public class Community extends DSpaceObject
// Capture ID & Handle of Community we are removing, so we can trigger events later // Capture ID & Handle of Community we are removing, so we can trigger events later
int removedId = c.getID(); int removedId = c.getID();
String removedHandle = c.getHandle(); String removedHandle = c.getHandle();
String[] removedIdentifiers = c.lookupIdentifiers(ourContext);
// How many parent(s) does this subcommunity have? // How many parent(s) does this subcommunity have?
TableRow trow = DatabaseManager.querySingle(ourContext, TableRow trow = DatabaseManager.querySingle(ourContext,
@@ -1100,7 +1113,7 @@ public class Community extends DSpaceObject
log.info(LogManager.getHeader(ourContext, "remove_subcommunity", log.info(LogManager.getHeader(ourContext, "remove_subcommunity",
"parent_comm_id=" + getID() + ",child_comm_id=" + removedId)); "parent_comm_id=" + getID() + ",child_comm_id=" + removedId));
ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(), Constants.COMMUNITY, removedId, removedHandle)); ourContext.addEvent(new Event(Event.REMOVE, Constants.COMMUNITY, getID(), Constants.COMMUNITY, removedId, removedHandle, removedIdentifiers));
} }
catch(SQLException|IOException e) catch(SQLException|IOException e)
{ {
@@ -1145,7 +1158,7 @@ public class Community extends DSpaceObject
// Since this is a top level Community, simulate a REMOVE event at the Site. // Since this is a top level Community, simulate a REMOVE event at the Site.
ourContext.addEvent(new Event(Event.REMOVE, Constants.SITE, Site.SITE_ID, ourContext.addEvent(new Event(Event.REMOVE, Constants.SITE, Site.SITE_ID,
Constants.COMMUNITY, getID(), getHandle())); Constants.COMMUNITY, getID(), getHandle(), lookupIdentifiers(ourContext)));
} else { } else {
// This is a subcommunity, so let the parent remove it // This is a subcommunity, so let the parent remove it
// NOTE: this essentially just logs event and calls "rawDelete()" // NOTE: this essentially just logs event and calls "rawDelete()"
@@ -1169,6 +1182,7 @@ public class Community extends DSpaceObject
// Capture ID & Handle of object we are removing, so we can trigger events later // Capture ID & Handle of object we are removing, so we can trigger events later
int deletedId = getID(); int deletedId = getID();
String deletedHandle = getHandle(); String deletedHandle = getHandle();
String[] deletedIdentifiers = lookupIdentifiers(ourContext);
// Remove Community object from cache // Remove Community object from cache
ourContext.removeCached(this, getID()); ourContext.removeCached(this, getID());
@@ -1219,7 +1233,7 @@ public class Community extends DSpaceObject
} }
// If everything above worked, then trigger any associated events // If everything above worked, then trigger any associated events
ourContext.addEvent(new Event(Event.DELETE, Constants.COMMUNITY, deletedId, deletedHandle)); ourContext.addEvent(new Event(Event.DELETE, Constants.COMMUNITY, deletedId, deletedHandle, deletedIdentifiers));
} }
/** /**
@@ -1386,6 +1400,7 @@ public class Community extends DSpaceObject
public void updateLastModified() public void updateLastModified()
{ {
//Also fire a modified event since the community HAS been modified //Also fire a modified event since the community HAS been modified
ourContext.addEvent(new Event(Event.MODIFY, Constants.COMMUNITY, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.COMMUNITY,
getID(), null, lookupIdentifiers(ourContext)));
} }
} }

View File

@@ -8,18 +8,24 @@
package org.dspace.content; package org.dspace.content;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
import org.dspace.handle.HandleManager;
import org.dspace.identifier.IdentifierService;
import org.dspace.utils.DSpace;
/** /**
* Abstract base class for DSpace objects * Abstract base class for DSpace objects
*/ */
public abstract class DSpaceObject public abstract class DSpaceObject
{ {
private static final Logger log = Logger.getLogger(DSpaceObject.class);
// accumulate information to add to "detail" element of content Event, // accumulate information to add to "detail" element of content Event,
// e.g. to document metadata fields touched, etc. // e.g. to document metadata fields touched, etc.
private StringBuffer eventDetails = null; private StringBuffer eventDetails = null;
@@ -99,6 +105,32 @@ public abstract class DSpaceObject
*/ */
public abstract String getName(); public abstract String getName();
/**
* Tries to lookup all Identifiers of this DSpaceObject.
* @return An array containing all found identifiers or an array with a length of 0.
*/
public String[] lookupIdentifiers(Context context)
{
String[] identifiers = new String[0];
IdentifierService identifierService =
new DSpace().getSingletonService(IdentifierService.class);
if (identifierService != null)
{
return identifierService.lookup(context, this);
}
log.warn("No IdentifierService found, will return an array containing "
+ "the Handle only.");
if (getHandle() != null)
{
return new String[] { HandleManager.getCanonicalForm(getHandle()) };
}
return new String[0];
}
/** /**
* Generic find for when the precise type of a DSO is not known, just the * Generic find for when the precise type of a DSO is not known, just the
* a pair of type number and database ID. * a pair of type number and database ID.

View File

@@ -224,7 +224,7 @@ public class InstallItem
// Notify interested parties of newly archived Item // Notify interested parties of newly archived Item
c.addEvent(new Event(Event.INSTALL, Constants.ITEM, item.getID(), c.addEvent(new Event(Event.INSTALL, Constants.ITEM, item.getID(),
item.getHandle())); item.getHandle(), item.lookupIdentifiers(c)));
// remove in-progress submission // remove in-progress submission
is.deleteWrapper(); is.deleteWrapper();

View File

@@ -200,7 +200,8 @@ public class Item extends DSpaceObject
i.update(); i.update();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
context.addEvent(new Event(Event.CREATE, Constants.ITEM, i.getID(), null)); context.addEvent(new Event(Event.CREATE, Constants.ITEM, i.getID(),
null, i.lookupIdentifiers(context)));
log.info(LogManager.getHeader(context, "create_item", "item_id=" log.info(LogManager.getHeader(context, "create_item", "item_id="
+ row.getIntColumn("item_id"))); + row.getIntColumn("item_id")));
@@ -357,7 +358,7 @@ public class Item extends DSpaceObject
itemRow.setColumn("last_modified", lastModified); itemRow.setColumn("last_modified", lastModified);
DatabaseManager.updateQuery(ourContext, "UPDATE item SET last_modified = ? WHERE item_id= ? ", lastModified, getID()); DatabaseManager.updateQuery(ourContext, "UPDATE item SET last_modified = ? WHERE item_id= ? ", lastModified, getID());
//Also fire a modified event since the item HAS been modified //Also fire a modified event since the item HAS been modified
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), null, lookupIdentifiers(ourContext)));
} catch (SQLException e) { } catch (SQLException e) {
log.error(LogManager.getHeader(ourContext, "Error while updating last modified timestamp", "Item: " + getID())); log.error(LogManager.getHeader(ourContext, "Error while updating last modified timestamp", "Item: " + getID()));
} }
@@ -1304,7 +1305,9 @@ public class Item extends DSpaceObject
mappingRow.setColumn("bundle_id", b.getID()); mappingRow.setColumn("bundle_id", b.getID());
DatabaseManager.insert(ourContext, mappingRow); DatabaseManager.insert(ourContext, mappingRow);
ourContext.addEvent(new Event(Event.ADD, Constants.ITEM, getID(), Constants.BUNDLE, b.getID(), b.getName())); ourContext.addEvent(new Event(Event.ADD, Constants.ITEM, getID(),
Constants.BUNDLE, b.getID(), b.getName(),
lookupIdentifiers(ourContext)));
} }
/** /**
@@ -1345,7 +1348,8 @@ public class Item extends DSpaceObject
"AND bundle_id= ? ", "AND bundle_id= ? ",
getID(), b.getID()); getID(), b.getID());
ourContext.addEvent(new Event(Event.REMOVE, Constants.ITEM, getID(), Constants.BUNDLE, b.getID(), b.getName())); ourContext.addEvent(new Event(Event.REMOVE, Constants.ITEM, getID(),
Constants.BUNDLE, b.getID(), b.getName(), lookupIdentifiers(ourContext)));
// If the bundle is orphaned, it's removed // If the bundle is orphaned, it's removed
TableRowIterator tri = DatabaseManager.query(ourContext, TableRowIterator tri = DatabaseManager.query(ourContext,
@@ -1805,12 +1809,14 @@ public class Item extends DSpaceObject
if (dublinCoreChanged) if (dublinCoreChanged)
{ {
ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.ITEM, getID(), getDetails())); ourContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.ITEM, getID(),
getDetails(), lookupIdentifiers(ourContext)));
clearDetails(); clearDetails();
dublinCoreChanged = false; dublinCoreChanged = false;
} }
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(),
null, lookupIdentifiers(ourContext)));
modified = false; modified = false;
} }
} }
@@ -1902,7 +1908,8 @@ public class Item extends DSpaceObject
// Update item in DB // Update item in DB
update(); update();
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), "WITHDRAW")); ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(),
"WITHDRAW", lookupIdentifiers(ourContext)));
// remove all authorization policies, saving the custom ones // remove all authorization policies, saving the custom ones
AuthorizeManager.removeAllPoliciesByDSOAndTypeNotEqualsTo(ourContext, this, ResourcePolicy.TYPE_CUSTOM); AuthorizeManager.removeAllPoliciesByDSOAndTypeNotEqualsTo(ourContext, this, ResourcePolicy.TYPE_CUSTOM);
@@ -1959,7 +1966,8 @@ public class Item extends DSpaceObject
// Update item in DB // Update item in DB
update(); update();
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), "REINSTATE")); ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(),
"REINSTATE", lookupIdentifiers(ourContext)));
// authorization policies // authorization policies
if (colls.length > 0) if (colls.length > 0)
@@ -1992,7 +2000,8 @@ public class Item extends DSpaceObject
// leaving the database in an inconsistent state // leaving the database in an inconsistent state
AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE); AuthorizeManager.authorizeAction(ourContext, this, Constants.REMOVE);
ourContext.addEvent(new Event(Event.DELETE, Constants.ITEM, getID(), getHandle())); ourContext.addEvent(new Event(Event.DELETE, Constants.ITEM, getID(),
getHandle(), lookupIdentifiers(ourContext)));
log.info(LogManager.getHeader(ourContext, "delete_item", "item_id=" log.info(LogManager.getHeader(ourContext, "delete_item", "item_id="
+ getID())); + getID()));
@@ -2414,7 +2423,8 @@ public class Item extends DSpaceObject
// Note that updating the owning collection above will have the same effect, // Note that updating the owning collection above will have the same effect,
// so we only do this here if the owning collection hasn't changed. // so we only do this here if the owning collection hasn't changed.
ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(), null)); ourContext.addEvent(new Event(Event.MODIFY, Constants.ITEM, getID(),
null, lookupIdentifiers(ourContext)));
} }
} }

View File

@@ -546,7 +546,8 @@ public class EPerson extends DSpaceObject
log.info(LogManager.getHeader(context, "create_eperson", "eperson_id=" log.info(LogManager.getHeader(context, "create_eperson", "eperson_id="
+ e.getID())); + e.getID()));
context.addEvent(new Event(Event.CREATE, Constants.EPERSON, e.getID(), null)); context.addEvent(new Event(Event.CREATE, Constants.EPERSON, e.getID(),
null, e.lookupIdentifiers(context)));
return e; return e;
} }
@@ -576,7 +577,8 @@ public class EPerson extends DSpaceObject
throw new EPersonDeletionException(constraintList); throw new EPersonDeletionException(constraintList);
} }
myContext.addEvent(new Event(Event.DELETE, Constants.EPERSON, getID(), getEmail())); myContext.addEvent(new Event(Event.DELETE, Constants.EPERSON, getID(),
getEmail(), lookupIdentifiers(myContext)));
// Remove from cache // Remove from cache
myContext.removeCached(this, getID()); myContext.removeCached(this, getID());
@@ -1005,12 +1007,14 @@ public class EPerson extends DSpaceObject
if (modified) if (modified)
{ {
myContext.addEvent(new Event(Event.MODIFY, Constants.EPERSON, getID(), null)); myContext.addEvent(new Event(Event.MODIFY, Constants.EPERSON,
getID(), null, lookupIdentifiers(myContext)));
modified = false; modified = false;
} }
if (modifiedMetadata) if (modifiedMetadata)
{ {
myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.EPERSON, getID(), getDetails())); myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.EPERSON,
getID(), getDetails(), lookupIdentifiers(myContext)));
modifiedMetadata = false; modifiedMetadata = false;
clearDetails(); clearDetails();
} }

View File

@@ -214,7 +214,8 @@ public class Group extends DSpaceObject
log.info(LogManager.getHeader(context, "create_group", "group_id=" log.info(LogManager.getHeader(context, "create_group", "group_id="
+ g.getID())); + g.getID()));
context.addEvent(new Event(Event.CREATE, Constants.GROUP, g.getID(), null)); context.addEvent(new Event(Event.CREATE, Constants.GROUP, g.getID(),
null, g.lookupIdentifiers(context)));
return g; return g;
} }
@@ -270,7 +271,9 @@ public class Group extends DSpaceObject
epeople.add(e); epeople.add(e);
epeopleChanged = true; epeopleChanged = true;
myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), Constants.EPERSON, e.getID(), e.getEmail())); myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(),
Constants.EPERSON, e.getID(), e.getEmail(),
lookupIdentifiers(myContext)));
} }
/** /**
@@ -292,7 +295,9 @@ public class Group extends DSpaceObject
groups.add(g); groups.add(g);
groupsChanged = true; groupsChanged = true;
myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(), Constants.GROUP, g.getID(), g.getName())); myContext.addEvent(new Event(Event.ADD, Constants.GROUP, getID(),
Constants.GROUP, g.getID(), g.getName(),
lookupIdentifiers(myContext)));
} }
/** /**
@@ -308,7 +313,9 @@ public class Group extends DSpaceObject
if (epeople.remove(e)) if (epeople.remove(e))
{ {
epeopleChanged = true; epeopleChanged = true;
myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), Constants.EPERSON, e.getID(), e.getEmail())); myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(),
Constants.EPERSON, e.getID(), e.getEmail(),
lookupIdentifiers(myContext)));
} }
} }
@@ -324,7 +331,9 @@ public class Group extends DSpaceObject
if (groups.remove(g)) if (groups.remove(g))
{ {
groupsChanged = true; groupsChanged = true;
myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(), Constants.GROUP, g.getID(), g.getName())); myContext.addEvent(new Event(Event.REMOVE, Constants.GROUP, getID(),
Constants.GROUP, g.getID(), g.getName(),
lookupIdentifiers(myContext)));
} }
} }
@@ -997,7 +1006,8 @@ public class Group extends DSpaceObject
{ {
// FIXME: authorizations // FIXME: authorizations
myContext.addEvent(new Event(Event.DELETE, Constants.GROUP, getID(), getName())); myContext.addEvent(new Event(Event.DELETE, Constants.GROUP, getID(),
getName(), lookupIdentifiers(myContext)));
// Remove from cache // Remove from cache
myContext.removeCached(this, getID()); myContext.removeCached(this, getID());
@@ -1105,7 +1115,8 @@ public class Group extends DSpaceObject
if (modifiedMetadata) if (modifiedMetadata)
{ {
myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.GROUP, getID(), getDetails())); myContext.addEvent(new Event(Event.MODIFY_METADATA, Constants.GROUP,
getID(), getDetails(), lookupIdentifiers(myContext)));
modifiedMetadata = false; modifiedMetadata = false;
clearDetails(); clearDetails();
} }

View File

@@ -163,6 +163,22 @@ public class Event implements Serializable
*/ */
private String detail; private String detail;
/**
* Contains all identifiers of the DSpaceObject that was changed (added,
* modified, deleted, ...).
*
* All events gets fired when a context that contains events gets commited.
* When the delete event is fired, a deleted DSpaceObject is already gone.
* This array contains all identifiers of the object, not only the handle
* as the detail field does. The field may be an empty array if no
* identifiers could be found.
*
* FIXME: As the detail field describes it would be even better if all
* metadata would be available to a consumer, but the identifiers are the
* most important once.
*/
private String[] identifiers;
/** unique key to bind together events from one context's transaction */ /** unique key to bind together events from one context's transaction */
private String transactionID; private String transactionID;
@@ -182,6 +198,9 @@ public class Event implements Serializable
/** /**
* Constructor. * Constructor.
* *
* You should consider to use
* {@link Event#Event(int, int, int, java.lang.String, java.lang.String[])}.
*
* @param eventType * @param eventType
* action type, e.g. Event.ADD. * action type, e.g. Event.ADD.
* @param subjectType * @param subjectType
@@ -192,17 +211,40 @@ public class Event implements Serializable
* detail information that depends on context. * detail information that depends on context.
*/ */
public Event(int eventType, int subjectType, int subjectID, String detail) public Event(int eventType, int subjectType, int subjectID, String detail)
{
this(eventType, subjectType, subjectID, detail, new String[0]);
}
/**
* Constructor.
*
* @param eventType
* action type, e.g. Event.ADD.
* @param subjectType
* DSpace Object Type of subject e.g. Constants.ITEM.
* @param subjectID
* database ID of subject instance.
* @param detail
* detail information that depends on context.
* @param identifiers
* array containing all identifiers of the dso or an empty array
*/
public Event(int eventType, int subjectType, int subjectID, String detail, String[] identifiers)
{ {
this.eventType = eventType; this.eventType = eventType;
this.subjectType = coreTypeToMask(subjectType); this.subjectType = coreTypeToMask(subjectType);
this.subjectID = subjectID; this.subjectID = subjectID;
timeStamp = System.currentTimeMillis(); timeStamp = System.currentTimeMillis();
this.detail = detail; this.detail = detail;
this.identifiers = identifiers.clone();
} }
/** /**
* Constructor. * Constructor.
* *
* You should consider to use
* {@link Event#Event(int, int, int, int, int, java.lang.String)} instead.
*
* @param eventType * @param eventType
* action type, e.g. Event.ADD. * action type, e.g. Event.ADD.
* @param subjectType * @param subjectType
@@ -218,6 +260,31 @@ public class Event implements Serializable
*/ */
public Event(int eventType, int subjectType, int subjectID, int objectType, public Event(int eventType, int subjectType, int subjectID, int objectType,
int objectID, String detail) int objectID, String detail)
{
this(eventType, subjectType, subjectID, objectType, objectID, detail,
new String[0]);
}
/**
* Constructor.
*
* @param eventType
* action type, e.g. Event.ADD.
* @param subjectType
* DSpace Object Type of subject e.g. Constants.ITEM.
* @param subjectID
* database ID of subject instance.
* @param objectType
* DSpace Object Type of object e.g. Constants.BUNDLE.
* @param objectID
* database ID of object instance.
* @param detail
* detail information that depends on context.
* @param identifiers
* array containing all identifiers of the dso or an empty array
*/
public Event(int eventType, int subjectType, int subjectID, int objectType,
int objectID, String detail, String[] identifiers)
{ {
this.eventType = eventType; this.eventType = eventType;
this.subjectType = coreTypeToMask(subjectType); this.subjectType = coreTypeToMask(subjectType);
@@ -226,6 +293,7 @@ public class Event implements Serializable
this.objectID = objectID; this.objectID = objectID;
timeStamp = System.currentTimeMillis(); timeStamp = System.currentTimeMillis();
this.detail = detail; this.detail = detail;
this.identifiers = identifiers.clone();
} }
/** /**
@@ -507,6 +575,15 @@ public class Event implements Serializable
return detail; return detail;
} }
/**
* @return value of detail element of the event.
*/
public String[] getIdentifiers()
{
// don't return a reference to our private array, clone it.
return identifiers.clone();
}
/** /**
* @return value of transactionID element of the event. * @return value of transactionID element of the event.
*/ */

View File

@@ -10,6 +10,7 @@ package org.dspace.event;
import java.io.PrintStream; import java.io.PrintStream;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
@@ -66,6 +67,8 @@ public class TestConsumer implements Consumer
+ event.getObjectTypeAsString() + event.getObjectTypeAsString()
+ ", ObjectID=" + ", ObjectID="
+ String.valueOf(event.getObjectID()) + String.valueOf(event.getObjectID())
+ ", Identifiers="
+ ArrayUtils.toString(event.getIdentifiers())
+ ", TimeStamp=" + ", TimeStamp="
+ applyDateFormat(new Date(event.getTimeStamp())) + applyDateFormat(new Date(event.getTimeStamp()))
+ ", user=\"" + ", user=\""

View File

@@ -34,6 +34,17 @@ public interface IdentifierService {
*/ */
String lookup(Context context, DSpaceObject dso, Class<? extends Identifier> identifier); String lookup(Context context, DSpaceObject dso, Class<? extends Identifier> identifier);
/**
* Gets the identifiers all registered IdentifierProvider returns if asked
* to lookup the provided DSpaceObject.
*
* @param context
* @param dso the object to be identified.
* @return the matching identifiers, or the site identifier if the object
* is a Site, or an empty array if no matching identifier is found.
*/
String[] lookup(Context contex, DSpaceObject dso);
/** /**
* *
* This will resolve a DSpaceObject based on a provided Identifier. * This will resolve a DSpaceObject based on a provided Identifier.

View File

@@ -15,7 +15,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required; import org.springframework.beans.factory.annotation.Required;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.dspace.handle.HandleManager;
/** /**
* The main service class used to reserve, register and resolve identifiers * The main service class used to reserve, register and resolve identifiers
@@ -134,6 +137,66 @@ public class IdentifierServiceImpl implements IdentifierService {
return null; return null;
} }
@Override
public String[] lookup(Context context, DSpaceObject dso)
{
List<String> identifiers = new ArrayList<>();
for (IdentifierProvider service : providers)
{
try {
String result = service.lookup(context, dso);
if (!StringUtils.isEmpty(result))
{
if (log.isDebugEnabled())
{
try {
log.debug("Got an identifier from "
+ service.getClass().getCanonicalName() + ".");
} catch (NullPointerException ex) {
log.debug(ex.getMessage(), ex);
}
}
identifiers.add(result);
}
}
catch (IdentifierException ex)
{
log.error(ex.getMessage(), ex);
}
}
try {
String handle = dso.getHandle();
if (!StringUtils.isEmpty(handle))
{
if (!identifiers.contains(handle)
&& !identifiers.contains("hdl:" + handle)
&& !identifiers.contains(HandleManager.getCanonicalForm(handle)))
{
// The VerionedHandleIdentifierProvider gets loaded by default
// it returns handles without any scheme (neither hdl: nor http:).
// If the VersionedHandleIdentifierProvider is not loaded,
// we adds the handle in way it would.
// Generally it would be better if identifiers would be added
// here in a way they could be recognized.
log.info("Adding handle '" + handle + "' to the "
+ "array of looked up identifiers.");
identifiers.add(handle);
}
}
}
catch (Exception ex)
{
// nothing is expected here, but if an exception is thrown it
// should not stop everything running.
log.error(ex.getMessage(), ex);
}
log.debug("Found identifiers: " + identifiers.toString());
return identifiers.toArray(new String[0]);
}
public DSpaceObject resolve(Context context, String identifier) throws IdentifierNotFoundException, IdentifierNotResolvableException{ public DSpaceObject resolve(Context context, String identifier) throws IdentifierNotFoundException, IdentifierNotResolvableException{
for (IdentifierProvider service : providers) for (IdentifierProvider service : providers)
{ {

View File

@@ -53,8 +53,11 @@ public class VersioningConsumer implements Consumer {
previousItem.setArchived(false); previousItem.setArchived(false);
itemsToProcess.add(previousItem); itemsToProcess.add(previousItem);
//Fire a new modify event for our previous item //Fire a new modify event for our previous item
//Due to the need to reindex the item in the search & browse index we need to fire a new event //Due to the need to reindex the item in the search
ctx.addEvent(new Event(Event.MODIFY, previousItem.getType(), previousItem.getID(), null)); //and browse index we need to fire a new event
ctx.addEvent(new Event(Event.MODIFY,
previousItem.getType(), previousItem.getID(),
null, previousItem.lookupIdentifiers(ctx)));
} }
} }
} }