moduleProps = configurationService.getPropertyKeys(moduleName);
PackageParameters pkgParams = new PackageParameters();
- //If our config file doesn't load properly, we'll return null
- if(moduleProps!=null)
- {
- //loop through all properties in the config file
- for(String property : moduleProps)
- {
- //Set propertyName, removing leading module name (if applicable)
+ // If our config file doesn't load properly, we'll return null
+ if (moduleProps != null) {
+ // loop through all properties in the config file
+ for (String property : moduleProps) {
+ // Set propertyName, removing leading module name (if applicable)
String propertyName = property;
- if(propertyName.startsWith(moduleName + ".")) {
+ if (propertyName.startsWith(moduleName + ".")) {
propertyName = propertyName.replaceFirst(moduleName + ".", "");
}
- //Only obey the setting(s) beginning with this task's ID/name,
- if(propertyName.startsWith(this.taskId))
- {
- //Parse out the option name by removing the "[taskID]." from beginning of property
+ // Only obey the setting(s) beginning with this task's ID/name,
+ if (propertyName.startsWith(this.taskId)) {
+ // Parse out the option name by removing the "[taskID]." from beginning of property
String option = propertyName.replace(taskId + ".", "");
String value = configurationService.getProperty(property);
- //Check which option is being set
- if(option.equalsIgnoreCase(recursiveMode))
- {
+ // Check which option is being set
+ if (option.equalsIgnoreCase(recursiveMode)) {
pkgParams.setRecursiveModeEnabled(Boolean.parseBoolean(value));
- }
- else if (option.equals(useWorkflow))
- {
+ } else if (option.equals(useWorkflow)) {
pkgParams.setWorkflowEnabled(Boolean.parseBoolean(value));
- }
- else if (option.equals(useCollectionTemplate))
- {
+ } else if (option.equals(useCollectionTemplate)) {
pkgParams.setUseCollectionTemplate(Boolean.parseBoolean(value));
- }
- else //otherwise, assume the Packager will understand what to do with this option
- {
- //just set it as a property in PackageParameters
+ } else {
+ // otherwise, assume the Packager will understand what to do with this option
+ // just set it as a property in PackageParameters
pkgParams.addProperty(option, value);
}
diff --git a/src/main/java/org/dspace/ctask/replicate/BagItReplaceWithAIP.java b/src/main/java/org/dspace/ctask/replicate/BagItReplaceWithAIP.java
index 5240796d..d0d75d05 100644
--- a/src/main/java/org/dspace/ctask/replicate/BagItReplaceWithAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/BagItReplaceWithAIP.java
@@ -57,7 +57,7 @@ public void init(Curator curator, String taskId) throws IOException {
archFmt = configurationService.getProperty("replicate.packer.archfmt");
storeGroupName = configurationService.getProperty("replicate.group.aip.name");
}
-
+
/**
* Perform the 'Replace with AIP' task.
*
@@ -70,7 +70,7 @@ public void init(Curator curator, String taskId) throws IOException {
@Override
public int perform(DSpaceObject dso) throws IOException {
final ReplicaManager repMan = ReplicaManager.instance();
-
+
// overwrite with AIP data
try {
Context context = Curator.curationContext();
diff --git a/src/main/java/org/dspace/ctask/replicate/BagItReplicateConsumer.java b/src/main/java/org/dspace/ctask/replicate/BagItReplicateConsumer.java
index 3acaa063..3d74eeb8 100644
--- a/src/main/java/org/dspace/ctask/replicate/BagItReplicateConsumer.java
+++ b/src/main/java/org/dspace/ctask/replicate/BagItReplicateConsumer.java
@@ -102,25 +102,32 @@ public class BagItReplicateConsumer implements Consumer {
private final String archFmt = configurationService.getProperty("replicate.packer.archfmt");
@Override
- public void initialize() throws Exception
- {
- repMan = ReplicaManager.instance();
+ public void initialize() throws Exception {
+ try {
+ repMan = ReplicaManager.instance();
+ } catch (IOException ioE) {
+ // The ReplicaManager attempts to initialize the ObjectStore specified in the configuration.
+ log.error("Unable to initialize the ReplicaManager. ", ioE);
+ }
+
taskQueue = (TaskQueue) pluginService.getSinglePlugin(TaskQueue.class);
queueName = configurationService.getProperty("replicate.consumer.queue");
+
// look for and load any idFilter files - excludes trump includes
// An "idFilter" is an actual textual file named "exclude" or "include"
// which contains a list of handles to filter from the Consumer
- if (! loadIdFilter("exclude"))
- {
- if (loadIdFilter("include"))
- {
+ if (!loadIdFilter("exclude")) {
+ if (loadIdFilter("include")) {
idExclude = false;
}
}
+
taskQMap = new HashMap>();
taskPMap = new HashMap>();
+
parseTasks("add");
parseTasks("mod");
+
delMemIds = new ArrayList();
parseTasks("del");
}
@@ -142,23 +149,21 @@ public void initialize() throws Exception
* @throws Exception if error
*/
@Override
- public void consume(Context ctx, Event event) throws Exception
- {
+ public void consume(Context ctx, Event event) throws Exception {
int evType = event.getEventType();
int subjType = event.getSubjectType();
+
// This is the Handle of the object on which an event occured
String id = event.getDetail();
- //System.out.println("got event type: " + evType + " for subject type: " + subjType);
- switch (evType)
- {
+
+ // System.out.println("got event type: " + evType + " for subject type: " + subjType);
+ switch (evType) {
case CREATE: //CREATE = Create a new object.
case INSTALL: //INSTALL = Install an object (exits workflow/workspace). Only used for Items.
// if NOT (Item & Create)
// (i.e. We don't want to replicate items UNTIL they are Installed)
- if (subjType != Constants.ITEM || evType != CREATE)
- {
- if (acceptId(id, event, ctx))
- {
+ if (subjType != Constants.ITEM || evType != CREATE) {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of added/new objects
// for which we need to perform tasks
mapId(taskQMap, addQTasks, id);
@@ -166,11 +171,10 @@ public void consume(Context ctx, Event event) throws Exception
}
}
break;
- case MODIFY: //MODIFY = modify an object
- case MODIFY_METADATA: //MODIFY_METADATA = just modify an object's metadata
+ case MODIFY: // MODIFY = modify an object
+ case MODIFY_METADATA: // MODIFY_METADATA = just modify an object's metadata
// If subject of event is null, this means the object was likely deleted
- if (event.getSubject(ctx)==null)
- {
+ if (event.getSubject(ctx) == null) {
log.warn(event.getEventTypeAsString() + " event, could not get object for "
+ event.getSubjectTypeAsString() + " id="
+ String.valueOf(event.getSubjectID())
@@ -178,15 +182,13 @@ public void consume(Context ctx, Event event) throws Exception
break;
}
- //For MODIFY events, the Handle of modified object needs to be obtained from the Subject
+ // For MODIFY events, the Handle of modified object needs to be obtained from the Subject
id = event.getSubject(ctx).getHandle();
// make sure handle resolves - these could be events
// for a newly created item that hasn't been assigned a handle
- if (id != null)
- {
+ if (id != null) {
// make sure we are supposed to process this object
- if (acceptId(id, event, ctx))
- {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, id);
@@ -194,11 +196,10 @@ public void consume(Context ctx, Event event) throws Exception
}
}
break;
- case REMOVE: //REMOVE = Remove an object from a container or group
- case DELETE: //DELETE = Delete an object (actually destroy it)
+ case REMOVE: // REMOVE = Remove an object from a container or group
+ case DELETE: // DELETE = Delete an object (actually destroy it)
// make sure we are supposed to process this object
- if (acceptId(id, event, ctx))
- { // analyze & process the deletion/removal event
+ if (acceptId(id, event, ctx)) { // analyze & process the deletion/removal event
deleteEvent(ctx, id, event);
}
break;
@@ -208,38 +209,33 @@ public void consume(Context ctx, Event event) throws Exception
}
@Override
- public void end(Context ctx) throws Exception
- {
+ public void end(Context ctx) throws Exception {
// if there are any pending objectIds, pass them to the curation
// system to queue for later processing, or perform immediately
EPerson ep = ctx.getCurrentUser();
String name = (ep != null) ? ep.getName() : "unknown";
long stamp = System.currentTimeMillis();
+
// first the queueables
Set entrySet = new HashSet();
- if (taskQMap.size() > 0)
- {
+ if (!taskQMap.isEmpty()) {
List taskList = new ArrayList();
- for (String task : taskQMap.keySet())
- {
+ for (String task : taskQMap.keySet()) {
taskList.add(task);
- for (String id : taskQMap.get(task))
- {
+ for (String id : taskQMap.get(task)) {
entrySet.add(new TaskQueueEntry(name, stamp, taskList, id));
}
taskList.clear();
}
taskQMap.clear();
}
+
// now the performables
- if (taskPMap.size() > 0)
- {
+ if (!taskPMap.isEmpty()) {
Curator curator = new Curator();
- for (String task : taskPMap.keySet())
- {
+ for (String task : taskPMap.keySet()) {
curator.addTask(task);
- for (String id : taskQMap.get(task))
- {
+ for (String id : taskQMap.get(task)) {
curator.curate(ctx, id);
}
curator.clear();
@@ -248,23 +244,20 @@ public void end(Context ctx) throws Exception
}
// if there any uncommitted deletions, record them now
- if (delObjId != null)
- {
- if (delTasks != null)
- {
+ if (delObjId != null) {
+ if (delTasks != null) {
entrySet.add(new TaskQueueEntry(name, stamp, delTasks, delObjId));
}
processDelete(ctx);
}
- if (entrySet.size() > 0)
- {
+
+ if (!entrySet.isEmpty()) {
taskQueue.enqueue(queueName, entrySet);
}
}
@Override
- public void finish(Context ctx) throws Exception
- {
+ public void finish(Context ctx) throws Exception {
// no-op
}
@@ -280,27 +273,25 @@ public void finish(Context ctx) throws Exception
* @return true if this consumer should process this object event, false if it should not
* @throws SQLException if database error occurs
*/
- private boolean acceptId(String id, Event event, Context ctx) throws SQLException
- {
+ private boolean acceptId(String id, Event event, Context ctx) throws SQLException {
// always accept if not filtering
- if (idFilter == null)
- {
+ if (idFilter == null) {
return true;
}
+
// filter supports only container ids - so if id is for an item,
// find its owning collection
String id2check = id;
- if (event.getSubjectType() == Constants.ITEM)
- {
+ if (event.getSubjectType() == Constants.ITEM) {
// NB: Item should be available form context cache - should
// not incur a performance hit here
Item item = itemService.find(ctx, event.getSubjectID());
Collection coll = item.getOwningCollection();
- if (coll != null)
- {
+ if (coll != null) {
id2check = coll.getHandle();
}
}
+
boolean onList = idFilter.contains(id2check);
return idExclude ? ! onList : onList;
}
@@ -314,44 +305,34 @@ private boolean acceptId(String id, Event event, Context ctx) throws SQLExceptio
* @param event event that was triggered
* @throws Exception
*/
- private void deleteEvent(Context ctx, String id, Event event) throws Exception
- {
+ private void deleteEvent(Context ctx, String id, Event event) throws Exception {
int type = event.getEventType();
- if (DELETE == type)
- {
+ if (DELETE == type) {
// either marks start of new deletion or a member of enclosing one
- if (delObjId == null)
- {
+ if (delObjId == null) {
//Start of a new deletion
delObjId = id;
- }
- else
- {
+ } else {
// just add to list of deleted members
delMemIds.add(id);
}
- }
- else if (REMOVE == type)
- {
+ } else if (REMOVE == type) {
// either marks end of current deletion or is member of
// enclosing one: ignore if latter
- if (delObjId.equals(id))
- {
+ if (delObjId.equals(id)) {
// determine owner and write out deletion catalog
- if (Constants.COLLECTION == event.getSubjectType())
- {
+ if (Constants.COLLECTION == event.getSubjectType()) {
// my owner is a collection
Collection ownColl = collectionService.find(ctx, event.getSubjectID());
delOwnerId = ownColl.getHandle();
- }
- else if (Constants.COMMUNITY == event.getSubjectType())
- {
+ } else if (Constants.COMMUNITY == event.getSubjectType()) {
// my owner is a community
Community comm = communityService.find(ctx, event.getSubjectID());
delOwnerId = comm.getHandle();
}
+
processDelete(ctx);
- }
+ }
}
}
@@ -359,9 +340,14 @@ else if (Constants.COMMUNITY == event.getSubjectType())
* Process a deletion event by recording a deletion catalog if configured
*/
private void processDelete(Context context) throws IOException {
+ if (repMan == null) {
+ log.error("The ReplicaManager failed to initialize earlier. Check the logs above.");
+ return;
+ }
+
// write out deletion catalog if defined
if (catalogDeletes) {
- //First, check if this object has an AIP in storage
+ // First, check if this object has an AIP in storage
try {
final String storageId = repMan.storageId(context, delObjId, archFmt);
boolean found = repMan.objectExists(storeGroupName, storageId);
@@ -376,7 +362,7 @@ private void processDelete(Context context) throws IOException {
String catID = repMan.deletionCatalogId(delObjId, null);
File packDir = repMan.stage(context, deleteGroupName, catID);
File archive = packer.pack(packDir);
- //System.out.println("delcat about to transfer");
+ // System.out.println("delcat about to transfer");
repMan.transferObject(deleteGroupName, archive);
}
} catch (AuthorizeException | SQLException e) {
@@ -395,37 +381,27 @@ private void processDelete(Context context) throws IOException {
* @param filterName the name of the textual filter file
* @return true if filter file was loaded successfully, false otherwise
*/
- private boolean loadIdFilter(String filterName)
- {
+ private boolean loadIdFilter(String filterName) {
File filterFile = new File(configurationService.getProperty("replicate.base.dir"), filterName);
- if (filterFile.exists())
- {
+ if (filterFile.exists()) {
idFilter = new ArrayList();
BufferedReader reader = null;
- try
- {
+ try {
reader = new BufferedReader(new FileReader(filterFile));
String id = null;
- while((id = reader.readLine()) != null)
- {
+ while ((id = reader.readLine()) != null) {
idFilter.add(id);
}
return true;
- }
- catch (IOException ioE)
- {
- //log.error("Unable to read filter file '" + filterName + "'");
+ } catch (IOException ioE) {
+ // log.error("Unable to read filter file '" + filterName + "'");
idFilter = null;
- }
- finally
- {
+ } finally {
if (reader != null) {
- try
- {
+ try {
reader.close();
- }
- catch (IOException ioE)
- {
+ } catch (IOException ioE) {
+ // ignore exception
}
}
}
@@ -442,15 +418,11 @@ private boolean loadIdFilter(String filterName)
* @param tasks Tasks to be performed
* @param id Object for which the tasks should be performed.
*/
- private void mapId(Map> map, List tasks, String id)
- {
- if (tasks != null)
- {
- for (String task : tasks)
- {
+ private void mapId(Map> map, List tasks, String id) {
+ if (tasks != null) {
+ for (String task : tasks) {
Set ids = map.get(task);
- if (ids == null)
- {
+ if (ids == null) {
ids = new HashSet();
map.put(task, ids);
}
@@ -464,71 +436,50 @@ private void mapId(Map> map, List tasks, String id)
* is in the 'replicate.cfg' file.
* @param propName property name
*/
- private void parseTasks(String propName)
- {
+ private void parseTasks(String propName) {
String taskStr = configurationService.getProperty("replicate.consumer.tasks." + propName);
- if (taskStr == null || taskStr.length() == 0)
- {
+ if (taskStr == null || taskStr.isEmpty()) {
return;
}
- for (String task : taskStr.split(","))
- {
+ for (String task : taskStr.split(",")) {
task = task.trim();
- //If the task in question does NOT end in "+p",
+ // If the task in question does NOT end in "+p",
// then it should be queued for later processing
- if (! task.endsWith("+p"))
- {
- if ("add".equals(propName))
- {
- if (addQTasks == null)
- {
+ if (! task.endsWith("+p")) {
+ if ("add".equals(propName)) {
+ if (addQTasks == null) {
addQTasks = new ArrayList();
}
addQTasks.add(task);
- }
- else if ("mod".equals(propName))
- {
- if (modQTasks == null)
- {
+ } else if ("mod".equals(propName)) {
+ if (modQTasks == null) {
modQTasks = new ArrayList();
}
modQTasks.add(task);
- }
- else if ("del".equals(propName))
- {
- if (delTasks == null)
- {
+ } else if ("del".equals(propName)) {
+ if (delTasks == null) {
delTasks = new ArrayList();
}
delTasks.add(task);
}
- }
- //Otherwise (if the task ends in "+p"),
- // it should be added to the list of tasks to perform immediately
- else
- {
+ } else {
+ // Otherwise (if the task ends in "+p"),
+ // it should be added to the list of tasks to perform immediately
+
String sTask = task.substring(0, task.lastIndexOf("+p"));
- if ("add".equals(propName))
- {
- if (addPTasks == null)
- {
+ if ("add".equals(propName)) {
+ if (addPTasks == null) {
addPTasks = new ArrayList();
}
addPTasks.add(sTask);
- }
- else if ("mod".equals(propName))
- {
- if (modPTasks == null)
- {
+ } else if ("mod".equals(propName)) {
+ if (modPTasks == null) {
modPTasks = new ArrayList();
}
addPTasks.add(sTask);
- }
- else if ("del".equals(propName))
- {
+ } else if ("del".equals(propName)) {
// just test for special case of deletion catalogs.
- if ("catalog".equals(sTask))
- {
+ if ("catalog".equals(sTask)) {
catalogDeletes = true;
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/BagItRestoreFromAIP.java b/src/main/java/org/dspace/ctask/replicate/BagItRestoreFromAIP.java
index aca07487..1dfb0a08 100644
--- a/src/main/java/org/dspace/ctask/replicate/BagItRestoreFromAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/BagItRestoreFromAIP.java
@@ -63,7 +63,7 @@ public class BagItRestoreFromAIP extends AbstractCurationTask {
// Group where all AIPs are stored
private String storeGroupName;
-
+
// Group where object deletion catalog/records are stored
private String deleteGroupName;
@@ -79,7 +79,7 @@ public void init(Curator curator, String taskId) throws IOException {
storeGroupName = configurationService.getProperty("replicate.group.aip.name");
archFmt = configurationService.getProperty("replicate.packer.archfmt");
}
-
+
/**
* Perform 'Recover From AIP' task on a particular object. If the {@code dso} is a {@link Site}, attempt to restore
* the Site and child objects. Otherwise this method returns an exception.
@@ -136,6 +136,7 @@ public int perform(final DSpaceObject dso) throws IOException {
@Override
public int perform(Context ctx, String id) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
+
// first we locate the deletion catalog for this object
String catId = repMan.deletionCatalogId(id, archFmt);
File catArchive = repMan.fetchObject(ctx, deleteGroupName, catId);
@@ -203,7 +204,7 @@ private void recover(Context ctx, ReplicaManager repMan, String id) throws IOExc
/**
* Recover a DSpace Item from a particular AIP package file
* @param ctx current DSpace context
- * @param archive AIP package file
+ * @param archive AIP package file
* @param objId identifier of object we are restoring
* @param props properties which control how item is restored
* @throws IOException if IO error
@@ -241,7 +242,7 @@ private void recoverItem(Context ctx, File archive, String objId, Properties pro
/**
* Recover a DSpace Collection from a particular AIP package file
* @param ctx current DSpace context
- * @param archive AIP package file
+ * @param archive AIP package file
* @param collId identifier of collection we are restoring
* @param commId identifier of parent community for this collection
* @throws IOException if IO error
@@ -268,7 +269,7 @@ private void recoverCollection(Context ctx, File archive, String collId, String
/**
* Recover a DSpace Community from a particular AIP package file
* @param ctx current DSpace context
- * @param archive AIP package file
+ * @param archive AIP package file
* @param commId identifier of community we are restoring
* @param parentId identifier of parent community (if any) for community
* @throws IOException if IO error
diff --git a/src/main/java/org/dspace/ctask/replicate/CompareWithAIP.java b/src/main/java/org/dspace/ctask/replicate/CompareWithAIP.java
index 0b26a794..1be86f4d 100644
--- a/src/main/java/org/dspace/ctask/replicate/CompareWithAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/CompareWithAIP.java
@@ -31,8 +31,8 @@
/**
* CompareWithAIP task compares local repository values with the replica store
* values. It can perform 2 types of comparison: first, an 'integrity' audit
- * which compares the checksums of the local and remote zipped AIPs; second, a
- * 'count' or enumerative audit that verifies that all child objects of a local
+ * which compares the checksums of the local and remote zipped AIPs; second, a
+ * 'count' or enumerative audit that verifies that all child objects of a local
* container have corresponding replicas in the remote store.
*
* The reason it performs two checks is for performance purposes. We'd rather
@@ -49,13 +49,12 @@
*
* @author richardrodgers
*/
-@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
-public class CompareWithAIP extends AbstractCurationTask
-{
+@Suspendable(invoked = Curator.Invoked.INTERACTIVE)
+public class CompareWithAIP extends AbstractCurationTask {
private String archFmt;
private int status = Curator.CURATE_UNSET;
private String result = null;
-
+
// Group where all AIPs are stored
private String storeGroupName;
@@ -73,21 +72,18 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
String id = dso.getHandle();
status = Curator.CURATE_SUCCESS;
result = "Checksums of local and remote agree";
- try
- {
+ try {
Context context = Curator.curationContext();
String objId = repMan.storageId(context, id, archFmt);
Packer packer = PackerFactory.instance(context, dso);
- //First, make sure this object has an AIP in remote storage
- if(checkReplica(context, repMan, dso))
- {
- // generate an archive and calculate it's checksum
+ // First, make sure this object has an AIP in remote storage
+ if (checkReplica(context, repMan, dso)) {
+ // generate an archive and calculate its checksum
File packDir = repMan.stage(context, storeGroupName, id);
File archive = packer.pack(packDir);
String chkSum = Utils.checksum(archive, "MD5");
@@ -96,33 +92,27 @@ public int perform(DSpaceObject dso) throws IOException
// compare with replica
String repChkSum = repMan.objectAttribute(storeGroupName, objId, "checksum");
- if (! chkSum.equals(repChkSum))
- {
+ if (! chkSum.equals(repChkSum)) {
report("Local and remote checksums differ for: " + id);
report("Local: " + chkSum + " replica: " + repChkSum);
result = "Checksums of local and remote differ for: " + id;
status = Curator.CURATE_FAIL;
- }
- else
- {
+ } else {
report("Local and remote checksums agree for: " + id);
}
+
// if a container, also perform an extent (count) audit - i.e.
// does replica store have replicas for each object in container?
- if (Curator.isContainer(dso) || dso.getType() == Constants.SITE)
- {
+ if (Curator.isContainer(dso) || dso.getType() == Constants.SITE) {
auditExtent(context, repMan, dso);
}
}
+
setResult(result);
return status;
- }
- catch (AuthorizeException authE)
- {
+ } catch (AuthorizeException authE) {
throw new IOException(authE);
- }
- catch (SQLException sqlE)
- {
+ } catch (SQLException sqlE) {
throw new IOException(sqlE);
}
}
@@ -139,37 +129,30 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- private void auditExtent(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException, SQLException
- {
+ private void auditExtent(Context context, ReplicaManager repMan, DSpaceObject dso)
+ throws IOException, SQLException {
int type = dso.getType();
-
- //If container is a Collection, make sure all Items have AIPs in remote storage
- if (Constants.COLLECTION == type)
- {
+
+ // If container is a Collection, make sure all Items have AIPs in remote storage
+ if (Constants.COLLECTION == type) {
Collection coll = (Collection)dso;
Iterator- iter = itemService.findByCollection(context, coll);
- while (iter.hasNext())
- {
+ while (iter.hasNext()) {
checkReplica(context, repMan, iter.next());
}
- } //If Community, make sure all Sub-Communities/Collections have AIPs in remote storage
- else if (Constants.COMMUNITY == type)
- {
+ } else if (Constants.COMMUNITY == type) {
+ // If Community, make sure all Sub-Communities/Collections have AIPs in remote storage
Community comm = (Community)dso;
- for (Community subcomm : comm.getSubcommunities())
- {
+ for (Community subcomm : comm.getSubcommunities()) {
checkReplica(context, repMan, subcomm);
}
- for (Collection coll : comm.getCollections())
- {
+ for (Collection coll : comm.getCollections()) {
checkReplica(context, repMan, coll);
}
- } //if Site, check to see all Top-Level Communities have an AIP in remote storage
- else if (Constants.SITE == type)
- {
+ } else if (Constants.SITE == type) {
+ // If Site, check to see all Top-Level Communities have an AIP in remote storage
List topComm = communityService.findAllTop(context);
- for (Community comm : topComm)
- {
+ for (Community comm : topComm) {
checkReplica(context, repMan, comm);
}
}
@@ -184,19 +167,17 @@ else if (Constants.SITE == type)
* @return true if replica exists, false otherwise
* @throws IOException if I/O error
*/
- private boolean checkReplica(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException
- {
- String objId = repMan.storageId(context, dso.getHandle(), archFmt);
+ private boolean checkReplica(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException {
+ String objId = repMan.storageId(context, dso.getHandle(), archFmt);
- if (! repMan.objectExists(storeGroupName, objId))
- {
- String msg = "Missing replica for: " + dso.getHandle();
- report(msg);
- result = msg;
- status = Curator.CURATE_FAIL;
- return false;
- }
- else
- return true;
+ if (!repMan.objectExists(storeGroupName, objId)) {
+ String msg = "Missing replica for: " + dso.getHandle();
+ report(msg);
+ result = msg;
+ status = Curator.CURATE_FAIL;
+ return false;
+ } else {
+ return true;
+ }
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/EstimateAIPSize.java b/src/main/java/org/dspace/ctask/replicate/EstimateAIPSize.java
index 3292b260..c6bc7c30 100644
--- a/src/main/java/org/dspace/ctask/replicate/EstimateAIPSize.java
+++ b/src/main/java/org/dspace/ctask/replicate/EstimateAIPSize.java
@@ -31,12 +31,10 @@
* @see TransmitAIP
*/
@Distributive
-public class EstimateAIPSize extends AbstractCurationTask
-{
+public class EstimateAIPSize extends AbstractCurationTask {
@Override
public int perform(DSpaceObject dso) throws IOException {
- try
- {
+ try {
Packer packer = PackerFactory.instance(Curator.curationContext(), dso);
// just report the size
long size = packer.size("");
@@ -44,17 +42,15 @@ public int perform(DSpaceObject dso) throws IOException {
") estimated AIP size: " + scaledSize(size, 0);
report(msg);
setResult(scaledSize(size, 0));
- }
- catch (SQLException sqlE)
- {
+ } catch (SQLException sqlE) {
throw new IOException(sqlE);
}
+
return Curator.CURATE_SUCCESS;
}
-
+
String[] prefixes = { "", "kilo", "mega", "giga", "tera", "peta", "exa" };
- private String scaledSize(long size, int idx)
- {
+ private String scaledSize(long size, int idx) {
return (size < 1000L) ? size + " " + prefixes[idx] + "bytes" :
scaledSize(size / 1000L, idx + 1);
}
diff --git a/src/main/java/org/dspace/ctask/replicate/FetchAIP.java b/src/main/java/org/dspace/ctask/replicate/FetchAIP.java
index e7aca5bd..d3133e8c 100644
--- a/src/main/java/org/dspace/ctask/replicate/FetchAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/FetchAIP.java
@@ -25,8 +25,7 @@
* @see TransmitAIP
*/
-public class FetchAIP extends AbstractCurationTask
-{
+public class FetchAIP extends AbstractCurationTask {
private String archFmt;
private String baseFolder;
@@ -49,18 +48,14 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
- if(dso!=null)
- {
+ public int perform(DSpaceObject dso) throws IOException {
+ if (dso != null) {
try {
return perform(Curator.curationContext(), dso.getHandle());
} catch (SQLException e) {
throw new IOException(e);
}
- }
- else
- {
+ } else {
String result = "DSpace Object not found!";
report(result);
setResult(result);
@@ -77,16 +72,19 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
String objId = repMan.storageId(ctx, id, archFmt);
File archive = repMan.fetchObject(ctx, storeGroupName, objId);
+
boolean found = archive != null;
String result = "AIP for object: " + id + " located : " + found + ".";
- if(found)
+
+ if (found) {
result += " AIP file downloaded to '"
+ baseFolder + "/" + storeGroupName + "/" + objId + "'";
+ }
+
report(result);
setResult(result);
return found ? Curator.CURATE_SUCCESS : Curator.CURATE_FAIL;
diff --git a/src/main/java/org/dspace/ctask/replicate/FilteredFileTaskQueue.java b/src/main/java/org/dspace/ctask/replicate/FilteredFileTaskQueue.java
index b0809e66..dad69872 100644
--- a/src/main/java/org/dspace/ctask/replicate/FilteredFileTaskQueue.java
+++ b/src/main/java/org/dspace/ctask/replicate/FilteredFileTaskQueue.java
@@ -33,18 +33,16 @@
* Only the first TWO entries will be returned by "dequeue()", as entries #3
* and #4 would be considered duplicates of entry #1.
*
- * This FilteredFileTaskQueue is extremely useful to Replication Tasks, as it
+ * This FilteredFileTaskQueue is extremely useful to Replication Tasks, as it
* ensures that AIPs are not (re-)generated multiple times when the queue
* is actually processed. (NOTE however that some of the Replication store plugins
* avoid duplicate transfers by ensuring Checksums differ before transferring)
*
* @author Tim Donohue
*/
-public class FilteredFileTaskQueue extends FileTaskQueue
-{
+public class FilteredFileTaskQueue extends FileTaskQueue {
private static Logger log = LogManager.getLogger();
-
/**
* Returns the set of UNIQUE task entries from the named queue. Any duplicate
* task entries in the queue are ignored. The operation locks
@@ -62,12 +60,11 @@ public class FilteredFileTaskQueue extends FileTaskQueue
*/
@Override
public synchronized Set dequeue(String queueName, long ticket)
- throws IOException
- {
- //Dequeue our list of tasks (which may include duplicates)
+ throws IOException {
+ // Dequeue our list of tasks (which may include duplicates)
Set entrySet = super.dequeue(queueName, ticket);
- //Filter out any duplicate entries in the task list
+ // Filter out any duplicate entries in the task list
filterDuplicates(entrySet);
return entrySet;
@@ -78,25 +75,22 @@ public synchronized Set dequeue(String queueName, long ticket)
* A duplicate entry is one that references the same object and the same task(s)
* @param entries initial set of entries
*/
- private void filterDuplicates(Set entries)
- {
- //create filteredSet as a LinkedHashSet in order to maintain existing order of queue
+ private void filterDuplicates(Set entries) {
+ // create filteredSet as a LinkedHashSet in order to maintain existing order of queue
Set filteredSet = new LinkedHashSet();
// Add all our TaskQueueEntries to our "filteredSet".
- // This will filter out any duplicates automatically
+ // This will filter out any duplicates automatically
// (see UniqueTaskQueueEntry.equals() below).
Iterator entryIter = entries.iterator();
- while (entryIter.hasNext())
- {
+ while (entryIter.hasNext()) {
filteredSet.add(new UniqueTaskQueueEntry(entryIter.next()));
}
// Now overwrite our initial entry set with the filtered list of entries
entries.clear();
Iterator filterIter = filteredSet.iterator();
- while (filterIter.hasNext())
- {
+ while (filterIter.hasNext()) {
entries.add(filterIter.next().getTaskQueueEntry());
}
}
@@ -108,19 +102,16 @@ private void filterDuplicates(Set entries)
* TaskQueueEntry (not allowed, as it's "final"), or have a similar
* TaskQueueEntry.equals() method.
*/
- private class UniqueTaskQueueEntry
- {
+ private class UniqueTaskQueueEntry {
private final TaskQueueEntry entry;
private final String tasks;
private final String objId;
- public UniqueTaskQueueEntry(TaskQueueEntry entry)
- {
+ public UniqueTaskQueueEntry(TaskQueueEntry entry) {
this.entry = entry;
List taskNames = entry.getTaskNames();
StringBuilder sb = new StringBuilder();
- for (String tName : taskNames)
- {
+ for (String tName : taskNames) {
sb.append(tName).append(",");
}
this.tasks = sb.substring(0, sb.length() - 1);
@@ -131,12 +122,10 @@ public UniqueTaskQueueEntry(TaskQueueEntry entry)
* Get the TaskQueueEntry object that was used to generate the TaskQueueEntryFilter
* @return TaskQueueEntry object
*/
- public TaskQueueEntry getTaskQueueEntry()
- {
+ public TaskQueueEntry getTaskQueueEntry() {
return entry;
}
-
/**
* Return true if this object equals obj, false otherwise.
*
@@ -144,22 +133,20 @@ public TaskQueueEntry getTaskQueueEntry()
* @return true if TaskQueueEntryFilter objects are equal
*/
@Override
- public boolean equals(Object obj)
- {
- if (obj == null)
- {
+ public boolean equals(Object obj) {
+ if (obj == null) {
return false;
}
- if (getClass() != obj.getClass())
- {
+
+ if (getClass() != obj.getClass()) {
return false;
}
+
final UniqueTaskQueueEntry other = (UniqueTaskQueueEntry) obj;
// two task entries are considered "equal" if they refer to the
// same object and same list of tasks
if (this.tasks.equalsIgnoreCase(other.tasks) &&
- this.objId.equalsIgnoreCase(other.objId))
- {
+ this.objId.equalsIgnoreCase(other.objId)) {
return true;
}
diff --git a/src/main/java/org/dspace/ctask/replicate/METSReplicateConsumer.java b/src/main/java/org/dspace/ctask/replicate/METSReplicateConsumer.java
index 302fb3b0..5ccbf47b 100644
--- a/src/main/java/org/dspace/ctask/replicate/METSReplicateConsumer.java
+++ b/src/main/java/org/dspace/ctask/replicate/METSReplicateConsumer.java
@@ -122,21 +122,26 @@ public class METSReplicateConsumer implements Consumer {
private final String deleteGroupName = configurationService.getProperty("replicate.group.delete.name");
@Override
- public void initialize() throws Exception
- {
- repMan = ReplicaManager.instance();
+ public void initialize() throws Exception {
+ try {
+ repMan = ReplicaManager.instance();
+ } catch (IOException ioE) {
+ // The ReplicaManager attempts to initialize the ObjectStore specified in the configuration.
+ log.error("Unable to initialize the ReplicaManager. ", ioE);
+ }
+
taskQueue = (TaskQueue) pluginService.getSinglePlugin(TaskQueue.class);
queueName = configurationService.getProperty("replicate.consumer.queue");
+
// look for and load any idFilter files - excludes trump includes
// An "idFilter" is an actual textual file named "exclude" or "include"
// which contains a list of handles to filter from the Consumer
- if (! loadIdFilter("exclude"))
- {
- if (loadIdFilter("include"))
- {
+ if (! loadIdFilter("exclude")) {
+ if (loadIdFilter("include")) {
idExclude = false;
}
}
+
taskQMap = new HashMap>();
taskPMap = new HashMap>();
parseTasks("add");
@@ -162,44 +167,39 @@ public void initialize() throws Exception
* @throws Exception if error
*/
@Override
- public void consume(Context ctx, Event event) throws Exception
- {
+ public void consume(Context ctx, Event event) throws Exception {
int evType = event.getEventType();
int subjType = event.getSubjectType();
- //In this situation the "id" is actually the Object Handle
+
+ // In this situation the "id" is actually the Object Handle
String id = null;
//Special processing specific to Group & EPerson events
- if(subjType==Constants.GROUP || subjType==Constants.EPERSON)
- {
+ if (subjType == Constants.GROUP || subjType == Constants.EPERSON) {
// ANY changes to a Group/EPerson are essentially modifications
// to the DSpace System (Site), as they are site-wide changes
Site site = siteService.findSite(ctx);
id = site == null ? null : site.getHandle();
+
// make sure we are supposed to process this object
- if (acceptId(id, event, ctx))
- {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, id);
mapId(taskPMap, modPTasks, id);
}
- }
- else // process all other object types
- {
- switch (evType)
- {
- //ADD = Adding an object to a container or group
+ } else {
+ // process all other object types
+ switch (evType) {
+ // ADD = Adding an object to a container or group
case ADD:
- //If mapping/adding an Item to a Collection
- if(subjType==Constants.COLLECTION)
- {
- //First, get Handle of collection that was modified
+ // If mapping/adding an Item to a Collection
+ if (subjType == Constants.COLLECTION) {
+ // First, get Handle of collection that was modified
id = event.getSubject(ctx).getHandle();
// make sure we are supposed to process this Collection
- if (acceptId(id, event, ctx))
- {
+ if (acceptId(id, event, ctx)) {
// add Collection to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, id);
@@ -214,21 +214,19 @@ public void consume(Context ctx, Event event) throws Exception
mapId(taskPMap, modPTasks, id);
}
}
- //IGNORE all other "ADD" events. Currently it's not possible to map
- //Collections or SubCommunities to multiple parents.
- break;
- case CREATE: //CREATE = Create a new object.
- case INSTALL: //INSTALL = Install an object (exits workflow/workspace). Only used for Items.
+ // IGNORE all other "ADD" events. Currently it's not possible to map
+ // Collections or SubCommunities to multiple parents.
+ break;
+ case CREATE: // CREATE = Create a new object.
+ case INSTALL: // INSTALL = Install an object (exits workflow/workspace). Only used for Items.
// For CREATE & INSTALL, the Handle of object being created is found in Event Detail
id = event.getDetail();
// if NOT (Create & Item)
// (i.e. We don't want to replicate items UNTIL they are Installed)
- if (!(subjType == Constants.ITEM && evType == CREATE))
- {
- if (acceptId(id, event, ctx))
- {
+ if (!(subjType == Constants.ITEM && evType == CREATE)) {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of added/new objects
// for which we need to perform tasks
mapId(taskQMap, addQTasks, id);
@@ -237,14 +235,13 @@ public void consume(Context ctx, Event event) throws Exception
// get parent of this newly created object & mark it as modified
DSpaceObject subject = event.getSubject(ctx);
- DSpaceObject parent = ContentServiceFactory.getInstance().getDSpaceObjectService(subject).getParentObject(ctx, subject);
- if(parent!=null)
- {
+ DSpaceObject parent = ContentServiceFactory.getInstance()
+ .getDSpaceObjectService(subject).getParentObject(ctx, subject);
+
+ if (parent != null) {
id = parent.getHandle();
- if(id != null)
- {
- if (acceptId(id, event, ctx))
- {
+ if (id != null) {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, id);
@@ -254,12 +251,10 @@ public void consume(Context ctx, Event event) throws Exception
}
}
break;
-
- case MODIFY: //MODIFY = modify an object
- case MODIFY_METADATA: //MODIFY_METADATA = just modify an object's metadata
+ case MODIFY: // MODIFY = modify an object
+ case MODIFY_METADATA: // MODIFY_METADATA = just modify an object's metadata
// If subject of event is null, this means the object was likely deleted
- if (event.getSubject(ctx)==null)
- {
+ if (event.getSubject(ctx) == null) {
log.warn(event.getEventTypeAsString() + " event, could not get object for "
+ event.getSubjectTypeAsString() + " id="
+ String.valueOf(event.getSubjectID())
@@ -267,16 +262,14 @@ public void consume(Context ctx, Event event) throws Exception
break;
}
- //For MODIFY events, the Handle of modified object needs to be obtained from the Subject
+ // For MODIFY events, the Handle of modified object needs to be obtained from the Subject
id = event.getSubject(ctx).getHandle();
// make sure handle resolves - these could be events
// for a newly created item that hasn't been assigned a handle
- if (id != null)
- {
+ if (id != null) {
// make sure we are supposed to process this object
- if (acceptId(id, event, ctx))
- {
+ if (acceptId(id, event, ctx)) {
// add it to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, id);
@@ -284,58 +277,51 @@ public void consume(Context ctx, Event event) throws Exception
}
}
break;
-
case REMOVE: //REMOVE = Remove an object from a container or group
case DELETE: //DELETE = Delete an object (actually destroy it)
// For REMOVE & DELETE, the Handle of object being deleted is found in Event Detail
id = event.getDetail();
// make sure we are supposed to process this object
- if (acceptId(id, event, ctx))
- { // analyze & process the deletion/removal event
+ if (acceptId(id, event, ctx)) {
+ // analyze & process the deletion/removal event
deleteEvent(ctx, id, event);
}
-
break;
default:
break;
- }//end switch
- }//end if
+ }
+ }
}
@Override
- public void end(Context ctx) throws Exception
- {
+ public void end(Context ctx) throws Exception {
// if there are any pending objectIds, pass them to the curation
// system to queue for later processing, or perform immediately
EPerson ep = ctx.getCurrentUser();
String name = (ep != null) ? ep.getName() : "unknown";
long stamp = System.currentTimeMillis();
+
// first the queueables
Set entrySet = new HashSet();
- if (taskQMap.size() > 0)
- {
+ if (!taskQMap.isEmpty()) {
List taskList = new ArrayList();
- for (String task : taskQMap.keySet())
- {
+ for (String task : taskQMap.keySet()) {
taskList.add(task);
- for (String id : taskQMap.get(task))
- {
+ for (String id : taskQMap.get(task)) {
entrySet.add(new TaskQueueEntry(name, stamp, taskList, id));
}
taskList.clear();
}
taskQMap.clear();
}
+
// now the performables
- if (taskPMap.size() > 0)
- {
+ if (!taskPMap.isEmpty()) {
Curator curator = new Curator();
- for (String task : taskPMap.keySet())
- {
+ for (String task : taskPMap.keySet()) {
curator.addTask(task);
- for (String id : taskQMap.get(task))
- {
+ for (String id : taskQMap.get(task)) {
curator.curate(ctx, id);
}
curator.clear();
@@ -344,23 +330,20 @@ public void end(Context ctx) throws Exception
}
// if there any uncommitted deletions, record them now
- if (delObjId != null)
- {
- if (delTasks != null)
- {
+ if (delObjId != null) {
+ if (delTasks != null) {
entrySet.add(new TaskQueueEntry(name, stamp, delTasks, delObjId));
}
processDelete(ctx);
}
- if (entrySet.size() > 0)
- {
+
+ if (!entrySet.isEmpty()) {
taskQueue.enqueue(queueName, entrySet);
}
}
@Override
- public void finish(Context ctx) throws Exception
- {
+ public void finish(Context ctx) throws Exception {
// no-op
}
@@ -376,27 +359,25 @@ public void finish(Context ctx) throws Exception
* @return true if this consumer should process this object event, false if it should not
* @throws SQLException if database error occurs
*/
- private boolean acceptId(String id, Event event, Context ctx) throws SQLException
- {
+ private boolean acceptId(String id, Event event, Context ctx) throws SQLException {
// always accept if not filtering
- if (idFilter == null)
- {
+ if (idFilter == null) {
return true;
}
+
// filter supports only container ids - so if id is for an item,
// find its owning collection
String id2check = id;
- if (event.getSubjectType() == Constants.ITEM)
- {
+ if (event.getSubjectType() == Constants.ITEM) {
// NB: Item should be available form context cache - should
// not incur a performance hit here
Item item = itemService.find(ctx, event.getSubjectID());
Collection coll = item.getOwningCollection();
- if (coll != null)
- {
+ if (coll != null) {
id2check = coll.getHandle();
}
}
+
boolean onList = idFilter.contains(id2check);
return idExclude ? ! onList : onList;
}
@@ -410,38 +391,27 @@ private boolean acceptId(String id, Event event, Context ctx) throws SQLExceptio
* @param event event that was triggered
* @throws Exception if error
*/
- private void deleteEvent(Context ctx, String id, Event event) throws Exception
- {
+ private void deleteEvent(Context ctx, String id, Event event) throws Exception {
int type = event.getEventType();
- if (DELETE == type)
- {
+ if (DELETE == type) {
// either marks start of new deletion or a member of enclosing one
- if (delObjId == null)
- {
- //Start of a new deletion
+ if (delObjId == null) {
+ // Start of a new deletion
delObjId = id;
- }
- else
- {
+ } else {
// just add to list of deleted members
delMemIds.add(id);
}
- }
- else if (REMOVE == type)
- {
+ } else if (REMOVE == type) {
// either marks end of current deletion or is member of
// enclosing one: ignore if latter
- if (event.getDetail().equals(id) || (delObjId != null && delObjId.equals(id)))
- {
+ if (event.getDetail().equals(id) || (delObjId != null && delObjId.equals(id))) {
// determine owner and write out deletion catalog
- if (Constants.COLLECTION == event.getSubjectType())
- {
+ if (Constants.COLLECTION == event.getSubjectType()) {
// my owner is a collection
Collection ownColl = collectionService.find(ctx, event.getSubjectID());
delOwnerId = ownColl.getHandle();
- }
- else if (Constants.COMMUNITY == event.getSubjectType())
- {
+ } else if (Constants.COMMUNITY == event.getSubjectType()) {
// my owner is a community
Community comm = communityService.find(ctx, event.getSubjectID());
delOwnerId = comm.getHandle();
@@ -449,10 +419,8 @@ else if (Constants.COMMUNITY == event.getSubjectType())
// If the parent/owner was found, mark that parent as having been modified
// (This ensures that a fresh AIP will be generated for the parent object)
- if(delOwnerId != null)
- {
- if (acceptId(delOwnerId, event, ctx))
- {
+ if (delOwnerId != null) {
+ if (acceptId(delOwnerId, event, ctx)) {
// add parent to the master lists of modified objects
// for which we need to perform tasks
mapId(taskQMap, modQTasks, delOwnerId);
@@ -460,32 +428,33 @@ else if (Constants.COMMUNITY == event.getSubjectType())
}
}
- //Record the deletion catalog for the deleted object (as needed)
+ // Record the deletion catalog for the deleted object (as needed)
processDelete(ctx);
- }
+ }
}
}
/*
* Process a deletion event by recording a deletion catalog if configured
*/
- private void processDelete(Context ctx) throws IOException
- {
+ private void processDelete(Context ctx) throws IOException {
+ if (repMan == null) {
+ log.error("The ReplicaManager failed to initialize earlier. Check the logs above.");
+ return;
+ }
+
// write out deletion catalog if defined
- if (catalogDeletes)
- {
- //First, check if this object has an AIP in storage
+ if (catalogDeletes) {
+ // First, check if this object has an AIP in storage
boolean found = repMan.objectExists(storeGroupName, delObjId);
// If the object has an AIP, then create a deletion catalog
// If there's no AIP, then there's no need for a deletion
// catalog as the object isn't backed up & cannot be restored!
- if(found)
- {
+ if (found) {
//Create a deletion catalog (in BagIt format) of all deleted objects
Packer packer = new CatalogPacker(ctx, delObjId, delOwnerId, delMemIds);
- try
- {
+ try {
// Create a new deletion catalog (with default file extension / format)
// and store it in the deletion group store
String catID = repMan.deletionCatalogId(delObjId, null);
@@ -493,17 +462,14 @@ private void processDelete(Context ctx) throws IOException
File archive = packer.pack(packDir);
// Create a deletion catalog in deletion archive location.
repMan.transferObject(deleteGroupName, archive);
- }
- catch (AuthorizeException authE)
- {
+ } catch (AuthorizeException authE) {
throw new IOException(authE);
- }
- catch (SQLException sqlE)
- {
+ } catch (SQLException sqlE) {
throw new IOException(sqlE);
}
}
}
+
// reset for next events
delObjId = delOwnerId = null;
delMemIds.clear();
@@ -516,41 +482,32 @@ private void processDelete(Context ctx) throws IOException
* @param filterName the name of the textual filter file
* @return true if filter file was loaded successfully, false otherwise
*/
- private boolean loadIdFilter(String filterName)
- {
+ private boolean loadIdFilter(String filterName) {
File filterFile = new File(configurationService.getProperty("replicate.base.dir"), filterName);
- if (filterFile.exists())
- {
+ if (filterFile.exists()) {
idFilter = new ArrayList();
BufferedReader reader = null;
- try
- {
+ try {
reader = new BufferedReader(new FileReader(filterFile));
String id = null;
- while((id = reader.readLine()) != null)
- {
+ while ((id = reader.readLine()) != null) {
idFilter.add(id);
}
return true;
- }
- catch (IOException ioE)
- {
- //log.error("Unable to read filter file '" + filterName + "'");
+ } catch (IOException ioE) {
+ // log.error("Unable to read filter file '" + filterName + "'");
idFilter = null;
- }
- finally
- {
+ } finally {
if (reader != null) {
- try
- {
+ try {
reader.close();
- }
- catch (IOException ioE)
- {
+ } catch (IOException ioE) {
+ // ignore exception
}
}
}
}
+
return false;
}
@@ -563,15 +520,11 @@ private boolean loadIdFilter(String filterName)
* @param tasks Tasks to be performed
* @param id Object for which the tasks should be performed.
*/
- private void mapId(Map> map, List tasks, String id)
- {
- if (tasks != null)
- {
- for (String task : tasks)
- {
+ private void mapId(Map> map, List tasks, String id) {
+ if (tasks != null) {
+ for (String task : tasks) {
Set ids = map.get(task);
- if (ids == null)
- {
+ if (ids == null) {
ids = new HashSet();
map.put(task, ids);
}
@@ -585,76 +538,55 @@ private void mapId(Map> map, List tasks, String id)
* is in the 'replicate.cfg' file.
* @param propName property name
*/
- private void parseTasks(String propName)
- {
+ private void parseTasks(String propName) {
String taskStr = configurationService.getProperty("replicate.consumer.tasks." + propName);
- if (taskStr == null || taskStr.length() == 0)
- {
+ if (taskStr == null || taskStr.isEmpty()) {
return;
}
- for (String task : taskStr.split(","))
- {
+
+ for (String task : taskStr.split(",")) {
task = task.trim();
+
//If the task in question does NOT end in "+p",
// then it should be queued for later processing
- if (! task.endsWith("+p"))
- {
- if ("add".equals(propName))
- {
- if (addQTasks == null)
- {
+ if (!task.endsWith("+p")) {
+ if ("add".equals(propName)) {
+ if (addQTasks == null) {
addQTasks = new ArrayList();
}
addQTasks.add(task);
- }
- else if ("mod".equals(propName))
- {
- if (modQTasks == null)
- {
+ } else if ("mod".equals(propName)) {
+ if (modQTasks == null) {
modQTasks = new ArrayList();
}
modQTasks.add(task);
- }
- else if ("del".equals(propName))
- {
- if (delTasks == null)
- {
+ } else if ("del".equals(propName)) {
+ if (delTasks == null) {
delTasks = new ArrayList();
}
delTasks.add(task);
}
- }
- //Otherwise (if the task ends in "+p"),
- // it should be added to the list of tasks to perform immediately
- else
- {
+ } else {
+ // Otherwise (if the task ends in "+p"),
+ // it should be added to the list of tasks to perform immediately
String sTask = task.substring(0, task.lastIndexOf("+p"));
- if ("add".equals(propName))
- {
- if (addPTasks == null)
- {
+ if ("add".equals(propName)) {
+ if (addPTasks == null) {
addPTasks = new ArrayList();
}
addPTasks.add(sTask);
- }
- else if ("mod".equals(propName))
- {
- if (modPTasks == null)
- {
+ } else if ("mod".equals(propName)) {
+ if (modPTasks == null) {
modPTasks = new ArrayList();
}
addPTasks.add(sTask);
- }
- else if ("del".equals(propName))
- {
+ } else if ("del".equals(propName)) {
// just test for special case of deletion catalogs.
- if ("catalog".equals(sTask))
- {
+ if ("catalog".equals(sTask)) {
catalogDeletes = true;
}
}
}
}
}
-
}
diff --git a/src/main/java/org/dspace/ctask/replicate/METSRestoreFromAIP.java b/src/main/java/org/dspace/ctask/replicate/METSRestoreFromAIP.java
index 0bc7ded8..809e178a 100644
--- a/src/main/java/org/dspace/ctask/replicate/METSRestoreFromAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/METSRestoreFromAIP.java
@@ -32,10 +32,9 @@
*/
@Distributive
@Mutative
-public class METSRestoreFromAIP extends AbstractPackagerTask
-{
+public class METSRestoreFromAIP extends AbstractPackagerTask {
private Logger log = LogManager.getLogger();
-
+
private String archFmt;
// Group where all AIPs are stored
@@ -43,7 +42,7 @@ public class METSRestoreFromAIP extends AbstractPackagerTask
// Group where object deletion catalog/records are stored
private String deleteGroupName;
-
+
// Name of module configuration file specific to METS based AIPs
private final String metsModuleConfig = "replicate-mets";
@@ -54,8 +53,7 @@ public void init(Curator curator, String taskId) throws IOException {
storeGroupName = configurationService.getProperty("replicate.group.aip.name");
deleteGroupName = configurationService.getProperty("replicate.group.delete.name");
}
-
-
+
/**
* Perform the Restore/Replace task.
*
@@ -67,30 +65,28 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
String result = null;
int status = Curator.CURATE_FAIL;
-
+
ReplicaManager repMan = ReplicaManager.instance();
-
- //Look for object in Replica Store
+
+ // Look for object in Replica Store
String objId = repMan.storageId(ctx, id, archFmt);
File archive = repMan.fetchObject(ctx, storeGroupName, objId);
-
- if (archive != null)
- {
- //Load packaging options from replicate-mets.cfg configuration file
+
+ if (archive != null) {
+ // Load packaging options from replicate-mets.cfg configuration file
PackageParameters pkgParams = this.loadPackagerParameters(metsModuleConfig);
-
- //log that this task is starting (as this may be a large task)
+
+ // log that this task is starting (as this may be a large task)
log.info(getStartMsg(id, pkgParams));
-
- //restore/replace object represented by this archive file
- //(based on packaging params, this may also restore/replace all child objects too)
+
+ // restore/replace object represented by this archive file
+ // (based on packaging params, this may also restore/replace all child objects too)
restoreObject(ctx, repMan, archive, pkgParams);
- //Check if a deletion catalog exists for this object
+ // Check if a deletion catalog exists for this object
String catId = repMan.deletionCatalogId(id, archFmt);
File catArchive = repMan.fetchObject(ctx, deleteGroupName, catId);
if (catArchive != null) {
@@ -99,44 +95,36 @@ public int perform(Context ctx, String id) throws IOException
// remove from local cache as well
catArchive.delete();
}
-
+
result = getSuccessMsg(id, pkgParams);
status = Curator.CURATE_SUCCESS;
- }
- else
- {
+ } else {
result = "Failed to update Object '" + id + "'. AIP could not be found in Replica Store.";
}
-
+
report(result);
setResult(result);
return status;
}
-
-
-
+
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
int status = Curator.CURATE_FAIL;
- try
- {
- //Get Context from current curation thread
+ try {
+ // Get Context from current curation thread
Context ctx = Curator.curationContext();
status = perform(ctx, dso.getHandle());
- //Note: context will be committed/closed by Curator
- }
- catch(SQLException sqle)
- {
- throw new IOException(sqle);
+ // Note: context will be committed/closed by Curator
+ } catch (SQLException sqlE) {
+ throw new IOException(sqlE);
}
+
return status;
}
-
-
+
/**
* Restores/Replaces a DSpace Object (along with possibly its child objects),
- * based on an archive file in the Replica Filestore and the given
+ * based on an archive file in the Replica Filestore and the given
* PackageParameters.
*
* @param context the context to use
@@ -146,121 +134,109 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
*/
private void restoreObject(Context context, ReplicaManager repMan, File archive, PackageParameters pkgParams)
- throws IOException
- {
- //Initialize a new METS-based packer, without an associated object
+ throws IOException {
+ // Initialize a new METS-based packer, without an associated object
METSPacker packer = new METSPacker(context, archFmt);
-
- try
- {
- //unpack archival package & actually run the restore/replace,
+
+ try {
+ // unpack archival package & actually run the restore/replace,
// based on the current PackageParameters
// This only restores/replaces a single object.
packer.unpack(archive, pkgParams);
// Remove the locally cached archive file - it is no longer needed.
- if(archive.exists())
+ if (archive.exists()) {
archive.delete();
+ }
- //check if recursiveMode is enabled (restore/replace multiple objects)
- if(pkgParams.recursiveModeEnabled())
- {
- //See if this package refered to child packages,
- //if so, we want to also replace those child objects
+ // check if recursiveMode is enabled (restore/replace multiple objects)
+ if (pkgParams.recursiveModeEnabled()) {
+ // See if this package refered to child packages,
+ // if so, we want to also replace those child objects
List childPkgRefs = packer.getChildPackageRefs();
- if(childPkgRefs!=null && !childPkgRefs.isEmpty())
- {
- for(String childRef : childPkgRefs)
- {
+ if (childPkgRefs != null && !childPkgRefs.isEmpty()) {
+ for (String childRef : childPkgRefs) {
File childArchive = repMan.fetchObject(context, storeGroupName, childRef);
- if(childArchive!=null)
- {
- //recurse to restore/replace this child object (and all its children)
+ if (childArchive != null) {
+ // recurse to restore/replace this child object (and all its children)
restoreObject(context, repMan, childArchive, pkgParams);
- }
- else
- {
+ } else {
throw new IOException("Archive " + childRef + " was not found in Replica Store");
}
- }
+ }
}
}
+ } catch (AuthorizeException authE) {
+ throw new IOException(authE);
+ } catch (SQLException sqlE) {
+ throw new IOException(sqlE);
}
- catch(AuthorizeException authe)
- {
- throw new IOException(authe);
- }
- catch(SQLException sqle)
- {
- throw new IOException(sqle);
- }
- }
-
-
+ }
+
/**
- * Return a human-friendly 'start processing' message based on the
+ * Return a human-friendly 'start processing' message based on the
* actions performed (determined via PackageParameters).
*
* @param objId Object ID
* @param pkgParams PackageParameters (used to determine actions)
* @return human-friendly start message
*/
- private String getStartMsg(String objId, PackageParameters pkgParams)
- {
+ private String getStartMsg(String objId, PackageParameters pkgParams) {
String resultMsg = "Beginning ";
-
- //add action
- if(pkgParams.replaceModeEnabled())
+
+ // add action
+ if (pkgParams.replaceModeEnabled()) {
resultMsg += "replacement of ";
- else if (pkgParams.keepExistingModeEnabled())
+ } else if (pkgParams.keepExistingModeEnabled()) {
resultMsg += "restoration (keep-existing mode) of ";
- else
+ } else {
resultMsg += "restoration of ";
-
- //add object info
- resultMsg += "Object '" + objId +"' ";
-
- //is it recursive?
- if(pkgParams.recursiveModeEnabled())
+ }
+
+ // add object info
+ resultMsg += "Object '" + objId + "' ";
+
+ // is it recursive?
+ if (pkgParams.recursiveModeEnabled()) {
resultMsg += "(and all child objects) ";
-
- //complete message;
+ }
+
+ // complete message;
resultMsg += "from AIP.";
return resultMsg;
-
}
-
+
/**
- * Return a human-friendly success message based on the
+ * Return a human-friendly success message based on the
* actions performed (determined via PackageParameters).
*
* @param objId Object ID
* @param pkgParams PackageParameters (used to determine actions)
* @return human-friendly result message
*/
- private String getSuccessMsg(String objId, PackageParameters pkgParams)
- {
+ private String getSuccessMsg(String objId, PackageParameters pkgParams) {
String resultMsg = "Successfully ";
-
- //add action
- if(pkgParams.replaceModeEnabled())
+
+ // add action
+ if (pkgParams.replaceModeEnabled()) {
resultMsg += "replaced ";
- else if (pkgParams.keepExistingModeEnabled())
+ } else if (pkgParams.keepExistingModeEnabled()) {
resultMsg += "restored (keep-existing mode) ";
- else
+ } else {
resultMsg += "restored ";
-
- //add object info
- resultMsg += "Object '" + objId +"' ";
-
- //is it recursive?
- if(pkgParams.recursiveModeEnabled())
+ }
+
+ // add object info
+ resultMsg += "Object '" + objId + "' ";
+
+ // is it recursive?
+ if (pkgParams.recursiveModeEnabled()) {
resultMsg += "(and all child objects) ";
-
- //complete message;
+ }
+
+ // complete message;
resultMsg += "from AIP.";
return resultMsg;
}
-
}
diff --git a/src/main/java/org/dspace/ctask/replicate/MoveToTrashSingleAIP.java b/src/main/java/org/dspace/ctask/replicate/MoveToTrashSingleAIP.java
index 231c8b05..13f6ffd7 100644
--- a/src/main/java/org/dspace/ctask/replicate/MoveToTrashSingleAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/MoveToTrashSingleAIP.java
@@ -36,8 +36,7 @@
* @author tdonohue
*/
@Distributive
-public class MoveToTrashSingleAIP extends AbstractCurationTask
-{
+public class MoveToTrashSingleAIP extends AbstractCurationTask {
// Source and destination group where AIP will be moved to
private String srcGroupName;
private String destGroupName;
@@ -63,18 +62,14 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
- if(dso!=null)
- {
+ public int perform(DSpaceObject dso) throws IOException {
+ if (dso != null) {
try {
return perform(Curator.curationContext(), dso.getHandle());
} catch (SQLException e) {
throw new IOException(e);
}
- }
- else
- {
+ } else {
String result = "DSpace Object not specified!";
report(result);
setResult(result);
@@ -92,16 +87,19 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
String objId = repMan.storageId(ctx, id, archFmt);
boolean success = repMan.moveObject(srcGroupName, destGroupName, objId);
- String result = "AIP for object: " + id + " could NOT be moved from: " + srcGroupName + " to : " + destGroupName + ".";
- if(success)
+ String result = "AIP for object: " + id + " could NOT be moved from: " + srcGroupName + " to : "
+ + destGroupName + ".";
+
+ if (success) {
result = "AIP for object: " + id + " moved from: " + srcGroupName + " to : " + destGroupName + ".";
+ }
+
report(result);
setResult(result);
diff --git a/src/main/java/org/dspace/ctask/replicate/ObjectStore.java b/src/main/java/org/dspace/ctask/replicate/ObjectStore.java
index 98ebde64..a53d321b 100644
--- a/src/main/java/org/dspace/ctask/replicate/ObjectStore.java
+++ b/src/main/java/org/dspace/ctask/replicate/ObjectStore.java
@@ -56,7 +56,6 @@ public interface ObjectStore {
* @throws IOException if I/O error
*/
long fetchObject(String group, String id, File file) throws IOException;
-
/**
* Transfers a copy of this file to the object store
@@ -78,7 +77,7 @@ public interface ObjectStore {
* @throws IOException if I/O error
*/
long removeObject(String group, String id) throws IOException;
-
+
/**
* Moves the passed object from one storage group to another.
*
diff --git a/src/main/java/org/dspace/ctask/replicate/Odometer.java b/src/main/java/org/dspace/ctask/replicate/Odometer.java
index 6eb20e9b..d3e1ec0a 100644
--- a/src/main/java/org/dspace/ctask/replicate/Odometer.java
+++ b/src/main/java/org/dspace/ctask/replicate/Odometer.java
@@ -21,7 +21,7 @@
* usage. This can assist the consumer of the service to monitor it's cost,
* inter alia.
*
- * The Odometer tracks basic statistics of replication activities: bytes uploaded,
+ * The Odometer tracks basic statistics of replication activities: bytes uploaded,
* modified, count of objects, and external objectstore size.
*
* See org.dspace.ctask.replicate.ReplicaManager for how the Odometer readings
@@ -30,8 +30,7 @@
* @author richardrodgers
* @see org.dspace.ctask.replicate.ReplicaManager
*/
-public class Odometer
-{
+public class Odometer {
// name of file
private static final String ODO_NAME = "odometer";
// names of fixed properties
@@ -47,75 +46,56 @@ public class Odometer
// directory path
private String dirPath = null;
- Odometer(String dirPath, boolean readOnly) throws IOException
- {
+ Odometer(String dirPath, boolean readOnly) throws IOException {
this.readOnly = readOnly;
this.dirPath = dirPath;
odoProps = new Properties();
- try
- {
+ try {
File odoFile = new File(dirPath, ODO_NAME);
- if (odoFile.exists())
- {
-
+ if (odoFile.exists()) {
InputStream in = null;
- try
- {
+ try {
in = new FileInputStream(odoFile);
odoProps.load(new FileInputStream(odoFile));
- }
- finally
- {
- if (in != null)
- {
+ } finally {
+ if (in != null) {
in.close();
}
}
}
- }
- catch (FileNotFoundException fnfE)
- {
+ } catch (FileNotFoundException fnfE) {
throw new IOException(fnfE);
}
}
- void save() throws IOException
- {
- if (! readOnly)
- {
+ void save() throws IOException {
+ if (!readOnly) {
odoProps.setProperty("modified", String.valueOf(System.currentTimeMillis()));
File odoFile = new File(dirPath, ODO_NAME);
OutputStream out = null;
- try
- {
+ try {
out = new FileOutputStream(odoFile);
odoProps.store(out, null);
- }
- finally
- {
- if (out != null)
- {
+ } finally {
+ if (out != null) {
out.close();
}
}
}
}
- void adjustProperty(String name, long adjustment)
- {
+ void adjustProperty(String name, long adjustment) {
long val = getProperty(name);
setProperty(name, val + adjustment);
}
- void setProperty(String name, long value)
- {
+ void setProperty(String name, long value) {
odoProps.setProperty(name, String.valueOf(value));
}
-
- public long getProperty(String name)
- {
- String val = odoProps.getProperty(name);
- long lval = val != null ? Long.valueOf(val) : 0L;
- return lval;
+
+ public long getProperty(String name) {
+ String val = odoProps.getProperty(name);
+ long lval = val != null ? Long.valueOf(val) : 0L;
+ return lval;
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/ReadOdometer.java b/src/main/java/org/dspace/ctask/replicate/ReadOdometer.java
index 7c299a99..933fd2d3 100644
--- a/src/main/java/org/dspace/ctask/replicate/ReadOdometer.java
+++ b/src/main/java/org/dspace/ctask/replicate/ReadOdometer.java
@@ -16,7 +16,7 @@
/**
* ReadOdometer simply reads and displays the odometer data. Since this data
- * is currently only maintained per site, the actual data object is ignored.
+ * is currently only maintained per site, the actual data object is ignored.
*
* Odometer data is stored in base folder for the Replication Task Suite
* (see 'base.dir' setting in 'replicate.cfg'). It is stored in a text file
@@ -26,8 +26,7 @@
* @see Odometer
*/
@Distributive
-public class ReadOdometer extends AbstractCurationTask
-{
+public class ReadOdometer extends AbstractCurationTask {
/**
* Performs the "Read Odometer" task.
* @param dso this param is ignored, as the odometer is sitewide
@@ -35,8 +34,7 @@ public class ReadOdometer extends AbstractCurationTask
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
Odometer odometer = repMan.getOdometer();
StringBuilder sb = new StringBuilder();
@@ -44,15 +42,14 @@ public int perform(DSpaceObject dso) throws IOException
sb.append("Size: ").append(scaledSize(odometer.getProperty("storesize"), 0)).append(", \n");
sb.append("Uploaded: ").append(scaledSize(odometer.getProperty("uploaded"), 0)).append(", \n");
sb.append("Downloaded: ").append(scaledSize(odometer.getProperty("downloaded"), 0)).append("\n");
- String msg = sb.toString();
+ String msg = sb.toString();
report(msg);
setResult(msg);
return Curator.CURATE_SUCCESS;
}
-
+
String[] prefixes = { "", "kilo", "mega", "giga", "tera", "peta", "exa" };
- private String scaledSize(long size, int idx)
- {
+ private String scaledSize(long size, int idx) {
return (size < 1000L) ? size + " " + prefixes[idx] + "bytes" :
scaledSize(size / 1000L, idx + 1);
}
diff --git a/src/main/java/org/dspace/ctask/replicate/RemoveAIP.java b/src/main/java/org/dspace/ctask/replicate/RemoveAIP.java
index 0b9cec69..988b8b34 100644
--- a/src/main/java/org/dspace/ctask/replicate/RemoveAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/RemoveAIP.java
@@ -37,12 +37,11 @@
*/
@Distributive
public class RemoveAIP extends AbstractCurationTask {
-
private String archFmt;
// Group where all AIPs are stored
private String storeGroupName;
-
+
// Group where object deletion catalog/records are stored
private String deleteGroupName;
@@ -68,8 +67,7 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
try {
remove(Curator.curationContext(), repMan, dso);
@@ -90,22 +88,21 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- private void remove(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException, SQLException
- {
- //Remove object from AIP storage
+ private void remove(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException, SQLException {
+ // Remove object from AIP storage
String objId = repMan.storageId(context, dso.getHandle(), archFmt);
repMan.removeObject(storeGroupName, objId);
report("Removing AIP for: " + objId);
- //If it is a Collection, also remove all Items from AIP storage
+ // If it is a Collection, also remove all Items from AIP storage
if (dso instanceof Collection) {
Collection coll = (Collection) dso;
Iterator- iter = itemService.findByCollection(context, coll);
while (iter.hasNext()) {
remove(context, repMan, iter.next());
}
- } // else if it a Community, also remove all sub-communities, collections (and items) from AIP storage
- else if (dso instanceof Community) {
+ } else if (dso instanceof Community) {
+ // else if it's a Community, also remove all sub-communities, collections (and items) from AIP storage
Community comm = (Community) dso;
for (Community subcomm : comm.getSubcommunities()) {
remove(context, repMan, subcomm);
@@ -113,8 +110,8 @@ else if (dso instanceof Community) {
for (Collection coll : comm.getCollections()) {
remove(context, repMan, coll);
}
- } //else if it is a Site object, remove all top-level communities (and everything else) from AIP storage
- else if (dso instanceof Site) {
+ } else if (dso instanceof Site) {
+ // else if it's a Site object, remove all top-level communities (and everything else) from AIP storage
List topCommunities = communityService.findAllTop(context);
for (Community subcomm : topCommunities) {
@@ -137,11 +134,10 @@ else if (dso instanceof Site) {
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
-
- //If the object is still in DSpace, call perform(dso) instead.
+
+ // If the object is still in DSpace, call perform(dso) instead.
DSpaceObject dso = dereference(ctx, id);
if (dso != null) {
return perform(dso);
@@ -158,17 +154,19 @@ public int perform(Context ctx, String id) throws IOException
if (catFile != null) {
CatalogPacker cpack = new CatalogPacker(ctx, id);
cpack.unpack(catFile);
+
// remove the object AIP itself
String objId = repMan.storageId(ctx, id, archFmt);
repMan.removeObject(storeGroupName, objId);
report("Removing AIP for: " + objId);
+
// remove all member/child object's AIPs
for (String mem : cpack.getMembers()) {
String memId = repMan.storageId(ctx, mem, archFmt);
repMan.removeObject(storeGroupName, memId);
report("Removing AIP for: " + memId);
}
-
+
// remove local deletion catalog
catFile.delete();
// remove remote deletion catalog
@@ -176,10 +174,9 @@ public int perform(Context ctx, String id) throws IOException
result = "AIP for '" + id + "' has been removed (along with any child object AIPs)";
status = Curator.CURATE_SUCCESS;
- }
- else
- {
- result = "Deletion record for '" + id + "' could not be found in Replica Store. Perhaps this object's AIP was already removed?";
+ } else {
+ result = "Deletion record for '" + id + "' could not be found in Replica Store. Perhaps " +
+ "this object's AIP was already removed?";
}
setResult(result);
diff --git a/src/main/java/org/dspace/ctask/replicate/ReplicaManager.java b/src/main/java/org/dspace/ctask/replicate/ReplicaManager.java
index e7ae72b8..604b5845 100644
--- a/src/main/java/org/dspace/ctask/replicate/ReplicaManager.java
+++ b/src/main/java/org/dspace/ctask/replicate/ReplicaManager.java
@@ -36,7 +36,6 @@
* @author richardrodgers
*/
public class ReplicaManager {
-
private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
private PluginService pluginService = CoreServiceFactory.getInstance().getPluginService();
private HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
@@ -64,54 +63,45 @@ public class ReplicaManager {
private final String archFmt = configurationService.getProperty("replicate.packer.archfmt");
- private ReplicaManager() throws IOException
- {
+ private ReplicaManager() throws IOException {
objStore = (ObjectStore) pluginService.getSinglePlugin(ObjectStore.class);
if (objStore == null) {
log.error("No ObjectStore configured in 'replicate.cfg'!");
throw new IOException("No ObjectStore configured in 'replicate.cfg'!");
}
-
+
objStore.init();
-
+
// create directory structures
new File(repDir).mkdirs();
// load our odometer - writeable copy
- try
- {
+ try {
odometer = new Odometer(repDir, false);
- }
- catch (IOException ioE)
- {
- //just log a warning
- log.warn("Unable to read odometer file in '"+ repDir + "'", ioE);
+ } catch (IOException ioE) {
+ // just log a warning
+ log.warn("Unable to read odometer file in '" + repDir + "'", ioE);
}
}
- public static synchronized ReplicaManager instance() throws IOException
- {
- if (instance == null)
- {
+ public static synchronized ReplicaManager instance() throws IOException {
+ if (instance == null) {
instance = new ReplicaManager();
}
return instance;
}
-
- public File stage(Context context, String group, String id)
- {
+
+ public File stage(Context context, String group, String id) {
// ensure path exists
File stageDir = new File(repDir + File.separator + group);
- if (! stageDir.isDirectory())
- {
+ if (!stageDir.isDirectory()) {
stageDir.mkdirs();
}
return new File(stageDir, storageId(context, id, null));
}
-
-
+
/**
- * Determine the Identifier of an object once it is placed
- * in storage. This method ensures any special characters are
+ * Determine the Identifier of an object once it is placed
+ * in storage. This method ensures any special characters are
* escaped. It also ensures all objects are named in a similar
* manner once they are in a given store (so that they can similarly
* be retrieved from storage using this same 'storageId').
@@ -121,84 +111,81 @@ public File stage(Context context, String group, String id)
* @param fileExtension - file extension, if any (may be null)
* @return reformatted storage ID for this object (including file extension)
*/
- public String storageId(Context context, String objId, String fileExtension)
- {
+ public String storageId(Context context, String objId, String fileExtension) {
// canonical handle notation bedevils file system semantics
String storageId = objId.replaceAll("/", "-");
-
+
// add appropriate file extension, if needed
- if(fileExtension!=null && !storageId.endsWith("." + fileExtension))
+ if (fileExtension != null && !storageId.endsWith("." + fileExtension)) {
storageId = storageId + "." + fileExtension;
+ }
- // If 'packer.typeprefix' setting is 'true',
+ // If 'packer.typeprefix' setting is 'true',
// then prefix the storageID with the DSpace Type (if it doesn't already have a prefix)
- if(configurationService.getBooleanProperty("replicate.packer.typeprefix", true) &&
- !storageId.contains(typePrefixSeparator))
- {
+ if (configurationService.getBooleanProperty("replicate.packer.typeprefix", true) &&
+ !storageId.contains(typePrefixSeparator)) {
String typePrefix = null;
-
- try
- {
- //Get object associated with this handle
+
+ try {
+ // Get object associated with this handle
DSpaceObject dso = handleService.resolveToObject(context, objId);
- //typePrefix format = 'TYPE@'
- if(dso!=null)
+ // typePrefix format = 'TYPE@'
+ if (dso != null) {
typePrefix = Constants.typeText[dso.getType()] + typePrefixSeparator;
+ }
+ } catch (SQLException sqle) {
+ // do nothing, just ignore -- we'll handle this in a moment
}
- catch(SQLException sqle)
- {
- //do nothing, just ignore -- we'll handle this in a moment
- }
-
+
// If we were unable to determine a type prefix, then this must mean the object
// no longer exists in DSpace! Let's see if we can find it in storage!
- if(typePrefix==null)
- {
- try
- {
- //Currently we need to try and lookup the object in storage
- //Hopefully, there will be an easier way to do this in the future
-
- //see if this object exists in main storage group
+ if (typePrefix == null) {
+ try {
+ // Currently we need to try and lookup the object in storage
+ // Hopefully, there will be an easier way to do this in the future
+
+ // see if this object exists in main storage group
typePrefix = findTypePrefix(storeGroupName, storageId);
- if(typePrefix==null && deleteGroupName!=null) //if not found, check deletion group as well
+
+ // if not found, check deletion group as well
+ if (typePrefix == null && deleteGroupName != null) {
typePrefix = findTypePrefix(deleteGroupName, storageId);
+ }
+ } catch (IOException ioE) {
+ // do nothing, just ignore
}
- catch(IOException io)
- {
- //do nothing, just ignore
- }
- }
-
- //if we found a typePrefix, prepend it on storageId
- if(typePrefix!=null)
+ }
+
+ // if we found a typePrefix, prepend it on storageId
+ if (typePrefix != null) {
storageId = typePrefix + storageId;
+ }
}
-
-
+
// Return final storage ID
return storageId;
}
-
+
/**
* Convert a Storage ID back into a Canonical Identifier
* (opposite of 'storageId()' method).
* @param storageId the given object's storage ID
* @return the objects canonical identifier
*/
- public String canonicalId(String storageId)
- {
- //If this 'storageId' includes a TYPE prefix (see 'storageId()' method),
+ public String canonicalId(String storageId) {
+ // If this 'storageId' includes a TYPE prefix (see 'storageId()' method),
// then remove it, before returning the reformatted ID.
- if(storageId.contains(typePrefixSeparator))
- storageId = storageId.substring(storageId.indexOf(typePrefixSeparator)+1);
-
- //If this 'storageId' includes a file extension suffix, also remove it.
- if(storageId.contains("."))
+ if (storageId.contains(typePrefixSeparator)) {
+ storageId = storageId.substring(storageId.indexOf(typePrefixSeparator) + 1);
+ }
+
+ // If this 'storageId' includes a file extension suffix, also remove it.
+ if (storageId.contains(".")) {
storageId = storageId.substring(0, storageId.indexOf("."));
-
- //Finally revert all dashes back to slashes (to create the original canonical ID)
+ }
+
+ // Finally revert all dashes back to slashes (to create the original canonical ID)
return storageId.replaceAll("-", "/");
}
@@ -213,53 +200,46 @@ public String canonicalId(String storageId)
* @param fileExtension - file extension, if any (may be null)
* @return reformatted storage ID for this object (including file extension)
*/
- public String deletionCatalogId(String objId, String fileExtension)
- {
+ public String deletionCatalogId(String objId, String fileExtension) {
// canonical handle notation bedevils file system semantics
String storageId = objId.replaceAll("/", "-");
// add appropriate file extension, if needed
- if(fileExtension!=null && !storageId.endsWith("." + fileExtension))
+ if (fileExtension != null && !storageId.endsWith("." + fileExtension)) {
storageId = storageId + "." + fileExtension;
+ }
- if(configurationService.getBooleanProperty("replicate.packer.typeprefix", true) &&
- !storageId.contains(typePrefixSeparator))
- {
- //Prepend the "deletion catalog" type prefix on the name
+ if (configurationService.getBooleanProperty("replicate.packer.typeprefix", true) &&
+ !storageId.contains(typePrefixSeparator)) {
+ // Prepend the "deletion catalog" type prefix on the name
return deletionCatalogPrefix + typePrefixSeparator + storageId;
- }
- else
- {
+ } else {
// Otherwise, just return the cleaned up ID
return storageId;
}
}
- public Odometer getOdometer() throws IOException
- {
+ public Odometer getOdometer() throws IOException {
// return a new read-only copy
return new Odometer(repDir, true);
}
// Replica store-backed methods
- public File fetchObject(Context context, String group, String objId) throws IOException
- {
- //String repId = safeId(id) + "." + arFmt;
+ public File fetchObject(Context context, String group, String objId) throws IOException {
+ // String repId = safeId(id) + "." + arFmt;
File file = stage(context, group, objId);
long size = objStore.fetchObject(group, objId, file);
- if (size > 0L)
- {
- synchronized (odoLock)
- {
+ if (size > 0L) {
+ synchronized (odoLock) {
odometer.adjustProperty(DOWNLOADED, size);
odometer.save();
}
}
-
+
return file.exists() ? file : null;
}
-
+
public void transferObject(String group, File file) throws IOException {
String psStr = objStore.objectAttribute(group, file.getName(), "sizebytes");
long prevSize = psStr != null ? Long.valueOf(psStr) : 0L;
@@ -274,9 +254,9 @@ public void transferObject(String group, File file) throws IOException {
}
odometer.save();
}
- }
+ }
}
-
+
public boolean objectExists(String group, String objId) throws IOException {
return objStore.objectExists(group, objId);
}
@@ -295,18 +275,19 @@ public void removeObject(String group, String objId) throws IOException {
}
}
}
-
+
public boolean moveObject(String srcGroup, String destGroup, String objId) throws IOException {
long size = objStore.moveObject(srcGroup, destGroup, objId);
-
- // NOTE: no need to adjust the odometer. In this case we haven't
- // actually uploaded or downloaded any content.
- if (size > 0L)
+
+ // NOTE: no need to adjust the odometer. In this case we haven't
+ // actually uploaded or downloaded any content.
+ if (size > 0L) {
return true;
- else
+ } else {
return false;
+ }
}
-
+
/**
* This method is only called if we cannot determine an object's type prefix
* via DSpace (i.e. the object no longer exists in DSpace). In this case,
@@ -317,46 +298,44 @@ public boolean moveObject(String srcGroup, String destGroup, String objId) throw
* @param baseId base object id we are looking for (without type prefix)
* @return Type prefix if a matching object is located successfully. Null otherwise.
*/
- private String findTypePrefix(String group, String baseId) throws IOException
- {
+ private String findTypePrefix(String group, String baseId) throws IOException {
boolean exists = false;
-
+
// This next part may look a bit like a hack, but it's actually safer than
// it seems. Essentially, we are going to try to "guess" what the Type Prefix
// may be, and see if we can find an object with that name in our object Store.
// The reason this is still "safe" is that the "objId" should be unique with or without
- // the Type prefix. Even if it wasn't unique, DSpace HandleManager has checks in place
- // to ensure we can never restore an object of a different Type to a Handle that was
+ // the Type prefix. Even if it wasn't unique, DSpace HandleManager has checks in place
+ // to ensure we can never restore an object of a different Type to a Handle that was
// used previously (e.g. cannot restore an Item with a handle that was previously used by a Collection)
-
+
// NOTE: If DSpace ever provided a way to lookup Object type for an unbound handle, then
// we may no longer need to guess which type this object may have been.
// ALTERNATIVELY: If DuraCloud & other stores provide a way to search by file properties, we could change
// our store plugins to always save the object handle as a property & retrieve files via that property.
- //Most objects are Items, so lets see if this object can be found with an Item Type prefix
+ // Most objects are Items, so lets see if this object can be found with an Item Type prefix
String typePrefix = Constants.typeText[Constants.ITEM] + typePrefixSeparator;
exists = objStore.objectExists(group, typePrefix + baseId);
- if(!exists)
- {
- //Ok, our second guess will be that this used to be a Collection
+ if (!exists) {
+ // Ok, our second guess will be that this used to be a Collection
typePrefix = Constants.typeText[Constants.COLLECTION] + typePrefixSeparator;
exists = objStore.objectExists(group, typePrefix + baseId);
}
- if(!exists)
- {
- //Final guess: maybe this used to be a Community?
+ if (!exists) {
+ // Final guess: maybe this used to be a Community?
typePrefix = Constants.typeText[Constants.COMMUNITY] + typePrefixSeparator;
exists = objStore.objectExists(group, typePrefix + baseId);
- }
-
- // That's it. We're done guessing. If we still couldn't find this object,
+ }
+
+ // That's it. We're done guessing. If we still couldn't find this object,
// it obviously doesn't exist in our object Store.
- if(exists)
+ if (exists) {
return typePrefix;
- else
+ } else {
return null;
+ }
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/TransmitAIP.java b/src/main/java/org/dspace/ctask/replicate/TransmitAIP.java
index eddc8ff4..4ace89d8 100644
--- a/src/main/java/org/dspace/ctask/replicate/TransmitAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/TransmitAIP.java
@@ -30,7 +30,7 @@
*
* This task is "suspendable" when invoked from the UI. If a single AIP fails
* to be generated and transmitted to storage, we should inform the user ASAP.
- * We wouldn't want them to assume everything was transferred successfully,
+ * We wouldn't want them to assume everything was transferred successfully,
* if there were actually underlying errors.
*
* Note that this task has a companion task called TransmitSingleAIP which
@@ -40,9 +40,8 @@
* @see PackerFactory
* @see TransmitSingleAIP
*/
-@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
-public class TransmitAIP extends AbstractCurationTask
-{
+@Suspendable(invoked = Curator.Invoked.INTERACTIVE)
+public class TransmitAIP extends AbstractCurationTask {
// Group where all AIPs will be stored
private String storeGroupName;
@@ -52,7 +51,6 @@ public void init(Curator curator, String taskId) throws IOException {
storeGroupName = configurationService.getProperty("replicate.group.aip.name");
}
-
/**
* Perform 'Transmit AIP' task
*
@@ -62,22 +60,19 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
-
- try
- {
+
+ try {
Context context = Curator.curationContext();
Packer packer = PackerFactory.instance(context, dso);
File archive = packer.pack(repMan.stage(context, storeGroupName, dso.getHandle()));
- String msg = "Created AIP: '" + archive.getName() +
+ String msg = "Created AIP: '" + archive.getName() +
"' size: " + archive.length();
repMan.transferObject(storeGroupName, archive);
setResult(msg);
return Curator.CURATE_SUCCESS;
- }
- catch (AuthorizeException | SQLException e) {
+ } catch (AuthorizeException | SQLException e) {
throw new IOException(e);
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/TransmitSingleAIP.java b/src/main/java/org/dspace/ctask/replicate/TransmitSingleAIP.java
index 9849f187..8938583a 100644
--- a/src/main/java/org/dspace/ctask/replicate/TransmitSingleAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/TransmitSingleAIP.java
@@ -18,7 +18,7 @@
* inhibits container iteration (distribution to members) when invoked upon
* a container object.
*
- * This task is primarily for usage via the ReplicateConsumer, as it needs to
+ * This task is primarily for usage via the ReplicateConsumer, as it needs to
* interact with a single object at a time.
*
* The type of AIP produced is based on the 'packer.pkgtype' setting
diff --git a/src/main/java/org/dspace/ctask/replicate/VerifyAIP.java b/src/main/java/org/dspace/ctask/replicate/VerifyAIP.java
index 71799314..84d25cf5 100644
--- a/src/main/java/org/dspace/ctask/replicate/VerifyAIP.java
+++ b/src/main/java/org/dspace/ctask/replicate/VerifyAIP.java
@@ -30,16 +30,15 @@
* @author richardrodgers
* @see TransmitAIP
*/
-@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
-public class VerifyAIP extends AbstractCurationTask
-{
+@Suspendable(invoked = Curator.Invoked.INTERACTIVE)
+public class VerifyAIP extends AbstractCurationTask {
private String archFmt;
// Group where all AIPs are stored
private String storeGroupName;
@Override
- public void init(Curator curator, String taskId) throws IOException{
+ public void init(Curator curator, String taskId) throws IOException {
super.init(curator, taskId);
archFmt = configurationService.getProperty("replicate.packer.archfmt");
storeGroupName = configurationService.getProperty("replicate.group.aip.name");
@@ -54,17 +53,14 @@ public void init(Curator curator, String taskId) throws IOException{
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
- if(dso!=null) {
+ public int perform(DSpaceObject dso) throws IOException {
+ if (dso != null) {
try {
return perform(Curator.curationContext(), dso.getHandle());
} catch (SQLException e) {
throw new IOException(e);
}
- }
- else
- {
+ } else {
String result = "DSpace Object not found!";
report(result);
setResult(result);
@@ -82,12 +78,12 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
String objId = repMan.storageId(ctx, id, archFmt);
boolean found = repMan.objectExists(storeGroupName, objId);
+
String result = "AIP for object: " + id + " found: " + found;
report(result);
setResult(result);
diff --git a/src/main/java/org/dspace/ctask/replicate/checkm/CompareWithManifest.java b/src/main/java/org/dspace/ctask/replicate/checkm/CompareWithManifest.java
index 041366e6..871b2d1d 100644
--- a/src/main/java/org/dspace/ctask/replicate/checkm/CompareWithManifest.java
+++ b/src/main/java/org/dspace/ctask/replicate/checkm/CompareWithManifest.java
@@ -37,10 +37,9 @@
* @see TransmitManifest
*/
@Distributive
-public class CompareWithManifest extends AbstractCurationTask
-{
+public class CompareWithManifest extends AbstractCurationTask {
private String result = null;
-
+
// Group where all Manifests will be stored
private String manifestGroupName;
@@ -57,31 +56,27 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
-
- try
- {
+
+ try {
Context context = Curator.curationContext();
String filename = repMan.storageId(context, dso.getHandle(), TransmitManifest.MANIFEST_EXTENSION);
int status = checkManifest(repMan, filename, context);
- //report the final result
+ // report the final result
report(result);
setResult(result);
return status;
- }
- catch (SQLException sqlE)
- {
+ } catch (SQLException sqlE) {
throw new IOException(sqlE);
}
}
-
+
/**
* This method recursively checks Manifests.
*
- * In a sense, all this is checking is that Bitstreams (files) have not changed within
+ * In a sense, all this is checking is that Bitstreams (files) have not changed within
* the current DSpace object. So, if the current object is a Site, Community or Collection,
* its manifest is not validated (as those manifests just point at other sub-manifests). Rather,
* this method recursively loads manifests until it locates all Item-level manifests. Then it
@@ -94,73 +89,58 @@ public int perform(DSpaceObject dso) throws IOException
* @throws SQLException if database error
* @return integer which represents Curator return status
*/
- private int checkManifest(ReplicaManager repMan, String filename, Context context) throws IOException, SQLException
- {
+ private int checkManifest(ReplicaManager repMan, String filename, Context context)
+ throws IOException, SQLException {
File manFile = repMan.fetchObject(context, manifestGroupName, filename);
- if (manFile != null)
- {
+ if (manFile != null) {
Item item = null;
Map bsMap = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader(manFile));
String line = null;
- while ((line = reader.readLine()) != null)
- {
- if (! line.startsWith("#")) // skip comments
- {
+ while ((line = reader.readLine()) != null) {
+ if (! line.startsWith("#")) { // skip comments
String entry = line.substring(0, line.indexOf("|"));
// if there's a dash in the first entry, then it just
// refers to a sub manifest
- if (entry.indexOf("-") > 0)
- {
+ if (entry.indexOf("-") > 0) {
// it's another manifest - fetch & check it
item = null;
bsMap.clear();
int status = checkManifest(repMan, entry, context);
-
- //if manifest failed check, return immediately (otherwise we'll continue processing)
- if(status == Curator.CURATE_FAIL)
+
+ // if manifest failed check, return immediately (otherwise we'll continue processing)
+ if (status == Curator.CURATE_FAIL) {
return status;
- }
- else
- {
+ }
+ } else {
// first entry is a bitstream reference. So, check it
int cut = entry.lastIndexOf("/");
- if (item == null)
- {
+ if (item == null) {
// look up object first & map bitstreams by seqID
String handle = entry.substring(0, cut);
DSpaceObject dso = handleService.resolveToObject(context, handle);
- if (dso != null && dso instanceof Item)
- {
+ if (dso != null && dso instanceof Item) {
item = (Item)dso;
- for (Bundle bundle : item.getBundles())
- {
- for (Bitstream bs : bundle.getBitstreams())
- {
+ for (Bundle bundle : item.getBundles()) {
+ for (Bitstream bs : bundle.getBitstreams()) {
bsMap.put(Integer.toString(bs.getSequenceID()), bs);
}
}
- }
- else
- {
+ } else {
result = "No item found for manifest entry: " + handle;
return Curator.CURATE_FAIL;
}
}
String seqId = entry.substring(cut + 1);
Bitstream bs = bsMap.get(seqId);
- if (bs != null)
- {
+ if (bs != null) {
String[] parts = line.split("\\|");
// compare checksums
- if (! bs.getChecksum().equals(parts[2]))
- {
+ if (! bs.getChecksum().equals(parts[2])) {
result = "Bitstream: " + seqId + " differs from manifest: " + entry;
return Curator.CURATE_FAIL;
}
- }
- else
- {
+ } else {
result = "No bitstream: " + seqId + " found for manifest entry: " + entry;
return Curator.CURATE_FAIL;
}
@@ -168,15 +148,13 @@ private int checkManifest(ReplicaManager repMan, String filename, Context contex
}
}
reader.close();
-
- //finished checking this entire manifest -- it was successful!
+
+ // finished checking this entire manifest -- it was successful!
result = "Manifest and repository content agree";
return Curator.CURATE_SUCCESS;
- }
- else
- {
+ } else {
result = "No manifest file found: " + filename;
- return Curator.CURATE_FAIL;
+ return Curator.CURATE_FAIL;
}
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/checkm/FetchManifest.java b/src/main/java/org/dspace/ctask/replicate/checkm/FetchManifest.java
index a026dd16..b32fa688 100644
--- a/src/main/java/org/dspace/ctask/replicate/checkm/FetchManifest.java
+++ b/src/main/java/org/dspace/ctask/replicate/checkm/FetchManifest.java
@@ -29,8 +29,7 @@
* @see TransmitManifest
*/
-public class FetchManifest extends AbstractCurationTask
-{
+public class FetchManifest extends AbstractCurationTask {
private String archFmt;
// Group where all Manifests are stored
@@ -42,7 +41,7 @@ public void init(Curator curator, String taskId) throws IOException {
archFmt = configurationService.getProperty("replicate.packer.archfmt");
manifestGroupName = configurationService.getProperty("replicate.group.manifest.name");
}
-
+
/**
* Perform 'Fetch Manifest' task
* @param dso DSpace Object to perform on
@@ -50,8 +49,7 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
try {
Context context = Curator.curationContext();
ReplicaManager repMan = ReplicaManager.instance();
diff --git a/src/main/java/org/dspace/ctask/replicate/checkm/RemoveManifest.java b/src/main/java/org/dspace/ctask/replicate/checkm/RemoveManifest.java
index 6296d01b..30f9c539 100644
--- a/src/main/java/org/dspace/ctask/replicate/checkm/RemoveManifest.java
+++ b/src/main/java/org/dspace/ctask/replicate/checkm/RemoveManifest.java
@@ -31,7 +31,7 @@
/**
* RemoveManifest task will remove the manifest of requested objects from the
- * replica store. If the manifest is multi-level, all the manifests of its
+ * replica store. If the manifest is multi-level, all the manifests of its
* children (members) will also be removed.
*
* Manifests conform to the CDL Checkm v0.7 manifest format spec.
@@ -54,7 +54,7 @@ public void init(Curator curator, String taskId) throws IOException {
super.init(curator, taskId);
manifestGroupName = configurationService.getProperty("replicate.group.manifest.name");
}
-
+
/**
* Removes replicas of passed object from the replica store.
* If a container, removes all the member replicas, in addition
@@ -66,8 +66,7 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
try {
Context context = Curator.curationContext();
@@ -84,7 +83,7 @@ public int perform(DSpaceObject dso) throws IOException
* If object has any associated child objects, their existing manifests
* are also removed from the Replica ObjectStore.
*
- * NOTE: this method does NOT remove the DSpace Object itself (nor any
+ * NOTE: this method does NOT remove the DSpace Object itself (nor any
* children) from the DSpace repository. It only removes the associated
* manifests from the Replica ObjectStore.
*
@@ -94,8 +93,7 @@ public int perform(DSpaceObject dso) throws IOException
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- private void remove(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException, SQLException
- {
+ private void remove(Context context, ReplicaManager repMan, DSpaceObject dso) throws IOException, SQLException {
String objId = repMan.storageId(context, dso.getHandle(), TransmitManifest.MANIFEST_EXTENSION);
repMan.removeObject(manifestGroupName, objId);
report("Removing manifest for: " + objId);
@@ -139,8 +137,7 @@ private void remove(Context context, ReplicaManager repMan, DSpaceObject dso) th
* @throws IOException if I/O error
*/
@Override
- public int perform(Context ctx, String id) throws IOException
- {
+ public int perform(Context ctx, String id) throws IOException {
DSpaceObject dso = dereference(ctx, id);
if (dso != null) {
return perform(dso);
@@ -150,13 +147,13 @@ public int perform(Context ctx, String id) throws IOException
setResult("Manifest for '" + id + "' has been removed");
return Curator.CURATE_SUCCESS;
}
-
+
/**
* Removes a DSpace Object's Manifest from the Replica ObjectStore.
* If object has any associated child objects, their existing manifests
* are also removed from the Replica ObjectStore.
*
- * NOTE: this method does NOT remove the DSpace Object itself (nor any
+ * NOTE: this method does NOT remove the DSpace Object itself (nor any
* children) from the DSpace repository. It only removes the associated
* manifests from the Replica ObjectStore.
*
@@ -165,8 +162,7 @@ public int perform(Context ctx, String id) throws IOException
* @param id the DSpace Object's identifier
* @throws IOException if I/O error
*/
- private void deleteManifest(Context context, ReplicaManager repMan, String id) throws IOException
- {
+ private void deleteManifest(Context context, ReplicaManager repMan, String id) throws IOException {
File manFile = repMan.fetchObject(context, manifestGroupName, id);
if (manFile != null) {
BufferedReader reader = new BufferedReader(new FileReader(manFile));
diff --git a/src/main/java/org/dspace/ctask/replicate/checkm/TransmitManifest.java b/src/main/java/org/dspace/ctask/replicate/checkm/TransmitManifest.java
index 3c06df24..dd2cc712 100644
--- a/src/main/java/org/dspace/ctask/replicate/checkm/TransmitManifest.java
+++ b/src/main/java/org/dspace/ctask/replicate/checkm/TransmitManifest.java
@@ -51,17 +51,17 @@
@Distributive
public class TransmitManifest extends AbstractCurationTask {
- //Version of CDL Checkm spec that this manifest conforms to
+ // Version of CDL Checkm spec that this manifest conforms to
private static final String CKM_VSN = "0.7";
-
- //Format extension for manifest files
+
+ // Format extension for manifest files
protected static final String MANIFEST_EXTENSION = "txt";
private String template = null;
-
+
// Group where all Manifests will be stored
private String manifestGroupName;
-
+
private static Logger log = LogManager.getLogger();
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
@@ -73,7 +73,7 @@ public void init(Curator curator, String taskId) throws IOException {
template = configurationService.getProperty("replicate.checkm.template");
manifestGroupName = configurationService.getProperty("replicate.group.manifest.name");
}
-
+
/**
* Perform 'Transmit Manifest' task
*
@@ -83,45 +83,34 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
ReplicaManager repMan = ReplicaManager.instance();
- try
- {
+ try {
Context context = Curator.curationContext();
File manFile = null;
int type = dso.getType();
- if (Constants.ITEM == type)
- {
+ if (Constants.ITEM == type) {
manFile = itemManifest(context, repMan, (Item)dso);
- }
- else if (Constants.COLLECTION == type)
- {
+ } else if (Constants.COLLECTION == type) {
// create manifests for each item - link in collection manifest
manFile = collectionManifest(context, repMan, (Collection)dso);
- }
- else if (Constants.COMMUNITY == type)
- {
+ } else if (Constants.COMMUNITY == type) {
// create manifests for Community on down
manFile = communityManifest(context, repMan, (Community)dso);
- }
- else if (Constants.SITE == type)
- {
+ } else if (Constants.SITE == type) {
// create manifests for all objects in DSpace
manFile = siteManifest(context, repMan, (Site)dso);
}
-
+
repMan.transferObject(manifestGroupName, manFile);
- }
- catch (SQLException sqlE)
- {
+ } catch (SQLException sqlE) {
throw new IOException(sqlE);
}
setResult("Created manifest for: " + dso.getHandle());
return Curator.CURATE_SUCCESS;
}
-
-
+
+
/**
* Generate a manifest for the DSpace Site. Also
* generate & transfer to replica ObjectStore the manifests for all
@@ -134,40 +123,39 @@ else if (Constants.SITE == type)
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- private File siteManifest(Context context, ReplicaManager repMan, Site site) throws IOException, SQLException
- {
- //Manifests stored as text files
+ private File siteManifest(Context context, ReplicaManager repMan, Site site) throws IOException, SQLException {
+ // Manifests stored as text files
String filename = repMan.storageId(context, site.getHandle(), MANIFEST_EXTENSION);
-
+
log.debug("Creating manifest for: " + site.getHandle());
-
+
//Create site manifest
File manFile = repMan.stage(context, manifestGroupName, filename);
Writer writer = manifestWriter(manFile);
int count = 0;
-
+
List topCommunities = communityService.findAllTop(context);
- //Create top-level community manifests & transfer each
- for (Community comm : topCommunities)
- {
+ // Create top-level community manifests & transfer each
+ for (Community comm : topCommunities) {
File scFile = communityManifest(context, repMan, comm);
writer.write(tokenized(scFile) + "\n");
count++;
repMan.transferObject(manifestGroupName, scFile);
}
- if (count == 0)
- {
+
+ if (count == 0) {
// write EOF marker to prevent confusion if container empty
writer.write("#%eof" + "\n");
}
+
writer.close();
report("Created manifest for: " + site.getHandle());
return manFile;
}
-
+
/**
* Generate a manifest for the specified DSpace Community. Also
- * generate & transfer to replica ObjectStore the manifests for any child
+ * generate & transfer to replica ObjectStore the manifests for any child
* objects (sub-communities, collections).
*
* @param context the context to use
@@ -178,38 +166,37 @@ private File siteManifest(Context context, ReplicaManager repMan, Site site) thr
* @throws SQLException if database error
*/
private File communityManifest(Context context, ReplicaManager repMan, Community comm) throws IOException,
- SQLException
- {
- //Manifests stored as text files
+ SQLException {
+ // Manifests stored as text files
String filename = repMan.storageId(context, comm.getHandle(), MANIFEST_EXTENSION);
-
+
log.debug("Creating manifest for: " + comm.getHandle());
-
- //Create community manifest
+
+ // Create community manifest
File manFile = repMan.stage(context, manifestGroupName, filename);
Writer writer = manifestWriter(manFile);
int count = 0;
- //Create sub-community manifests & transfer each
- for (Community subComm : comm.getSubcommunities())
- {
+ // Create sub-community manifests & transfer each
+ for (Community subComm : comm.getSubcommunities()) {
File scFile = communityManifest(context, repMan, subComm);
writer.write(tokenized(scFile) + "\n");
count++;
- repMan.transferObject(manifestGroupName, scFile);
+ repMan.transferObject(manifestGroupName, scFile);
}
- //Create collection manifests & transfer each
- for (Collection coll: comm.getCollections())
- {
+
+ // Create collection manifests & transfer each
+ for (Collection coll: comm.getCollections()) {
File colFile = collectionManifest(context, repMan, coll);
writer.write(tokenized(colFile) + "\n");
count++;
repMan.transferObject(manifestGroupName, colFile);
}
- if (count == 0)
- {
+
+ if (count == 0) {
// write EOF marker to prevent confusion if container empty
writer.write("#%eof" + "\n");
}
+
writer.close();
report("Created manifest for: " + comm.getHandle());
return manFile;
@@ -217,7 +204,7 @@ private File communityManifest(Context context, ReplicaManager repMan, Community
/**
* Generate a manifest for the specified DSpace Collection. Also
- * generate & transfer to replica ObjectStore the manifests for any child
+ * generate & transfer to replica ObjectStore the manifests for any child
* objects (items).
*
* @param context the context to use
@@ -228,32 +215,31 @@ private File communityManifest(Context context, ReplicaManager repMan, Community
* @throws SQLException if database error
*/
private File collectionManifest(Context context, ReplicaManager repMan, Collection coll) throws IOException,
- SQLException
- {
- //Manifests stored as text files
+ SQLException {
+ // Manifests stored as text files
String filename = repMan.storageId(context, coll.getHandle(), MANIFEST_EXTENSION);
-
+
log.debug("Creating manifest for: " + coll.getHandle());
-
+
//Create Collection manifest
File manFile = repMan.stage(context, manifestGroupName, filename);
Writer writer = manifestWriter(manFile);
int count = 0;
-
- //Create all Item manifests & transfer each
+
+ // Create all Item manifests & transfer each
Iterator- ii = itemService.findByCollection(context, coll);
- while (ii.hasNext())
- {
+ while (ii.hasNext()) {
File itemMan = itemManifest(context, repMan, ii.next());
count++;
writer.write(tokenized(itemMan) + "\n");
repMan.transferObject(manifestGroupName, itemMan);
}
- if (count == 0)
- {
+
+ if (count == 0) {
// write EOF marker to prevent confusion if container empty
writer.write("#%eof" + "\n");
}
+
writer.close();
report("Created manifest for: " + coll.getHandle());
return manFile;
@@ -269,35 +255,29 @@ private File collectionManifest(Context context, ReplicaManager repMan, Collecti
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- private File itemManifest(Context context, ReplicaManager repMan, Item item) throws IOException, SQLException
- {
+ private File itemManifest(Context context, ReplicaManager repMan, Item item) throws IOException, SQLException {
String filename = repMan.storageId(context, item.getHandle(), MANIFEST_EXTENSION);
-
+
log.debug("Creating manifest for: " + item.getHandle());
-
+
//Create Item manifest
File manFile = repMan.stage(context, manifestGroupName, filename);
Writer writer = manifestWriter(manFile);
-
+
// look through all ORIGINAL bitstreams, and add
// information about each (e.g. checksum) to manifest
int count = 0;
List bundles = itemService.getBundles(item, "ORIGINAL");
- if(bundles!=null && bundles.size()>0)
- {
- //there should be only one ORIGINAL bundle
+ if (bundles != null && !bundles.isEmpty()) {
+ // there should be only one ORIGINAL bundle
Bundle bundle = bundles.get(0);
- for (Bitstream bs : bundle.getBitstreams())
- {
+ for (Bitstream bs : bundle.getBitstreams()) {
int i = 0;
StringBuilder sb = new StringBuilder();
- for (String token : Arrays.asList(template.split("\\|")))
- {
- if (! token.startsWith("x"))
- {
+ for (String token : Arrays.asList(template.split("\\|"))) {
+ if (!token.startsWith("x")) {
// tokens are positionally defined
- switch (i)
- {
+ switch (i) {
case 0:
// what URL/name format?
sb.append(item.getHandle()).append("/").append(bs.getSequenceID());
@@ -329,16 +309,15 @@ private File itemManifest(Context context, ReplicaManager repMan, Item item) thr
}
count++;
writer.write(sb.substring(0, sb.length() - 1) + "\n");
- } //end for each bitstream
- }//end if ORIGINAL bundle
-
- //If no bitstreams found, then this is an empty manifest
- if (count == 0)
- {
+ } // end for each bitstream
+ } // end if ORIGINAL bundle
+
+ // If no bitstreams found, then this is an empty manifest
+ if (count == 0) {
// write EOF marker to prevent confusion if container empty
writer.write("#%eof" + "\n");
}
-
+
writer.close();
report("Created manifest for: " + item.getHandle());
return manFile;
@@ -350,8 +329,7 @@ private File itemManifest(Context context, ReplicaManager repMan, Item item) thr
* @return reference to Writer
* @throws IOException if I/O error
*/
- private Writer manifestWriter(File file) throws IOException
- {
+ private Writer manifestWriter(File file) throws IOException {
FileWriter writer = new FileWriter(file);
writer.write("#%checkm_" + CKM_VSN + "\n");
// write out template as explanatory metadata
@@ -359,14 +337,11 @@ private Writer manifestWriter(File file) throws IOException
return writer;
}
- private String tokenized(File file) throws IOException
- {
+ private String tokenized(File file) throws IOException {
int i = 0;
StringBuilder sb = new StringBuilder();
- for (String token : Arrays.asList(template.split("\\|")))
- {
- if (! token.startsWith("x"))
- {
+ for (String token : Arrays.asList(template.split("\\|"))) {
+ if (!token.startsWith("x")) {
// tokens are positionally defined
switch (i) {
case 0:
@@ -390,9 +365,9 @@ private String tokenized(File file) throws IOException
sb.append(file.lastModified());
break;
case 5:
- // target name - skip for now
+ // target name - skip for now
default:
- break;
+ break;
}
}
sb.append("|");
diff --git a/src/main/java/org/dspace/ctask/replicate/checkm/VerifyManifest.java b/src/main/java/org/dspace/ctask/replicate/checkm/VerifyManifest.java
index 78ba505b..877163f1 100644
--- a/src/main/java/org/dspace/ctask/replicate/checkm/VerifyManifest.java
+++ b/src/main/java/org/dspace/ctask/replicate/checkm/VerifyManifest.java
@@ -34,7 +34,7 @@
* @author richardrodgers
* @see TransmitManifest
*/
-@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
+@Suspendable(invoked = Curator.Invoked.INTERACTIVE)
public class VerifyManifest extends AbstractCurationTask {
// Group where all Manifests are stored
@@ -53,14 +53,14 @@ public void init(Curator curator, String taskId) throws IOException {
* @throws IOException if I/O error
*/
@Override
- public int perform(DSpaceObject dso) throws IOException
- {
+ public int perform(DSpaceObject dso) throws IOException {
Context context;
try {
context = Curator.curationContext();
} catch (SQLException e) {
throw new IOException(e);
}
+
ReplicaManager repMan = ReplicaManager.instance();
String objId = repMan.storageId(context, dso.getHandle(), TransmitManifest.MANIFEST_EXTENSION);
boolean found = repMan.objectExists(manifestGroupName, objId);
diff --git a/src/main/java/org/dspace/ctask/replicate/store/DuraCloudObjectStore.java b/src/main/java/org/dspace/ctask/replicate/store/DuraCloudObjectStore.java
index 50c5df66..3d0318af 100644
--- a/src/main/java/org/dspace/ctask/replicate/store/DuraCloudObjectStore.java
+++ b/src/main/java/org/dspace/ctask/replicate/store/DuraCloudObjectStore.java
@@ -76,12 +76,14 @@ public void init() throws IOException {
defaultWait = configurationService.getIntProperty("duracloud.retry.wait", DEFAULT_WAIT_BETWEEN_RETRIES);
waitMultiplier = configurationService.getIntProperty("duracloud.retry.multiplier", DEFAULT_WAIT_MULTIPLIER);
+ // Attempt to get Content Store from a parameter in the configuration
+ String storeId = configurationService.getProperty("duracloud.store-id", "0");
try {
- //Get the primary content store (e.g. Amazon)
- dcStore = storeManager.getPrimaryContentStore();
+ dcStore = storeManager.getContentStore(storeId);
} catch (ContentStoreException csE) {
- throw new IOException("Unable to connect to the DuraCloud Primary Content Store. Please check the " +
- "DuraCloud connection/authentication settings in your 'duracloud.cfg' file.", csE);
+ throw new IOException("Unable to connect to the DuraCloud Content Store. " +
+ "Please check the DuraCloud connection/authentication settings " +
+ "and the store-id setting in your 'duracloud.cfg' file.", csE);
}
}
@@ -95,7 +97,7 @@ public long fetchObject(final String group, final String id, final File file) th
String contentSizeHeader = content.getProperties().get(ContentStore.CONTENT_SIZE);
try {
size = Long.parseLong(contentSizeHeader);
- } catch(NumberFormatException nfe) {
+ } catch (NumberFormatException nfe) {
// ignore - header was missing or not a valid Long. We will determine size below
}
@@ -148,6 +150,7 @@ public long removeObject(String group, String id) throws IOException {
public long transferObject(String group, File file) throws IOException {
long size = 0L;
String chkSum = Utils.checksum(file, "MD5");
+
// make sure this is a different file from what replica store has
// to avoid network I/O tax
try {
@@ -162,6 +165,7 @@ public long transferObject(String group, File file) throws IOException {
} catch (ContentStoreException csE) {
throw new IOException(csE);
}
+
// delete staging file
file.delete();
return size;
@@ -249,11 +253,12 @@ public String objectAttribute(String group, String id, String attrName) throws I
* @return DuraCloud Space ID
*/
private String getSpaceID(String group) {
- //If group contains a forward or backslash, then the
- //Space ID is whatever is before that slash
- if (group!=null && group.contains("/")) {
+ // If group contains a forward or backslash, then the
+ // Space ID is whatever is before that slash
+ if (group != null && group.contains("/")) {
return group.substring(0, group.indexOf("/"));
- } else { // otherwise, the passed in group is the Space ID
+ } else {
+ // otherwise, the passed in group is the Space ID
return group;
}
}
@@ -269,11 +274,12 @@ private String getSpaceID(String group) {
* @return content prefix (ending with a forward slash)
*/
private String getContentPrefix(String group) {
- //If group contains a forward or backslash, then the
+ // If group contains a forward or backslash, then the
// content prefix is whatever is after that slash
- if (group!=null && group.contains("/")) {
+ if (group != null && group.contains("/")) {
return group.substring(group.indexOf("/") + 1) + "/";
- } else { // otherwise, no content prefix is specified
+ } else {
+ // otherwise, no content prefix is specified
return "";
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/store/LocalObjectStore.java b/src/main/java/org/dspace/ctask/replicate/store/LocalObjectStore.java
index e06f02d0..474633cd 100644
--- a/src/main/java/org/dspace/ctask/replicate/store/LocalObjectStore.java
+++ b/src/main/java/org/dspace/ctask/replicate/store/LocalObjectStore.java
@@ -34,30 +34,28 @@ public class LocalObjectStore implements ObjectStore {
// where replicas are kept
protected String storeDir = null;
-
+
// need no-arg constructor for PluginManager
public LocalObjectStore() {
}
@Override
- public void init() throws IOException
- {
+ public void init() throws IOException {
storeDir = configurationService.getProperty("replicate.store.dir");
+
File storeFile = new File(storeDir);
- if (! storeFile.exists())
- {
+ if (! storeFile.exists()) {
storeFile.mkdirs();
}
}
@Override
- public long fetchObject(String group, String id, File file) throws IOException
- {
+ public long fetchObject(String group, String id, File file) throws IOException {
// locate archive and copy to file
long size = 0L;
+
File archFile = new File(storeDir + File.separator + group, id);
- if (archFile.exists())
- {
+ if (archFile.exists()) {
size = archFile.length();
Utils.copy(archFile, file);
}
@@ -65,20 +63,18 @@ public long fetchObject(String group, String id, File file) throws IOException
}
@Override
- public boolean objectExists(String group, String id)
- {
+ public boolean objectExists(String group, String id) {
// do we have a copy in our managed area?
return new File(storeDir + File.separator + group, id).exists();
}
@Override
- public long removeObject(String group, String id)
- {
+ public long removeObject(String group, String id) {
// remove file if present
long size = 0L;
+
File remFile = new File(storeDir + File.separator + group, id);
- if (remFile.exists())
- {
+ if (remFile.exists()) {
size = remFile.length();
remFile.delete();
}
@@ -86,61 +82,54 @@ public long removeObject(String group, String id)
}
@Override
- public long transferObject(String group, File file) throws IOException
- {
+ public long transferObject(String group, File file) throws IOException {
// local transfer is a simple matter of renaming the file,
// we don't bother checking if replica is really new, since
// local deletes/copies are cheap
+
File archDir = new File(storeDir, group);
- if (! archDir.isDirectory())
- {
+ if (!archDir.isDirectory()) {
archDir.mkdirs();
}
+
File archFile = new File(archDir, file.getName());
- if (archFile.exists())
- {
+ if (archFile.exists()) {
archFile.delete();
}
- if (! file.renameTo(archFile))
- {
- throw new UnsupportedOperationException("Store does not support rename");
+
+ if (!file.renameTo(archFile)) {
+ throw new UnsupportedOperationException("Store does not support rename.");
}
+
return archFile.length();
}
@Override
- public String objectAttribute(String group, String id, String attrName) throws IOException
- {
+ public String objectAttribute(String group, String id, String attrName) throws IOException {
File archFile = new File(storeDir + File.separator + group, id);
- if ("checksum".equals(attrName))
- {
+ if ("checksum".equals(attrName)) {
return Utils.checksum(archFile, "MD5");
- }
- else if ("sizebytes".equals(attrName))
- {
+ } else if ("sizebytes".equals(attrName)) {
return String.valueOf(archFile.length());
- }
- else if ("modified".equals(attrName))
- {
+ } else if ("modified".equals(attrName)) {
return String.valueOf(archFile.lastModified());
}
+
return null;
}
-
+
@Override
- public long moveObject(String srcGroup, String destGroup, String id) throws IOException
- {
+ public long moveObject(String srcGroup, String destGroup, String id) throws IOException {
long size = 0L;
-
- //Find the file
+
+ // Find the file
File file = new File(storeDir + File.separator + srcGroup, id);
- if (file.exists())
- {
- //If file is found, just transfer it to destination,
+ if (file.exists()) {
+ // If file is found, just transfer it to destination,
// as transferObject() just does a file rename
size = transferObject(destGroup, file);
}
-
+
return size;
}
}
diff --git a/src/main/java/org/dspace/ctask/replicate/store/MountableObjectStore.java b/src/main/java/org/dspace/ctask/replicate/store/MountableObjectStore.java
index 8b81b3e1..8bfe85f1 100644
--- a/src/main/java/org/dspace/ctask/replicate/store/MountableObjectStore.java
+++ b/src/main/java/org/dspace/ctask/replicate/store/MountableObjectStore.java
@@ -26,24 +26,22 @@
*
* @author richardrodgers
*/
-public class MountableObjectStore extends LocalObjectStore
-{
+public class MountableObjectStore extends LocalObjectStore {
// need a no-arg constructor for PluginManager
- public MountableObjectStore()
- {
+ public MountableObjectStore() {
}
@Override
- public long transferObject(String group, File file) throws IOException
- {
+ public long transferObject(String group, File file) throws IOException {
// local transfer is a simple matter of copying the file,
// we don't bother checking if replica is really new, since
// local deletes/copies are cheap
+
File archFile = new File(storeDir + File.separator + group, file.getName());
- if (archFile.exists())
- {
+ if (archFile.exists()) {
archFile.delete();
}
+
Utils.copy(file, archFile);
return file.length();
}
diff --git a/src/main/java/org/dspace/pack/Packer.java b/src/main/java/org/dspace/pack/Packer.java
index 082ba52c..05d1ebee 100644
--- a/src/main/java/org/dspace/pack/Packer.java
+++ b/src/main/java/org/dspace/pack/Packer.java
@@ -18,8 +18,7 @@
*
* @author richardrodgers
*/
-public interface Packer
-{
+public interface Packer {
/**
* Packs (maps) the contents of this object into an archive file.
*
diff --git a/src/main/java/org/dspace/pack/PackerFactory.java b/src/main/java/org/dspace/pack/PackerFactory.java
index fa965e6d..6a32957a 100644
--- a/src/main/java/org/dspace/pack/PackerFactory.java
+++ b/src/main/java/org/dspace/pack/PackerFactory.java
@@ -29,9 +29,7 @@
*
* @author richardrodgers
*/
-public class PackerFactory
-{
-
+public class PackerFactory {
// basic bag property names - some optional
public static final String OBJFILE = "object.properties";
public static final String BAG_TYPE = "bagType";
@@ -56,14 +54,18 @@ public class PackerFactory
// cached instance of METSPacker - because a little expensive to create
private static METSPacker metsPacker = null;
+ /**
+ * Private constructor for this utility class
+ */
+ private PackerFactory() {}
+
public static Packer instance(Context context, DSpaceObject dso) {
Packer packer = null;
int type = dso.getType();
if ("mets".equals(packType)) {
if (metsPacker == null) {
metsPacker = new METSPacker(context, dso, archFmt);
- }
- else {
+ } else {
metsPacker.setContext(context);
metsPacker.setDSO(dso);
}
@@ -83,7 +85,7 @@ public static Packer instance(Context context, DSpaceObject dso) {
} else if (Constants.SITE == type) {
packer = new SitePacker(context, (Site)dso, archFmt);
} else {
- throw new RuntimeException("No packer for object type");
+ throw new RuntimeException("No packer for object type.");
}
return packer;
}
diff --git a/src/main/java/org/dspace/pack/bagit/BagInfoHelper.java b/src/main/java/org/dspace/pack/bagit/BagInfoHelper.java
index 96f66412..0f7eaf0a 100644
--- a/src/main/java/org/dspace/pack/bagit/BagInfoHelper.java
+++ b/src/main/java/org/dspace/pack/bagit/BagInfoHelper.java
@@ -23,6 +23,11 @@
*/
public class BagInfoHelper {
+ /**
+ * Private constructor for this utility class
+ */
+ private BagInfoHelper() {}
+
/**
* Loads the bag-info.txt and any other fields for tag files found under 'replicate.bag.tag'
*
@@ -36,7 +41,7 @@ public static Map> getTagFiles() {
final List keys = configurationService.getPropertyKeys(TAG_KEY);
- // precomplie patterns for when we split strings
+ // precompile patterns for when we split strings
final Pattern dotSplit = Pattern.compile("\\.");
final Pattern hyphenSplit = Pattern.compile("-");
@@ -76,5 +81,4 @@ public static Map> getTagFiles() {
return tagFiles;
}
-
}
diff --git a/src/main/java/org/dspace/pack/bagit/BagItAipReader.java b/src/main/java/org/dspace/pack/bagit/BagItAipReader.java
index ef6f12e5..3824e75f 100644
--- a/src/main/java/org/dspace/pack/bagit/BagItAipReader.java
+++ b/src/main/java/org/dspace/pack/bagit/BagItAipReader.java
@@ -27,9 +27,6 @@
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
import com.google.common.base.Optional;
import gov.loc.repository.bagit.domain.Bag;
@@ -39,6 +36,9 @@
import gov.loc.repository.bagit.exceptions.UnsupportedAlgorithmException;
import gov.loc.repository.bagit.reader.BagReader;
import gov.loc.repository.bagit.verify.BagVerifier;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Unmarshaller;
import org.apache.commons.io.FileUtils;
import org.dspace.pack.bagit.xml.metadata.Metadata;
import org.dspace.pack.bagit.xml.policy.Policies;
@@ -183,7 +183,7 @@ public boolean accept(Path path) {
};
Optional logo = Optional.absent();
- try(DirectoryStream bitstreams = Files.newDirectoryStream(bag.resolve(dataDirectory), bitstreamFilter)) {
+ try (DirectoryStream bitstreams = Files.newDirectoryStream(bag.resolve(dataDirectory), bitstreamFilter)) {
final Iterator iterator = bitstreams.iterator();
if (iterator.hasNext()) {
logo = Optional.of(iterator.next());
@@ -293,7 +293,7 @@ public boolean accept(Path path) {
final String bundleName = bundle.getFileName().toString();
// iterate all bitstreams
- try(DirectoryStream bitstreams = Files.newDirectoryStream(bundle, bitstreamFilter)) {
+ try (DirectoryStream bitstreams = Files.newDirectoryStream(bundle, bitstreamFilter)) {
for (Path bitstream : bitstreams) {
final String bitstreamName = bitstream.getFileName().toString();
diff --git a/src/main/java/org/dspace/pack/bagit/BagItAipWriter.java b/src/main/java/org/dspace/pack/bagit/BagItAipWriter.java
index ef9e43c2..50393344 100644
--- a/src/main/java/org/dspace/pack/bagit/BagItAipWriter.java
+++ b/src/main/java/org/dspace/pack/bagit/BagItAipWriter.java
@@ -23,17 +23,19 @@
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
import com.google.common.io.CountingOutputStream;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Marshaller;
import org.apache.commons.io.FileUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
+import org.dspace.content.Item;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.BitstreamService;
import org.dspace.core.Context;
@@ -53,6 +55,7 @@
import org.joda.time.LocalDate;
import org.joda.time.format.ISODateTimeFormat;
+
/**
* The BagItAipWriter handles the packaging of DSpaceObjects into their respective bags. It processes the metadata and
* bitstreams given to it by the various {@link org.dspace.pack.Packer}s in order to write the object.properties,
@@ -79,12 +82,14 @@ public class BagItAipWriter {
public static final String TEMPLATE_XML = "template-metadata.xml";
private static final String BITSTREAM_PREFIX = "bitstream_";
+ protected static final long DEFAULT_MODIFIED_DATE = 1036368000L * 1000;
+
private final BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
- // Fields used for book keeping
+ // Fields used for bookkeeping
private final AtomicLong successBytes = new AtomicLong();
private final AtomicLong successFiles = new AtomicLong();
- private final Map checksums = new HashMap<>();
+ private final LinkedHashMap checksums = new LinkedHashMap<>();
/**
* The context to use
diff --git a/src/main/java/org/dspace/pack/bagit/BagItPolicyUtil.java b/src/main/java/org/dspace/pack/bagit/BagItPolicyUtil.java
index 238b3295..16606023 100644
--- a/src/main/java/org/dspace/pack/bagit/BagItPolicyUtil.java
+++ b/src/main/java/org/dspace/pack/bagit/BagItPolicyUtil.java
@@ -49,6 +49,11 @@ public class BagItPolicyUtil {
private static final Logger logger = LoggerFactory.getLogger(BagItPolicyUtil.class);
+ /**
+ * Private constructor for this utility class
+ */
+ private BagItPolicyUtil() {}
+
/**
* Create a {@link Policy} for a {@link DSpaceObject}
*
@@ -134,7 +139,45 @@ public static void registerPolicies(final Context context, final DSpaceObject dS
// then use the authorizationService to add all policies to the dso
final List resourcePolicies = new ArrayList<>();
for (Policy policy : policies.getPolicies()) {
- final ResourcePolicy resourcePolicy = resourcePolicyService.create(context);
+ EPerson ePerson = null;
+ Group group = null;
+
+ final String groupName = policy.getGroup();
+ final String ePersonEmail = policy.getEperson();
+
+ if (groupName != null) {
+ final String nameForImport;
+
+ if (groupName.equalsIgnoreCase(Group.ADMIN) || groupName.equalsIgnoreCase(Group.ANONYMOUS)) {
+ nameForImport = groupName;
+ } else {
+ nameForImport = PackageUtils.translateGroupNameForImport(context, groupName);
+ }
+
+ group = groupService.findByName(context, nameForImport);
+ if (group == null) {
+ logger.warn("Could not find group {}} in the database! If this" +
+ "is either the ADMIN or ANONYMOUS group check that your database is" +
+ "initialized correctly.", nameForImport);
+ }
+ } else if (ePersonEmail != null) {
+ ePerson = ePersonService.findByEmail(context, ePersonEmail);
+ if (ePerson == null) {
+ logger.warn("Could not find ePerson {} in the database!", ePersonEmail);
+ }
+ }
+
+ // ResourcePolicy requires either a Group or an EPerson
+ if (ePerson == null && group == null) {
+ throw new PackageException("ResourcePolicy requires either a Group or an EPerson. Neither were found.");
+ }
+
+ final ResourcePolicy resourcePolicy = resourcePolicyService.create(context, ePerson, group);
+ if (resourcePolicy == null) {
+ throw new PackageException("Unable to create a ResourcePolicy.");
+ }
+
+ // Set remaining ResourcePolicy fields
resourcePolicy.setdSpaceObject(dSpaceObject);
final String rpName = policy.getName();
@@ -167,37 +210,6 @@ public static void registerPolicies(final Context context, final DSpaceObject dS
}
}
- final String groupName = policy.getGroup();
- final String epersonEmail = policy.getEperson();
- if (groupName != null) {
- final String nameForImport;
-
- if (groupName.equalsIgnoreCase(Group.ADMIN) || groupName.equalsIgnoreCase(Group.ANONYMOUS)) {
- nameForImport = groupName;
- } else {
- nameForImport = PackageUtils.translateGroupNameForImport(context, groupName);
- }
-
- final Group group = groupService.findByName(context, nameForImport);
- if (group == null) {
- throw new PackageException("Could not find group " + nameForImport + " in the database! If this" +
- "is either the ADMIN or ANONYMOUS group check that your database is" +
- "initialized correctly.");
- }
-
- resourcePolicy.setGroup(group);
- } else if (epersonEmail != null) {
- final EPerson ePerson = ePersonService.findByEmail(context, epersonEmail);
- if (ePerson == null) {
- throw new PackageException("Could not find ePerson " + epersonEmail + " in the database!");
- }
-
- resourcePolicy.setEPerson(ePerson);
- } else {
- // throw an exception as well?
- logger.warn("Cannot import policy, no rp-group or rp-eperson attribute found on value!");
- }
-
final Integer action = actionMapper().get(policy.getAction());
// exception if null?
if (action != null) {
diff --git a/src/main/java/org/dspace/pack/bagit/BagItRolesUtil.java b/src/main/java/org/dspace/pack/bagit/BagItRolesUtil.java
index a3baa36a..e1951c5b 100644
--- a/src/main/java/org/dspace/pack/bagit/BagItRolesUtil.java
+++ b/src/main/java/org/dspace/pack/bagit/BagItRolesUtil.java
@@ -41,6 +41,11 @@
*/
public class BagItRolesUtil {
+ /**
+ * Private constructor for this utility class
+ */
+ private BagItRolesUtil() {}
+
/**
* Retrieve all roles in a DSpace site. Gets all {@link Group}s and {@link EPerson}s.
*
@@ -53,7 +58,7 @@ public class BagItRolesUtil {
public static DSpaceRoles getDSpaceRoles(final Context context, final Site site) throws SQLException,
PackageException {
final GroupService groupService = EPersonServiceFactory.getInstance().getGroupService();
- final EPersonService ePersonService= EPersonServiceFactory.getInstance().getEPersonService();
+ final EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
final DSpaceRoles dSpaceRoles = new DSpaceRoles();
diff --git a/src/main/java/org/dspace/pack/bagit/CatalogPacker.java b/src/main/java/org/dspace/pack/bagit/CatalogPacker.java
index 7271709a..aef4a861 100644
--- a/src/main/java/org/dspace/pack/bagit/CatalogPacker.java
+++ b/src/main/java/org/dspace/pack/bagit/CatalogPacker.java
@@ -39,8 +39,7 @@
*
* @author richardrodgers
*/
-public class CatalogPacker implements Packer
-{
+public class CatalogPacker implements Packer {
private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
private final Context context;
@@ -50,27 +49,23 @@ public class CatalogPacker implements Packer
// Package compression format (e.g. zip or tgz) - Catalog packer uses same as AIPs
private String archFmt = configurationService.getProperty("replicate.packer.archfmt");
- public CatalogPacker(Context context, String objectId)
- {
+ public CatalogPacker(Context context, String objectId) {
this.context = context;
this.objectId = objectId;
}
-
- public CatalogPacker(Context context, String objectId, String ownerId, List members)
- {
+
+ public CatalogPacker(Context context, String objectId, String ownerId, List members) {
this.context = context;
this.objectId = objectId;
this.ownerId = ownerId;
this.members = members;
}
- public String getOwnerId()
- {
+ public String getOwnerId() {
return ownerId;
}
- public List getMembers()
- {
+ public List getMembers() {
return members;
}
@@ -89,7 +84,7 @@ public File pack(File packDir) throws IOException, SQLException, AuthorizeExcept
properties.put(OBJFILE, objectProperties);
// members file
- if (members.size() > 0) {
+ if (!members.isEmpty()) {
properties.put("members", members);
}
@@ -114,21 +109,18 @@ public void unpack(File archive) throws IOException {
}
@Override
- public long size(String method)
- {
+ public long size(String method) {
// not currently implemented
return 0L;
}
@Override
- public void setContentFilter(String filter)
- {
+ public void setContentFilter(String filter) {
// no-op
}
@Override
- public void setReferenceFilter(String filter)
- {
+ public void setReferenceFilter(String filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
diff --git a/src/main/java/org/dspace/pack/bagit/CollectionPacker.java b/src/main/java/org/dspace/pack/bagit/CollectionPacker.java
index a70d898f..985fbb09 100644
--- a/src/main/java/org/dspace/pack/bagit/CollectionPacker.java
+++ b/src/main/java/org/dspace/pack/bagit/CollectionPacker.java
@@ -53,15 +53,13 @@
*
* @author richardrodgers
*/
-public class CollectionPacker implements Packer
-{
+public class CollectionPacker implements Packer {
private CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();
// NB - these values must remain synchronized with DB schema
// they represent the persistent object state
- private static final String[] fields =
- {
+ private static final String[] fields = {
"name",
"short_description",
"introductory_text",
@@ -75,20 +73,17 @@ public class CollectionPacker implements Packer
private Collection collection = null;
private String archFmt = null;
- public CollectionPacker(Context context, Collection collection, String archFmt)
- {
+ public CollectionPacker(Context context, Collection collection, String archFmt) {
this.context = context;
this.collection = collection;
this.archFmt = archFmt;
}
- public Collection getCollection()
- {
+ public Collection getCollection() {
return collection;
}
- public void setCollection(Collection collection)
- {
+ public void setCollection(Collection collection) {
this.collection = collection;
}
@@ -200,45 +195,40 @@ public void unpack(File archive) throws AuthorizeException, IOException, SQLExce
}
@Override
- public long size(String method) throws SQLException
- {
+ public long size(String method) throws SQLException {
long size = 0L;
+
// start with logo size, if present
Bitstream logo = collection.getLogo();
- if (logo != null)
- {
+ if (logo != null) {
size += logo.getSizeBytes();
}
+
// proceed to items, unless 'norecurse' set
- if (! "norecurse".equals(method))
- {
+ if (!"norecurse".equals(method)) {
Iterator
- itemIter = itemService.findByCollection(context, collection);
ItemPacker iPup = null;
- while (itemIter.hasNext())
- {
- if (iPup == null)
- {
+ while (itemIter.hasNext()) {
+ if (iPup == null) {
iPup = (ItemPacker)PackerFactory.instance(context, itemIter.next());
- }
- else
- {
+ } else {
iPup.setItem(itemIter.next());
}
+
size += iPup.size(method);
}
}
+
return size;
}
@Override
- public void setContentFilter(String filter)
- {
+ public void setContentFilter(String filter) {
// no-op
}
@Override
- public void setReferenceFilter(String filter)
- {
+ public void setReferenceFilter(String filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/dspace/pack/bagit/CommunityPacker.java b/src/main/java/org/dspace/pack/bagit/CommunityPacker.java
index 860591e2..5f1db86d 100644
--- a/src/main/java/org/dspace/pack/bagit/CommunityPacker.java
+++ b/src/main/java/org/dspace/pack/bagit/CommunityPacker.java
@@ -49,8 +49,7 @@
*
* @author richardrodgers
*/
-public class CommunityPacker implements Packer
-{
+public class CommunityPacker implements Packer {
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
// NB - these values must remain synchronized with DB schema -
@@ -67,20 +66,17 @@ public class CommunityPacker implements Packer
private Community community = null;
private String archFmt = null;
- public CommunityPacker(Context context, Community community, String archFmt)
- {
+ public CommunityPacker(Context context, Community community, String archFmt) {
this.context = context;
this.community = community;
this.archFmt = archFmt;
}
- public Community getCommunity()
- {
+ public Community getCommunity() {
return community;
}
- public void setCommunity(Community community)
- {
+ public void setCommunity(Community community) {
this.community = community;
}
@@ -110,7 +106,7 @@ public File pack(File packDir) throws AuthorizeException, SQLException, IOExcept
// collect the policy
final Policies policy = BagItPolicyUtil.getPolicy(context, community);
- // and finally get he roles
+ // and finally get the roles
DSpaceRoles dSpaceRoles = null;
try {
dSpaceRoles = BagItRolesUtil.getDSpaceRoles(context, community);
@@ -148,7 +144,7 @@ public void unpack(File archive) throws AuthorizeException, IOException, SQLExce
throw new IOException(e.getMessage(), e);
}
- final Metadata metadata= reader.readMetadata();
+ final Metadata metadata = reader.readMetadata();
for (Value value : metadata.getValues()) {
MetadataFieldName field = value.getMetadataField();
communityService.setMetadataSingleValue(context, community, field.schema, field.element, field.qualifier,
@@ -168,39 +164,35 @@ public void unpack(File archive) throws AuthorizeException, IOException, SQLExce
}
@Override
- public long size(String method) throws SQLException
- {
+ public long size(String method) throws SQLException {
long size = 0L;
+
// logo size, if present
Bitstream logo = community.getLogo();
- if (logo != null)
- {
+ if (logo != null) {
size += logo.getSizeBytes();
}
+
// proceed to children, unless 'norecurse' set
- if (! "norecurse".equals(method))
- {
- for (Community comm : community.getSubcommunities())
- {
+ if (!"norecurse".equals(method)) {
+ for (Community comm : community.getSubcommunities()) {
size += PackerFactory.instance(context, comm).size(method);
}
- for (Collection coll : community.getCollections())
- {
+ for (Collection coll : community.getCollections()) {
size += PackerFactory.instance(context, coll).size(method);
}
}
+
return size;
}
@Override
- public void setContentFilter(String filter)
- {
+ public void setContentFilter(String filter) {
// no-op
}
@Override
- public void setReferenceFilter(String filter)
- {
+ public void setReferenceFilter(String filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/dspace/pack/bagit/ItemPacker.java b/src/main/java/org/dspace/pack/bagit/ItemPacker.java
index 94499e8f..7e8cfa45 100644
--- a/src/main/java/org/dspace/pack/bagit/ItemPacker.java
+++ b/src/main/java/org/dspace/pack/bagit/ItemPacker.java
@@ -69,20 +69,17 @@ public class ItemPacker implements Packer {
private boolean exclude = true;
private List refFilters = new ArrayList<>();
- public ItemPacker(Context context, Item item, String archFmt)
- {
+ public ItemPacker(Context context, Item item, String archFmt) {
this.context = context;
this.item = item;
this.archFmt = archFmt;
}
- public Item getItem()
- {
+ public Item getItem() {
return item;
}
- public void setItem(Item item)
- {
+ public void setItem(Item item) {
this.item = item;
}
@@ -102,7 +99,7 @@ public File pack(final File packDir) throws AuthorizeException, IOException, SQL
linked.append(coll.getHandle()).append(",");
}
}
- if (linked.length() > 0) {
+ if (!linked.isEmpty()) {
objectProperties.add(OTHER_IDS + PROPERTIES_DELIMITER + linked.substring(0, linked.length() - 1));
}
if (item.isWithdrawn()) {
@@ -120,7 +117,7 @@ public File pack(final File packDir) throws AuthorizeException, IOException, SQL
// policy.xml
final Policies policy = BagItPolicyUtil.getPolicy(context, item);
- // proceed to bundles, in sub-directories, filtering
+ // proceed to bundles, in subdirectories, filtering
final List bitstreams = new ArrayList<>();
for (Bundle bundle : item.getBundles()) {
final String bundleName = bundle.getName();
@@ -232,81 +229,69 @@ public void unpack(File archive) throws AuthorizeException, IOException, SQLExce
}
@Override
- public long size(String method) throws SQLException
- {
+ public long size(String method) throws SQLException {
long size = 0L;
+
// just total bitstream sizes, respecting filters
- for (Bundle bundle : item.getBundles())
- {
- if (accept(bundle.getName()))
- {
- for (Bitstream bs : bundle.getBitstreams())
- {
+ for (Bundle bundle : item.getBundles()) {
+ if (accept(bundle.getName())) {
+ for (Bitstream bs : bundle.getBitstreams()) {
size += bs.getSizeBytes();
}
}
}
+
return size;
}
-
+
@Override
- public void setContentFilter(String filter)
- {
- //If our filter list of bundles begins with a '+', then this list
- // specifies all the bundles to *include*. Otherwise all
+ public void setContentFilter(String filter) {
+ // If our filter list of bundles begins with a '+', then this list
+ // specifies all the bundles to *include*. Otherwise all
// bundles *except* the listed ones are included
- if(filter.startsWith("+"))
- {
+ if (filter.startsWith("+")) {
exclude = false;
- //remove the preceding '+' from our bundle list
+ // remove the preceding '+' from our bundle list
filter = filter.substring(1);
}
-
+
filterBundles = Arrays.asList(filter.split(","));
}
- private boolean accept(String name)
- {
+ private boolean accept(String name) {
boolean onList = filterBundles.contains(name);
return exclude ? ! onList : onList;
}
@Override
- public void setReferenceFilter(String filterSet)
- {
+ public void setReferenceFilter(String filterSet) {
// parse ref filter list
- for (String filter : filterSet.split(","))
- {
+ for (String filter : filterSet.split(",")) {
refFilters.add(new RefFilter(filter));
}
}
- private String byReference(Bundle bundle, Bitstream bs)
- {
- for (RefFilter filter : refFilters)
- {
+ private String byReference(Bundle bundle, Bitstream bs) {
+ for (RefFilter filter : refFilters) {
if (filter.bundle.equals(bundle.getName()) &&
- filter.size == bs.getSizeBytes())
- {
+ filter.size == bs.getSizeBytes()) {
return filter.url;
}
}
+
return null;
}
- private class RefFilter
- {
+ private class RefFilter {
public String bundle;
public long size;
public String url;
- public RefFilter(String filter)
- {
+ public RefFilter(String filter) {
String[] parts = filter.split(" ");
bundle = parts[0];
- size = Long.valueOf(parts[1]);
+ size = Long.parseLong(parts[1]);
url = parts[2];
}
}
-
}
diff --git a/src/main/java/org/dspace/pack/bagit/SitePacker.java b/src/main/java/org/dspace/pack/bagit/SitePacker.java
index 44cdf371..bf4789d0 100644
--- a/src/main/java/org/dspace/pack/bagit/SitePacker.java
+++ b/src/main/java/org/dspace/pack/bagit/SitePacker.java
@@ -66,6 +66,7 @@ public SitePacker(Context context, Site site, String archFmt) {
@Override
public File pack(File packDir) throws AuthorizeException, IOException, SQLException {
final Map> properties = new HashMap<>();
+
// object.properties
final List objectProperties = new ArrayList<>();
objectProperties.add(BAG_TYPE + PROPERTIES_DELIMITER + BAG_AIP);
diff --git a/src/main/java/org/dspace/pack/bagit/xml/metadata/Metadata.java b/src/main/java/org/dspace/pack/bagit/xml/metadata/Metadata.java
index 6ca816c7..1b42af57 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/metadata/Metadata.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/metadata/Metadata.java
@@ -9,8 +9,9 @@
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
+
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlRootElement;
/**
* Root tag for metadata.xml. Contains only a list of metadata {@link Value}s.
diff --git a/src/main/java/org/dspace/pack/bagit/xml/metadata/Value.java b/src/main/java/org/dspace/pack/bagit/xml/metadata/Value.java
index c903d21d..e735ed15 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/metadata/Value.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/metadata/Value.java
@@ -21,9 +21,8 @@
import static org.dspace.eperson.service.EPersonService.MD_LASTNAME;
import static org.dspace.eperson.service.EPersonService.MD_PHONE;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlValue;
-
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlValue;
import org.dspace.content.MetadataFieldName;
import org.dspace.content.MetadataValue;
diff --git a/src/main/java/org/dspace/pack/bagit/xml/policy/Policies.java b/src/main/java/org/dspace/pack/bagit/xml/policy/Policies.java
index a58b2b05..d7ca8552 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/policy/Policies.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/policy/Policies.java
@@ -9,8 +9,9 @@
import java.util.ArrayList;
import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
+
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlRootElement;
/**
* Root element for policy.xml. Contains only a list of {@link Policy} objects.
diff --git a/src/main/java/org/dspace/pack/bagit/xml/policy/Policy.java b/src/main/java/org/dspace/pack/bagit/xml/policy/Policy.java
index c4a36227..89ff8beb 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/policy/Policy.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/policy/Policy.java
@@ -7,7 +7,7 @@
*/
package org.dspace.pack.bagit.xml.policy;
-import javax.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlAttribute;
/**
* Pojo for {@link org.dspace.authorize.ResourcePolicy} objects
diff --git a/src/main/java/org/dspace/pack/bagit/xml/roles/AssociatedGroup.java b/src/main/java/org/dspace/pack/bagit/xml/roles/AssociatedGroup.java
index bde26f63..0cffced9 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/roles/AssociatedGroup.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/roles/AssociatedGroup.java
@@ -11,10 +11,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlElementWrapper;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
diff --git a/src/main/java/org/dspace/pack/bagit/xml/roles/DSpaceRoles.java b/src/main/java/org/dspace/pack/bagit/xml/roles/DSpaceRoles.java
index 08ac3e5f..8bfedf82 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/roles/DSpaceRoles.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/roles/DSpaceRoles.java
@@ -9,9 +9,10 @@
import java.util.HashSet;
import java.util.Set;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
+
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlElementWrapper;
+import jakarta.xml.bind.annotation.XmlRootElement;
/**
* Top level object for the DSpaceRoles xml schema mapping
diff --git a/src/main/java/org/dspace/pack/bagit/xml/roles/Member.java b/src/main/java/org/dspace/pack/bagit/xml/roles/Member.java
index cca9e136..0bfe4b4e 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/roles/Member.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/roles/Member.java
@@ -7,8 +7,7 @@
*/
package org.dspace.pack.bagit.xml.roles;
-import javax.xml.bind.annotation.XmlAttribute;
-
+import jakarta.xml.bind.annotation.XmlAttribute;
import org.dspace.content.packager.PackageException;
import org.dspace.content.packager.PackageUtils;
import org.dspace.core.Context;
diff --git a/src/main/java/org/dspace/pack/bagit/xml/roles/Person.java b/src/main/java/org/dspace/pack/bagit/xml/roles/Person.java
index 376bf3dd..27c13cf0 100644
--- a/src/main/java/org/dspace/pack/bagit/xml/roles/Person.java
+++ b/src/main/java/org/dspace/pack/bagit/xml/roles/Person.java
@@ -7,9 +7,8 @@
*/
package org.dspace.pack.bagit.xml.roles;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
-
+import jakarta.xml.bind.annotation.XmlAttribute;
+import jakarta.xml.bind.annotation.XmlElement;
import org.dspace.eperson.EPerson;
/**
diff --git a/src/main/java/org/dspace/pack/mets/METSPacker.java b/src/main/java/org/dspace/pack/mets/METSPacker.java
index c56229d3..52ec6078 100644
--- a/src/main/java/org/dspace/pack/mets/METSPacker.java
+++ b/src/main/java/org/dspace/pack/mets/METSPacker.java
@@ -45,8 +45,7 @@
*
* @author richardrodgers
*/
-public class METSPacker implements Packer
-{
+public class METSPacker implements Packer {
private PluginService pluginService = CoreServiceFactory.getInstance().getPluginService();
private CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
private ItemService itemService = ContentServiceFactory.getInstance().getItemService();
@@ -73,15 +72,13 @@ public class METSPacker implements Packer
private PackageDisseminator dip = null;
private PackageIngester sip = null;
- public METSPacker(Context context, String archFmt)
- {
+ public METSPacker(Context context, String archFmt) {
this.context = context;
this.dso = null;
this.archFmt = archFmt;
}
- public METSPacker(Context context, DSpaceObject dso, String archFmt)
- {
+ public METSPacker(Context context, DSpaceObject dso, String archFmt) {
this.context = context;
this.dso = dso;
this.archFmt = archFmt;
@@ -99,8 +96,7 @@ public void setContext(Context context) {
* Get DSpaceObject we are working with
* @return dso DSpaceObject
*/
- public DSpaceObject getDSO()
- {
+ public DSpaceObject getDSO() {
return dso;
}
@@ -108,8 +104,7 @@ public DSpaceObject getDSO()
* Set DSpaceObject we are working with
* @param dso DSpaceObject
*/
- public void setDSO(DSpaceObject dso)
- {
+ public void setDSO(DSpaceObject dso) {
this.dso = dso;
}
@@ -123,41 +118,34 @@ public void setDSO(DSpaceObject dso)
* @throws SQLException if database error
*/
@Override
- public File pack(File packDir) throws AuthorizeException, IOException, SQLException
- {
- //retrieve specified package disseminator
- if (dip == null)
- {
+ public File pack(File packDir) throws AuthorizeException, IOException, SQLException {
+ // retrieve specified package disseminator
+ if (dip == null) {
dip = (PackageDisseminator) pluginService.
getNamedPlugin(PackageDisseminator.class, "AIP");
}
- if (dip == null)
- {
+
+ if (dip == null) {
throw new IOException("Cannot obtain AIP disseminator. No dissemination plugin named 'AIP' is configured.");
}
- //Initialize packaging params
+ // Initialize packaging params
PackageParameters pkgParams = new PackageParameters();
- //If a content (Bundle) filter is specified
- if(this.contentFilter!=null && !this.contentFilter.isEmpty())
- {
- //Pass that on to the 'filterBundles' package parameter (which uses the same syntax)
+ // If a content (Bundle) filter is specified
+ if (this.contentFilter != null && !this.contentFilter.isEmpty()) {
+ // Pass that on to the 'filterBundles' package parameter (which uses the same syntax)
pkgParams.addProperty("filterBundles", contentFilter);
}
File archive = new File(packDir.getParentFile(), packDir.getName() + "." + archFmt);
- //disseminate the requested object
- try
- {
+
+ // disseminate the requested object
+ try {
dip.disseminate(context, dso, pkgParams, archive);
- }
- catch (PackageException pkgE)
- {
+ } catch (PackageException pkgE) {
throw new IOException(pkgE.getMessage(), pkgE);
- }
- catch (CrosswalkException xwkE)
- {
+ } catch (CrosswalkException xwkE) {
throw new IOException(xwkE.getMessage(), xwkE);
}
@@ -174,13 +162,11 @@ public File pack(File packDir) throws AuthorizeException, IOException, SQLExcept
* @throws SQLException if database error
*/
@Override
- public void unpack(File archive) throws AuthorizeException, IOException, SQLException
- {
- //unpack with default PackageParameter settings
+ public void unpack(File archive) throws AuthorizeException, IOException, SQLException {
+ // unpack with default PackageParameter settings
unpack(archive, null);
}
-
/**
* Restore/Replace a *single* DSpaceObject based on the contents of a METS AIP Package,
* and the given PackageParameters. This uses the configured AIP PackageIngester
@@ -197,118 +183,104 @@ public void unpack(File archive) throws AuthorizeException, IOException, SQLExce
* @throws IOException if I/O error
* @throws SQLException if database error
*/
- public void unpack(File archive, PackageParameters pkgParams) throws AuthorizeException, IOException, SQLException
- {
+ public void unpack(File archive, PackageParameters pkgParams) throws AuthorizeException, IOException, SQLException {
if (archive == null || ! archive.exists()) {
throw new IOException("Missing archive for object: " + dso.getHandle());
}
- if (sip == null)
- {
+
+ if (sip == null) {
sip = (PackageIngester) pluginService
.getNamedPlugin(PackageIngester.class, "AIP");
}
- if (sip == null)
- {
+
+ if (sip == null) {
throw new IOException("Cannot obtain AIP ingester. No ingestion plugin named 'AIP' is configured.");
}
- if(pkgParams==null || pkgParams.isEmpty())
- {
+ if (pkgParams == null || pkgParams.isEmpty()) {
pkgParams = new PackageParameters();
//--- Default settings/parameters for PackageIngester --
// These default settings should work for a wide variety of replace/restore actions.
// For more info, see: https://wiki.duraspace.org/display/DSDOC18/AIP+Backup+and+Restore
- //Always run in Replace mode (always replace existing objects & restore ones that are missing)
+ // Always run in Replace mode (always replace existing objects & restore ones that are missing)
pkgParams.setReplaceModeEnabled(true);
- //Always run in Recursive mode (also replace/restore all child objects)
+
+ // Always run in Recursive mode (also replace/restore all child objects)
pkgParams.setRecursiveModeEnabled(true);
- //Always create Metadata Fields referenced in an AIP, which are found to be missing in DSpace
+
+ // Always create Metadata Fields referenced in an AIP, which are found to be missing in DSpace
pkgParams.setProperty("createMetadataFields", "true");
- //Always skip over an object if it's Parent Object is "missing". These errors will still be logged as warnings.
- //(This setting is recommended for 'recursive' mode, as sometimes ingester will try to restore a child object
- // before its parent. But, once parent is restored, the child object will then be restored immediately after)
+
+ // Always skip over an object if it's Parent Object is "missing". These errors will still be
+ // logged as warnings. (This setting is recommended for 'recursive' mode, as sometimes ingester
+ // will try to restore a child object before its parent. But, once parent is restored, the child
+ // object will then be restored immediately after)
pkgParams.setProperty("skipIfParentMissing", "true");
}
DSpaceObject updatedDso = null;
- try
- {
+ try {
// Because we may be unpacking AIPs from an external storage location (e.g. DuraCloud or mapped drive)
// we will only ever replace/restore a SINGLE OBJECT at a time.
// It is up to the Replication Task to ensure each item is downloaded as needed and its
// children are also replaced/restored recursively as needed.
- if(pkgParams.replaceModeEnabled()) //run object replace
+ if (pkgParams.replaceModeEnabled()) {
+ // run object replace
updatedDso = sip.replace(context, dso, archive, pkgParams);
- else //else run a 'restore' (special form of ingest) with a null parent object (parent obj will be determined from package manifest)
+ } else {
+ // else run a 'restore' (special form of ingest) with a null parent object
+ // (parent obj will be determined from package manifest)
updatedDso = sip.ingest(context, null, archive, pkgParams, null);
- }
- catch(IllegalStateException ie)
- {
+ }
+ } catch (IllegalStateException isE) {
// NOTE: we should only encounter an IllegalStateException, when
// attempting to ingest an object that already exists in the system.
// (i.e. this is a "handle already in use" exception)
- //if we are skipping over (i.e. keeping) existing objects
- if(pkgParams.keepExistingModeEnabled())
- {
- //just log a warning
+ // if we are skipping over (i.e. keeping) existing objects
+ if (pkgParams.keepExistingModeEnabled()) {
+ // just log a warning
log.warn("Skipping over object which already exists.");
+ } else {
+ // Pass this exception on -- which essentially causes a full rollback
+ // of all changes (this is the default)
+ throw isE;
}
- else // Pass this exception on -- which essentially causes a full rollback of all changes (this is the default)
- {
- throw ie;
- }
- }
- catch (PackageException pkgE)
- {
+ } catch (PackageException pkgE) {
throw new IOException(pkgE.getMessage(), pkgE);
- }
- catch (CrosswalkException xwkE)
- {
+ } catch (CrosswalkException xwkE) {
throw new IOException(xwkE.getMessage(), xwkE);
- }
- catch (WorkflowException wfE)
- {
+ } catch (WorkflowException wfE) {
throw new IOException(wfE.getMessage(), wfE);
}
- //If we are using a class that extends AbstractPackageIngester,
- //then we can save the child AIP references for later processing.
- //(When recursion is enabled, this step ensures the calling curation task
+ // If we are using a class that extends AbstractPackageIngester,
+ // then we can save the child AIP references for later processing.
+ // (When recursion is enabled, this step ensures the calling curation task
// knows which child AIPs to next restore/replace)
- if(sip instanceof AbstractPackageIngester)
- {
- //Only non-Items reference other child AIPs
- //(NOTE: Items have no children, as Bitstreams/Bundles are contained in Item packages)
- if(updatedDso!=null && updatedDso.getType()!=Constants.ITEM)
- {
- //Check if we found child package references when unpacking this latest package into a DSpaceObject
+ if (sip instanceof AbstractPackageIngester) {
+ // Only non-Items reference other child AIPs
+ // (NOTE: Items have no children, as Bitstreams/Bundles are contained in Item packages)
+ if (updatedDso != null && updatedDso.getType() != Constants.ITEM) {
+ // Check if we found child package references when unpacking this latest package into a DSpaceObject
this.childPackageRefs = ((AbstractPackageIngester) sip).getPackageReferences(updatedDso);
- }//end if not an Item
+ }
}
- //NOTE: Context is handled by Curator -- it will commit or close when needed.
+ // NOTE: Context is handled by Curator -- it will commit or close when needed.
}
@Override
- public long size(String method) throws SQLException
- {
+ public long size(String method) throws SQLException {
int type = dso.getType();
- if (Constants.SITE == type)
- {
+ if (Constants.SITE == type) {
return siteSize();
- }
- else if (Constants.COMMUNITY == type)
- {
+ } else if (Constants.COMMUNITY == type) {
return communitySize((Community)dso);
- }
- else if (Constants.COLLECTION == type)
- {
+ } else if (Constants.COLLECTION == type) {
return collectionSize((Collection)dso);
- }
- else
- {
+ } else {
return itemSize((Item)dso);
}
}
@@ -322,16 +294,14 @@ else if (Constants.COLLECTION == type)
* @return estimated storage size
* @throws SQLException if database error
*/
- private long siteSize() throws SQLException
- {
+ private long siteSize() throws SQLException {
long size = 0L;
- //This Site AIP itself is very small, so as a "guess" we'll just total
+ // This Site AIP itself is very small, so as a "guess" we'll just total
// up the size of all Community, Collection & Item AIPs
- //Then, perform this task for all Top-Level Communities in the Site
+ // Then, perform this task for all Top-Level Communities in the Site
// (this will recursively perform task for all objects in DSpace)
- for (Community subcomm : communityService.findAllTop(context))
- {
+ for (Community subcomm : communityService.findAllTop(context)) {
size += communitySize(subcomm);
}
@@ -348,23 +318,25 @@ private long siteSize() throws SQLException
* @return estimated storage size
* @throws SQLException if database error
*/
- private long communitySize(Community community) throws SQLException
- {
+ private long communitySize(Community community) throws SQLException {
long size = 0L;
+
// logo size, if present
Bitstream logo = community.getLogo();
- if (logo != null)
- {
+ if (logo != null) {
size += logo.getSizeBytes();
}
- for (Community comm : community.getSubcommunities())
- {
+
+ // Calculate sub-communities
+ for (Community comm : community.getSubcommunities()) {
size += communitySize(comm);
}
- for (Collection coll : community.getCollections())
- {
+
+ // Calculate collections
+ for (Collection coll : community.getCollections()) {
size += collectionSize(coll);
}
+
return size;
}
@@ -378,20 +350,21 @@ private long communitySize(Community community) throws SQLException
* @return estimated storage size
* @throws SQLException if database error
*/
- private long collectionSize(Collection collection) throws SQLException
- {
+ private long collectionSize(Collection collection) throws SQLException {
long size = 0L;
+
// start with logo size, if present
Bitstream logo = collection.getLogo();
- if (logo != null)
- {
+ if (logo != null) {
size += logo.getSizeBytes();
}
+
+ // Calculate items
Iterator
- itemIter = itemService.findByCollection(context, collection);
- while (itemIter.hasNext())
- {
+ while (itemIter.hasNext()) {
size += itemSize(itemIter.next());
}
+
return size;
}
@@ -404,33 +377,29 @@ private long collectionSize(Collection collection) throws SQLException
* @return estimated storage size
* @throws SQLException if database error
*/
- private long itemSize(Item item) throws SQLException
- {
+ private long itemSize(Item item) throws SQLException {
long size = 0L;
+
// just total bitstream sizes, respecting filters
- for (Bundle bundle : item.getBundles())
- {
- if (includedBundle(bundle.getName()))
- {
- for (Bitstream bs : bundle.getBitstreams())
- {
+ for (Bundle bundle : item.getBundles()) {
+ if (includedBundle(bundle.getName())) {
+ for (Bitstream bs : bundle.getBitstreams()) {
size += bs.getSizeBytes();
}
}
}
+
return size;
}
@Override
- public void setContentFilter(String filter)
- {
- //If our filter list of bundles begins with a '+', then this list
+ public void setContentFilter(String filter) {
+ // If our filter list of bundles begins with a '+', then this list
// specifies all the bundles to *include*. Otherwise all
// bundles *except* the listed ones are included
- if(filter.startsWith("+"))
- {
+ if (filter.startsWith("+")) {
exclude = false;
- //remove the preceding '+' from our bundle list
+ // remove the preceding '+' from our bundle list
filter = filter.substring(1);
}
@@ -438,15 +407,13 @@ public void setContentFilter(String filter)
filterBundles = Arrays.asList(filter.split(","));
}
- private boolean includedBundle(String name)
- {
+ private boolean includedBundle(String name) {
boolean onList = filterBundles.contains(name);
return exclude ? ! onList : onList;
}
@Override
- public void setReferenceFilter(String filterSet)
- {
+ public void setReferenceFilter(String filterSet) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -459,8 +426,7 @@ public void setReferenceFilter(String filterSet)
*
* @return List of references to child AIPs
*/
- public List getChildPackageRefs()
- {
+ public List getChildPackageRefs() {
return childPackageRefs;
}
}
diff --git a/src/test/java/org/dspace/TestAuthorizeServiceFactory.java b/src/test/java/org/dspace/TestAuthorizeServiceFactory.java
index aa8b9e3c..8c687f91 100644
--- a/src/test/java/org/dspace/TestAuthorizeServiceFactory.java
+++ b/src/test/java/org/dspace/TestAuthorizeServiceFactory.java
@@ -19,11 +19,9 @@
* @author mikejritter
*/
public class TestAuthorizeServiceFactory extends AuthorizeServiceFactory {
-
private final AuthorizeService authorizeService = mock(AuthorizeService.class);
private final ResourcePolicyService resourcePolicyService = mock(ResourcePolicyService.class);
-
@Override
public AuthorizeService getAuthorizeService() {
return authorizeService;
diff --git a/src/test/java/org/dspace/TestContentServiceFactory.java b/src/test/java/org/dspace/TestContentServiceFactory.java
index 1c6d46a8..f393ad80 100644
--- a/src/test/java/org/dspace/TestContentServiceFactory.java
+++ b/src/test/java/org/dspace/TestContentServiceFactory.java
@@ -21,6 +21,7 @@
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.DSpaceObjectLegacySupportService;
import org.dspace.content.service.DSpaceObjectService;
+import org.dspace.content.service.DuplicateDetectionService;
import org.dspace.content.service.EntityService;
import org.dspace.content.service.EntityTypeService;
import org.dspace.content.service.InstallItemService;
@@ -53,6 +54,11 @@ public class TestContentServiceFactory extends ContentServiceFactory {
private final CommunityService communityService = mock(CommunityService.class);
private final BundleService bundleService = mock(BundleService.class);
+ @Override
+ public DuplicateDetectionService getDuplicateDetectionService() {
+ throw new UnsupportedOperationException();
+ };
+
@Override
public List> getDSpaceObjectServices() {
throw new UnsupportedOperationException();
diff --git a/src/test/java/org/dspace/TestServiceManager.java b/src/test/java/org/dspace/TestServiceManager.java
index cdcf54a2..2d6d044a 100644
--- a/src/test/java/org/dspace/TestServiceManager.java
+++ b/src/test/java/org/dspace/TestServiceManager.java
@@ -49,6 +49,11 @@ public List getServicesNames() {
return new ArrayList<>(serviceNameMap.keySet());
}
+ @Override
+ public Map getServicesWithNamesByType(Class type) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void registerService(String name, Object service) {
serviceNameMap.put(name, service);
diff --git a/src/test/java/org/dspace/ctask/replicate/store/DuraCloudObjectStoreTest.java b/src/test/java/org/dspace/ctask/replicate/store/DuraCloudObjectStoreTest.java
index 6191390f..2665b405 100644
--- a/src/test/java/org/dspace/ctask/replicate/store/DuraCloudObjectStoreTest.java
+++ b/src/test/java/org/dspace/ctask/replicate/store/DuraCloudObjectStoreTest.java
@@ -39,7 +39,6 @@
* create outgoing requests to DuraCloud
*/
public class DuraCloudObjectStoreTest {
-
private final String group = "dc-object-store-test";
private final String mimeType = "application/zip";
@@ -55,6 +54,7 @@ public void setup() {
@Test
public void testUploadRetry() throws Exception {
final URL root = DuraCloudObjectStoreTest.class.getClassLoader().getResource("unpack");
+
// copy the file because the ObjectStore will delete it after transfer
final Path catalog = Paths.get(root.toURI()).resolve("catalog.zip");
final Path zipFile = Paths.get(root.toURI()).resolve("dc-upload.zip");
@@ -95,6 +95,7 @@ public void testUploadFailure() throws Exception {
objectStore.transferObject(group, zipFile.toFile());
fail("Expected transfer to fail");
} catch (IOException ignored) {
+ // ignore exception
}
// verify that the retry process was attempted
@@ -108,5 +109,4 @@ public void testUploadFailure() throws Exception {
// and finish cleaning up
Files.delete(zipFile);
}
-
}
\ No newline at end of file
diff --git a/src/test/java/org/dspace/pack/bagit/BagItPolicyUtilTest.java b/src/test/java/org/dspace/pack/bagit/BagItPolicyUtilTest.java
index d06e15ff..947385b9 100644
--- a/src/test/java/org/dspace/pack/bagit/BagItPolicyUtilTest.java
+++ b/src/test/java/org/dspace/pack/bagit/BagItPolicyUtilTest.java
@@ -213,7 +213,8 @@ public void registerPolicies() throws Exception {
final EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
final ResourcePolicyService resourcePolicyService = AuthorizeServiceFactory.getInstance()
.getResourcePolicyService();
- when(resourcePolicyService.create(any(Context.class))).thenReturn(initReloadable(ResourcePolicy.class));
+ when(resourcePolicyService.create(any(Context.class), any(), any()))
+ .thenReturn(initReloadable(ResourcePolicy.class));
when(groupService.findByName(any(Context.class), eq(Group.ADMIN))).thenReturn(group);
when(groupService.findByName(any(Context.class), eq(Group.ANONYMOUS))).thenReturn(group);
when(ePersonService.findByEmail(any(Context.class), eq(personEmail))).thenReturn(ePerson);
@@ -222,14 +223,15 @@ public void registerPolicies() throws Exception {
BagItPolicyUtil.registerPolicies(mockContext, community, policy);
// verify service interactions
- verify(resourcePolicyService, times(8)).create(any(Context.class));
- verify(groupService, times(4)).findByName(any(Context.class), matches(Group.ADMIN + "|" + Group.ANONYMOUS));
+ verify(resourcePolicyService, times(8)).create(any(Context.class), any(), any());
+ verify(groupService, times(4)).findByName(any(Context.class),
+ matches(Group.ADMIN + "|" + Group.ANONYMOUS));
verify(ePersonService, times(4)).findByEmail(any(Context.class), eq(personEmail));
// additional verification of services which we didn't need to set up
final AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
verify(authorizeService, times(1)).removeAllPolicies(any(Context.class), eq(community));
- verify(authorizeService, times(1)).addPolicies(any(Context.class), anyListOf(ResourcePolicy.class),
- eq(community));
+ verify(authorizeService, times(1)).addPolicies(any(Context.class),
+ anyListOf(ResourcePolicy.class), eq(community));
}
}
diff --git a/src/test/java/org/dspace/pack/bagit/CatalogPackerTest.java b/src/test/java/org/dspace/pack/bagit/CatalogPackerTest.java
index e70730c7..04dfaea9 100644
--- a/src/test/java/org/dspace/pack/bagit/CatalogPackerTest.java
+++ b/src/test/java/org/dspace/pack/bagit/CatalogPackerTest.java
@@ -35,7 +35,8 @@ public void testPack() throws Exception {
final Path output = Paths.get(resources.toURI().resolve("catalog-packer-test"));
// setup the packer
- final CatalogPacker packer = new CatalogPacker(mockContext, "object-id", "owner-id", ImmutableList.of("member"));
+ final CatalogPacker packer = new CatalogPacker(mockContext, "object-id",
+ "owner-id", ImmutableList.of("member"));
final File packedOutput = packer.pack(output.toFile());
assertThat(packedOutput).exists();
diff --git a/src/test/java/org/dspace/pack/bagit/CollectionPackerTest.java b/src/test/java/org/dspace/pack/bagit/CollectionPackerTest.java
index 6ffbf8eb..b1d50865 100644
--- a/src/test/java/org/dspace/pack/bagit/CollectionPackerTest.java
+++ b/src/test/java/org/dspace/pack/bagit/CollectionPackerTest.java
@@ -41,6 +41,8 @@
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
+import org.dspace.eperson.EPerson;
+import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
@@ -159,7 +161,7 @@ public void testUnpack() throws Exception {
// since our policy.xml is empty, verify that we never fetched anything and still used the authorize service
// as expected
final List empty = new ArrayList<>();
- verify(resourcePolicyService, never()).create(any(Context.class));
+ verify(resourcePolicyService, never()).create(any(Context.class), any(EPerson.class), any(Group.class));
verify(groupService, never()).findByName(any(Context.class), anyString());
verify(ePersonService, never()).findByEmail(any(Context.class), anyString());
verify(authorizeService, times(1)).removeAllPolicies(any(Context.class), eq(collection));
diff --git a/src/test/java/org/dspace/pack/bagit/CommunityPackerTest.java b/src/test/java/org/dspace/pack/bagit/CommunityPackerTest.java
index 9897f46e..f23be172 100644
--- a/src/test/java/org/dspace/pack/bagit/CommunityPackerTest.java
+++ b/src/test/java/org/dspace/pack/bagit/CommunityPackerTest.java
@@ -35,6 +35,8 @@
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
+import org.dspace.eperson.EPerson;
+import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
@@ -126,7 +128,7 @@ public void testUnpack() throws Exception {
// since our policy.xml is empty, verify that we never fetched anything and still used the authorize service
// as expected
final List empty = new ArrayList<>();
- verify(resourcePolicyService, never()).create(any(Context.class));
+ verify(resourcePolicyService, never()).create(any(Context.class), any(EPerson.class), any(Group.class));
verify(groupService, never()).findByName(any(Context.class), anyString());
verify(ePersonService, never()).findByEmail(any(Context.class), anyString());
verify(authorizeService, times(1)).removeAllPolicies(any(Context.class), eq(community));
diff --git a/src/test/java/org/dspace/pack/bagit/ItemPackerTest.java b/src/test/java/org/dspace/pack/bagit/ItemPackerTest.java
index 16e5fceb..74ca945c 100644
--- a/src/test/java/org/dspace/pack/bagit/ItemPackerTest.java
+++ b/src/test/java/org/dspace/pack/bagit/ItemPackerTest.java
@@ -52,6 +52,8 @@
import org.dspace.content.service.BundleService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
+import org.dspace.eperson.EPerson;
+import org.dspace.eperson.Group;
import org.dspace.eperson.factory.EPersonServiceFactory;
import org.dspace.eperson.service.EPersonService;
import org.dspace.eperson.service.GroupService;
@@ -329,7 +331,7 @@ public void testUnpack() throws Exception {
// since our policy.xml is empty, verify that we never fetched anything and still used the authorize service
// as expected
final List empty = new ArrayList<>();
- verify(resourcePolicyService, never()).create(any(Context.class));
+ verify(resourcePolicyService, never()).create(any(Context.class), any(EPerson.class), any(Group.class));
verify(groupService, never()).findByName(any(Context.class), anyString());
verify(ePersonService, never()).findByEmail(any(Context.class), anyString());
verify(authorizeService, times(1)).removeAllPolicies(any(Context.class), eq(item));