Index: Packager.java =================================================================== --- Packager.java (.../dspace/trunk/dspace-api/src/main/java/org/dspace/app/packager) (revision 5257) +++ Packager.java (.../sandbox/aip-external-1_6-prototype/dspace-api/src/main/java/org/dspace/app/packager) (revision 5257) @@ -38,22 +38,24 @@ package org.dspace.app.packager; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.SQLException; +import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.PosixParser; -import org.dspace.content.Collection; +import org.dspace.authorize.AuthorizeException; import org.dspace.content.DSpaceObject; -import org.dspace.content.Item; -import org.dspace.content.InstallItem; -import org.dspace.content.WorkspaceItem; +import org.dspace.content.crosswalk.CrosswalkException; import org.dspace.content.packager.PackageDisseminator; +import org.dspace.content.packager.PackageException; import org.dspace.content.packager.PackageParameters; import org.dspace.content.packager.PackageIngester; import org.dspace.core.Constants; @@ -61,8 +63,6 @@ import org.dspace.core.PluginManager; import org.dspace.eperson.EPerson; import org.dspace.handle.HandleManager; -import org.dspace.workflow.WorkflowManager; -import org.dspace.workflow.WorkflowItem; /** * Command-line interface to the Packager plugin. @@ -79,13 +79,15 @@ * (Add the -h option to get the command to show its own help) * *
- *  1. To submit a SIP:
- *   java org.dspace.app.packager.Packager
+ *  1. To submit a SIP  (submissions tend to create a *new* object, with a new handle.  If you want to restore an object, see -r option below)
+ *   dspace packager
  *       -e {ePerson}
  *       -t {PackagerType}
- *       -c {collection-handle} [ -c {collection} ...]
- *       -o {name}={value} [ -o {name}={value} ..]
- *       [-w]
+ *       -p {parent-handle} [ -p {parent2} ...]
+ *       [-o {name}={value} [ -o {name}={value} ..]]
+ *       [-a] --- also recursively ingest all child packages of the initial package
+ *                (child pkgs must be referenced from parent pkg)
+ *       [-w]   --- skip Workflow
  *       {package-filename}
  * 
  *   {PackagerType} must match one of the aliases of the chosen Packager
@@ -94,14 +96,37 @@
  *   The "-w" option circumvents Workflow, and is optional.  The "-o"
  *   option, which may be repeated, passes options to the packager
  *   (e.g. "metadataOnly" to a DIP packager).
+ *
+ *  2. To restore an AIP  (similar to submit mode, but attempts to restore with the handles/parents specified in AIP):
+ *   dspace packager
+ *       -r     --- restores a object from a package info, including the specified handle (will throw an error if handle is already in use)
+ *       -e {ePerson}
+ *       -t {PackagerType}
+ *       [-o {name}={value} [ -o {name}={value} ..]]
+ *       [-a] --- also recursively restore all child packages of the initial package
+ *                (child pkgs must be referenced from parent pkg)
+ *       [-k]   --- Skip over errors where objects already exist and Keep Existing objects by default.
+ *                  Use with -r to only restore objects which do not already exist.  By default, -r will throw an error
+ *                  and rollback all changes when an object is found that already exists.
+ *       [-f]   --- Force a restore (even if object already exists).
+ *                  Use with -r to replace an existing object with one from a package (essentially a delete and restore).
+ *                  By default, -r will throw an error and rollback all changes when an object is found that already exists.
+ *       [-i {identifier-handle-of-object}] -- Optional when -f is specified.  When replacing an object, you can specify the
+ *                  object to replace if it cannot be easily determined from the package itself.
+ *       {package-filename}
  * 
- *  2. To write out a DIP:
- *   java org.dspace.content.packager.Packager
+ *   Restoring is very similar to submitting, except that you are recreating pre-existing objects.  So, in a restore, the object(s) are
+ *   being recreated based on the details in the AIP.  This means that the object is recreated with the same handle and same parent/children
+ *   objects.  Not all {PackagerTypes} may support a "restore".
+ *
+ *  3. To write out a DIP:
+ *   dspace packager
  *       -d
  *       -e {ePerson}
  *       -t {PackagerType}
- *       -i {item-handle}
- *       -o {name}={value} [ -o {name}={value} ..]
+ *       -i {identifier-handle-of-object}
+ *       [-a] --- also recursively disseminate all child objects of this object
+ *       [-o {name}={value} [ -o {name}={value} ..]]
  *       {package-filename}
  * 
  *   The "-d" switch chooses a Dissemination packager, and is required.
@@ -113,10 +138,16 @@
  * output, respectively.
  * 
  * @author Larry Stone
+ * @author Tim Donohue
  * @version $Revision$
  */
 public class Packager
 {
+    /* Various private global settings/options */
+    private String packageType = null;
+    private boolean submit = true;
+    private boolean userInteractionEnabled = true;
+
     // die from illegal command line
     private static void usageError(String msg)
     {
@@ -128,8 +159,8 @@
     public static void main(String[] argv) throws Exception
     {
         Options options = new Options();
-        options.addOption("c", "collection", true,
-                "destination collection(s) Handle (repeatable)");
+        options.addOption("p", "parent", true,
+                "Handle(s) of parent Community or Collection into which to ingest object (repeatable)");
         options.addOption("e", "eperson", true,
                 "email address of eperson doing importing");
         options
@@ -138,27 +169,34 @@
                         "install",
                         false,
                         "disable workflow; install immediately without going through collection's workflow");
+        options.addOption("r", "restore", false, "ingest in \"restore\" mode.  Restores a missing object based on the contents in a package.");
+        options.addOption("k", "keep-existing", false, "if an object is found to already exist during a restore (-r), then keep the existing object and continue processing.  Can only be used with '-r'.  This avoids object-exists errors which are thrown by -r by default.");
+        options.addOption("f", "force-replace", false, "if an object is found to already exist during a restore (-r), then remove it and replace it with the contents of the package.  Can only be used with '-r'.  This REPLACES the object(s) in the repository with the contents from the package(s).");
         options.addOption("t", "type", true, "package type or MIMEtype");
         options
                 .addOption("o", "option", true,
                         "Packager option to pass to plugin, \"name=value\" (repeatable)");
         options.addOption("d", "disseminate", false,
                 "Disseminate package (output); default is to submit.");
-        options.addOption("i", "item", true, "Handle of item to disseminate.");
+        options.addOption("s", "submit", false,
+                "Submission package (Input); this is the default. ");
+        options.addOption("i", "identifier", true, "Handle of object to disseminate.");
+        options.addOption("a", "all", false, "also recursively ingest/disseminate any child packages, e.g. all Items within a Collection (not all packagers may support this option!)");
         options.addOption("h", "help", false, "help");
+        options.addOption("u", "no-user-interaction", false, "Skips over all user interaction (i.e. [y/n] question prompts) within this script. This flag can be used if you want to save (pipe) a report of all changes to a file, and therefore need to bypass all user interaction.");
 
         CommandLineParser parser = new PosixParser();
         CommandLine line = parser.parse(options, argv);
 
         String sourceFile = null;
         String eperson = null;
-        String[] collections = null;
-        boolean useWorkflow = true;
-        String packageType = null;
-        boolean submit = true;
-        String itemHandle = null;
+        String[] parents = null;
+        String identifier = null;
         PackageParameters pkgParams = new PackageParameters();
 
+        //initialize a new packager -- we'll add all our current params as settings
+        Packager myPackager = new Packager();
+
         if (line.hasOption('h'))
         {
             HelpFormatter myhelp = new HelpFormatter();
@@ -176,21 +214,38 @@
                 System.out.println("  " + pn[i]);
             System.exit(0);
         }
+
+        //look for flag to disable all user interaction
+        if(line.hasOption('u'))
+            myPackager.userInteractionEnabled = false;
         if (line.hasOption('w'))
-            useWorkflow = false;
+            pkgParams.setWorkflowEnabled(false);
+        if (line.hasOption('r'))
+            pkgParams.setRestoreModeEnabled(true);
+        //keep-existing is only valid in restoreMode (-r) -- otherwise ignore -k option.
+        if (line.hasOption('k') && pkgParams.restoreModeEnabled())
+            pkgParams.setKeepExistingModeEnabled(true);
+        //force-replace is only valid in restoreMode (-r) -- otherwise ignore -f option.
+        if (line.hasOption('f') && pkgParams.restoreModeEnabled())
+            pkgParams.setReplaceModeEnabled(true);
         if (line.hasOption('e'))
             eperson = line.getOptionValue('e');
-        if (line.hasOption('c'))
-            collections = line.getOptionValues('c');
+        if (line.hasOption('p'))
+            parents = line.getOptionValues('p');
         if (line.hasOption('t'))
-            packageType = line.getOptionValue('t');
+            myPackager.packageType = line.getOptionValue('t');
         if (line.hasOption('i'))
-            itemHandle = line.getOptionValue('i');
+            identifier = line.getOptionValue('i');
+        if (line.hasOption('a'))
+        {
+            //enable 'recursiveMode' param to packager implementations, in case it helps with packaging or ingestion process
+            pkgParams.setRecursiveModeEnabled(true);
+        }
         String files[] = line.getArgs();
         if (files.length > 0)
             sourceFile = files[0];
         if (line.hasOption('d'))
-            submit = false;
+            myPackager.submit = false;
         if (line.hasOption('o'))
         {
             String popt[] = line.getOptionValues('o');
@@ -209,8 +264,8 @@
         }
 
         // Sanity checks on arg list: required args
-        if (sourceFile == null || eperson == null || packageType == null
-                || (submit && collections == null))
+        // REQUIRED: sourceFile, ePerson (-e), packageType (-t)
+        if (sourceFile == null || eperson == null || myPackager.packageType == null)
         {
             System.err
                     .println("Error - missing a REQUIRED argument or option.\n");
@@ -228,102 +283,425 @@
             usageError("Error, eperson cannot be found: " + eperson);
         context.setCurrentUser(myEPerson);
 
-        if (submit)
+
+        //If we are in REPLACE mode
+        if(pkgParams.replaceModeEnabled())
         {
-            // make sure we have an input file
-            InputStream source = (sourceFile.equals("-")) ? System.in
-                    : new FileInputStream(sourceFile);
-
             PackageIngester sip = (PackageIngester) PluginManager
-                    .getNamedPlugin(PackageIngester.class, packageType);
+                    .getNamedPlugin(PackageIngester.class, myPackager.packageType);
             if (sip == null)
-                usageError("Error, Unknown package type: " + packageType);
+                usageError("Error, Unknown package type: " + myPackager.packageType);
 
-            // find collections
-            Collection[] mycollections = null;
+            DSpaceObject objToReplace = null;
 
-            System.out.println("Destination collections:");
+            //if a specific identifier was specified, make sure it is valid
+            if(identifier!=null && identifier.length()>0)
+            {
+                objToReplace = HandleManager.resolveToObject(context, identifier);
+                if (objToReplace == null)
+                    throw new IllegalArgumentException("Bad identifier/handle -- "
+                            + "Cannot resolve handle \"" + identifier +"\"");
+            }
 
-            // validate each collection arg to see if it's a real collection
-            mycollections = new Collection[collections.length];
-            for (int i = 0; i < collections.length; i++)
+            String choiceString = null;
+            if(myPackager.userInteractionEnabled)
             {
-                // sanity check: did handle resolve, and to a collection?
-                DSpaceObject dso = HandleManager.resolveToObject(context,
-                        collections[i]);
-                if (dso == null)
-                    throw new IllegalArgumentException(
-                            "Bad collection list -- "
-                                    + "Cannot resolve collection handle \""
-                                    + collections[i] + "\"");
-                else if (dso.getType() != Constants.COLLECTION)
-                    throw new IllegalArgumentException(
-                            "Bad collection list -- " + "Object at handle \""
-                                    + collections[i]
-                                    + "\" is not a collection!");
-                mycollections[i] = (Collection) dso;
-                System.out.println((i == 0 ? "  Owning " : "  ")
-                        + " Collection: "
-                        + mycollections[i].getMetadata("name"));
+                BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
+                System.out.println("\n\nWARNING -- You are running the packager in REPLACE mode.");
+                System.out.println("\nREPLACE mode may be potentially dangerous as it will automatically remove and replace contents within DSpace.");
+                System.out.println("We highly recommend backing up all your DSpace contents (files & database) before continuing.");
+                System.out.print("\nWould you like to continue? [y/n]: ");
+                choiceString = input.readLine();
             }
+            else
+            {
+                //user interaction disabled -- default answer to 'yes', otherwise script won't continue
+                choiceString = "y";
+            }
 
-            try
+            if (choiceString.equalsIgnoreCase("y"))
             {
-                WorkspaceItem wi = sip.ingest(context, mycollections[0],
-                        source, pkgParams, null);
-                if (useWorkflow)
+                System.out.println("Beginning replacement process...");
+
+                try
                 {
-                    String handle = null;
+                    //replace the object from the source file
+                    myPackager.replace(context, sip, pkgParams, sourceFile, objToReplace);
 
-                    // Check if workflow completes immediately, and
-                    // return Handle if so.
-                    WorkflowItem wfi = WorkflowManager.startWithoutNotify(context, wi);
-
-                    if (wfi.getState() == WorkflowManager.WFSTATE_ARCHIVE)
-                    {
-                        Item ni = wfi.getItem();
-                        handle = HandleManager.findHandle(context, ni);
-                    }
-                    if (handle == null)
-                    System.out.println("Created Workflow item, ID="
-                                + String.valueOf(wfi.getID()));
-                    else
-                        System.out.println("Created and installed item, handle="+handle);
+                    //commit all changes & exit successfully
+                    context.complete();
+                    System.exit(0);
                 }
-                else
+                catch (Exception e)
                 {
-                    InstallItem.installItem(context, wi);
-                    System.out.println("Created and installed item, handle="
-                            + HandleManager.findHandle(context, wi.getItem()));
+                    // abort all operations
+                    e.printStackTrace();
+                    context.abort();
+                    System.out.println(e);
+                    System.exit(1);
                 }
+            }
+
+        }
+        //else if normal SUBMIT mode (or basic RESTORE mode -- which is a special type of submission)
+        else if (myPackager.submit || pkgParams.restoreModeEnabled())
+        {
+            PackageIngester sip = (PackageIngester) PluginManager
+                    .getNamedPlugin(PackageIngester.class, myPackager.packageType);
+            if (sip == null)
+                usageError("Error, Unknown package type: " + myPackager.packageType);
+
+            // validate each parent arg (if any)
+            DSpaceObject parentObjs[] = null;
+            if(parents!=null)
+            {
+                System.out.println("Destination parents:");
+
+                parentObjs = new DSpaceObject[parents.length];
+                for (int i = 0; i < parents.length; i++)
+                {
+                    // sanity check: did handle resolve?
+                    parentObjs[i] = HandleManager.resolveToObject(context,
+                            parents[i]);
+                    if (parentObjs[i] == null)
+                        throw new IllegalArgumentException(
+                                "Bad parent list -- "
+                                        + "Cannot resolve parent handle \""
+                                        + parents[i] + "\"");
+                    System.out.println((i == 0 ? "Owner: " : "Parent: ")
+                            + parentObjs[i].getHandle());
+                }
+            }
+
+            try
+            {
+                //ingest the object from the source file
+                myPackager.ingest(context, sip, pkgParams, sourceFile, parentObjs);
+
+                //commit all changes & exit successfully
                 context.complete();
                 System.exit(0);
             }
             catch (Exception e)
             {
                 // abort all operations
+                e.printStackTrace();
                 context.abort();
-                e.printStackTrace();
                 System.out.println(e);
                 System.exit(1);
             }
-        }
+        }// else, if DISSEMINATE mode
         else
         {
-            OutputStream dest = (sourceFile.equals("-")) ? (OutputStream) System.out
-                    : (OutputStream) (new FileOutputStream(sourceFile));
-
+            //retrieve specified package disseminator
             PackageDisseminator dip = (PackageDisseminator) PluginManager
-                    .getNamedPlugin(PackageDisseminator.class, packageType);
+                .getNamedPlugin(PackageDisseminator.class, myPackager.packageType);
             if (dip == null)
-                usageError("Error, Unknown package type: " + packageType);
+                usageError("Error, Unknown package type: " + myPackager.packageType);
 
-            DSpaceObject dso = HandleManager.resolveToObject(context,
-                    itemHandle);
+            DSpaceObject dso = HandleManager.resolveToObject(context, identifier);
             if (dso == null)
-                throw new IllegalArgumentException("Bad Item handle -- "
-                        + "Cannot resolve handle \"" + itemHandle);
-            dip.disseminate(context, dso, pkgParams, dest);
+                throw new IllegalArgumentException("Bad identifier/handle -- "
+                        + "Cannot resolve handle \"" + identifier +"\"");
+
+            //disseminate the requested object
+            myPackager.disseminate(context, dip, dso, pkgParams, sourceFile);
         }
+        System.exit(0);
     }
+
+    /**
+     * Ingest one or more DSpace objects from package(s) based on the
+     * options passed to the 'packager' script.  This method is called
+     * for both 'submit' (-s) and 'restore' (-r) modes.
+     * 

+ * Please note that replace (-r -f) mode calls the replace() method instead. + * + * @param context DSpace Context + * @param sip PackageIngester which will actually ingest the package + * @param pkgParams Parameters to pass to individual packager instances + * @param sourceFile location of the source package to ingest + * @param parentObjs Parent DSpace object(s) to attach new object to + * @throws IOException + * @throws SQLException + * @throws FileNotFoundException + * @throws AuthorizeException + * @throws CrosswalkException + * @throws PackageException + */ + protected void ingest(Context context, PackageIngester sip, PackageParameters pkgParams, String sourceFile, DSpaceObject parentObjs[]) + throws IOException, SQLException, FileNotFoundException, AuthorizeException, CrosswalkException, PackageException + { + // make sure we have an input file + File pkgFile = new File(sourceFile); + + if(!pkgFile.exists()) + { + System.out.println("\nERROR: Package located at " + sourceFile + " does not exist!"); + System.exit(1); + } + + System.out.println("\nIngesting package located at " + sourceFile); + + //find first parent (if specified) -- this will be the "owner" of the object + DSpaceObject parent = null; + if(parentObjs!=null && parentObjs.length>0) + parent = parentObjs[0]; + //NOTE: at this point, Parent may be null -- in which case it is up to the PackageIngester + // to either determine the Parent (from package contents) or throw an error. + + + //If we are doing a recursive ingest, call ingestAll() + if(pkgParams.recursiveModeEnabled()) + { + System.out.println("\nAlso ingesting all referenced packages (recursive mode).."); + System.out.println("This may take a while, please check your logs for ongoing status while we process each package."); + + //ingest first package & recursively ingest anything else that package references (child packages, etc) + List dsoResults = sip.ingestAll(context, parent, pkgFile, pkgParams, null); + + if(dsoResults!=null) + { + //Report total objects created + System.out.println("\nCREATED a total of " + dsoResults.size() + " DSpace Objects."); + + String choiceString = null; + //Ask if user wants full list printed to command line, as this may be rather long. + if(this.userInteractionEnabled) + { + BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("\nWould you like to view a list of all objects that were created? [y/n]: "); + choiceString = input.readLine(); + } + else + { + // user interaction disabled -- default answer to 'yes', as + // we want to provide user with as detailed a report as possible. + choiceString = "y"; + } + + // Provide detailed report if user answered 'yes' + if (choiceString.equalsIgnoreCase("y")) + { + System.out.println("\n\n"); + for(DSpaceObject result : dsoResults) + { + if(pkgParams.restoreModeEnabled()) + System.out.println("RESTORED DSpace " + Constants.typeText[result.getType()] + + " [ hdl=" + result.getHandle() + " ] "); + else + System.out.println("CREATED new DSpace " + Constants.typeText[result.getType()] + + " [ hdl=" + result.getHandle() + " ] "); + } + } + + } + } + else + { + + //otherwise, just one package to ingest + try + { + + DSpaceObject dso = sip.ingest(context, parent, pkgFile, pkgParams, null); + + if(dso!=null) + { + if(pkgParams.restoreModeEnabled()) + System.out.println("RESTORED DSpace " + Constants.typeText[dso.getType()] + + " [ hdl=" + dso.getHandle() + " ] "); + else + System.out.println("CREATED new DSpace " + Constants.typeText[dso.getType()] + + " [ hdl=" + dso.getHandle() + " ] "); + } + } + catch(IllegalStateException ie) + { + // NOTE: if we encounter an IllegalStateException, this means the + // handle is already in use and this object already exists. + + //if we are skipping over (i.e. keeping) existing objects + if(pkgParams.keepExistingModeEnabled()) + { + System.out.println("\nSKIPPED processing package '" + pkgFile + "', as an Object already exists with this handle."); + } + else // Pass this exception on -- which essentially causes a full rollback of all changes (this is the default) + throw ie; + } + + } + + } + + + /** + * Disseminate one or more DSpace objects into package(s) based on the + * options passed to the 'packager' script + * + * @param context DSpace context + * @param dip PackageDisseminator which will actually create the package + * @param dso DSpace Object to disseminate as a package + * @param pkgParams Parameters to pass to individual packager instances + * @param outputFile File where final package should be saved + * @param identifier identifier of main DSpace object to disseminate + * @throws IOException + * @throws SQLException + * @throws FileNotFoundException + * @throws AuthorizeException + * @throws CrosswalkException + * @throws PackageException + */ + protected void disseminate(Context context, PackageDisseminator dip, DSpaceObject dso, PackageParameters pkgParams, String outputFile) + throws IOException, SQLException, FileNotFoundException, AuthorizeException, CrosswalkException, PackageException + { + // initialize output file + File pkgFile = new File(outputFile); + + System.out.println("\nDisseminating DSpace " + Constants.typeText[dso.getType()] + + " [ hdl=" + dso.getHandle() + " ] to " + outputFile); + + //If we are doing a recursive dissemination of this object & all its child objects, call disseminateAll() + if(pkgParams.recursiveModeEnabled()) + { + System.out.println("\nAlso disseminating all child objects (recursive mode).."); + System.out.println("This may take a while, please check your logs for ongoing status while we process each package."); + + //disseminate initial object & recursively disseminate all child objects as well + List fileResults = dip.disseminateAll(context, dso, pkgParams, pkgFile); + + if(fileResults!=null) + { + //Report total files created + System.out.println("\nCREATED a total of " + fileResults.size() + " dissemination package files."); + + String choiceString = null; + //Ask if user wants full list printed to command line, as this may be rather long. + if(this.userInteractionEnabled) + { + BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("\nWould you like to view a list of all files that were created? [y/n]: "); + choiceString = input.readLine(); + } + else + { + // user interaction disabled -- default answer to 'yes', as + // we want to provide user with as detailed a report as possible. + choiceString = "y"; + } + + // Provide detailed report if user answered 'yes' + if (choiceString.equalsIgnoreCase("y")) + { + System.out.println("\n\n"); + for(File result : fileResults) + { + System.out.println("CREATED package file: " + result.getCanonicalPath()); + } + } + } + } + else + { + //otherwise, just disseminate a single object to a single package file + dip.disseminate(context, dso, pkgParams, pkgFile); + + if(pkgFile!=null && pkgFile.exists()) + System.out.println("\nCREATED package file: " + pkgFile.getCanonicalPath()); + } + } + + + + /** + * Replace an one or more existing DSpace objects with the contents of + * specified package(s) based on the options passed to the 'packager' script. + * This method is only called for full replaces ('-r -f' options specified) + * + * @param context DSpace Context + * @param sip PackageIngester which will actually replace the object with the package + * @param pkgParams Parameters to pass to individual packager instances + * @param sourceFile location of the source package to ingest as the replacement + * @param objToReplace DSpace object to replace (may be null if it will be specified in the package itself) + * @throws IOException + * @throws SQLException + * @throws FileNotFoundException + * @throws AuthorizeException + * @throws CrosswalkException + * @throws PackageException + */ + protected void replace(Context context, PackageIngester sip, PackageParameters pkgParams, String sourceFile, DSpaceObject objToReplace) + throws IOException, SQLException, FileNotFoundException, AuthorizeException, CrosswalkException, PackageException + { + + // make sure we have an input file + File pkgFile = new File(sourceFile); + + if(!pkgFile.exists()) + { + System.out.println("\nPackage located at " + sourceFile + " does not exist!"); + System.exit(1); + } + + System.out.println("\nReplacing DSpace object(s) with package located at " + sourceFile); + if(objToReplace!=null) + { + System.out.println("Will replace existing DSpace " + Constants.typeText[objToReplace.getType()] + + " [ hdl=" + objToReplace.getHandle() + " ]"); + } + // NOTE: At this point, objToReplace may be null. If it is null, it is up to the PackageIngester + // to determine which Object needs to be replaced (based on the handle specified in the pkg, etc.) + + + //If we are doing a recursive replace, call replaceAll() + if(pkgParams.recursiveModeEnabled()) + { + //ingest first object using package & recursively replace anything else that package references (child objects, etc) + List dsoResults = sip.replaceAll(context, objToReplace, pkgFile, pkgParams); + + if(dsoResults!=null) + { + //Report total objects replaced + System.out.println("\nREPLACED a total of " + dsoResults.size() + " DSpace Objects."); + + String choiceString = null; + //Ask if user wants full list printed to command line, as this may be rather long. + if(this.userInteractionEnabled) + { + BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("\nWould you like to view a list of all objects that were replaced? [y/n]: "); + choiceString = input.readLine(); + } + else + { + // user interaction disabled -- default answer to 'yes', as + // we want to provide user with as detailed a report as possible. + choiceString = "y"; + } + + // Provide detailed report if user answered 'yes' + if (choiceString.equalsIgnoreCase("y")) + { + System.out.println("\n\n"); + for(DSpaceObject result : dsoResults) + { + System.out.println("REPLACED new DSpace " + Constants.typeText[result.getType()] + + " [ hdl=" + result.getHandle() + " ] "); + } + } + + + } + } + else + { + //otherwise, just one object to replace + DSpaceObject dso = sip.replace(context, objToReplace, pkgFile, pkgParams); + + if(dso!=null) + System.out.println("REPLACED DSpace " + Constants.typeText[dso.getType()] + + " [ hdl=" + dso.getHandle() + " ] "); + } + } + }