mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
AIP Backup/Restore : Adding ability to auto-restore missing Metadata Fields. By default, AIP ingester will now create metadata fields if they are not found in the current DSpace Metadata Field Registry (However, it will not create missing Metadata Schemas). This option is important for scenarios where you want to restore all AIPs to an *empty* DSpace install, and you had a few custom 'DC' fields previously. You may also disable this new option by passing "-o createMetadataFields=false" to the packager command. This change necessitated a very minor refactor to the 'AbstractMETSIngester.finishObject()' method -- it now needs access to the PackageParameters, in order to see whether 'createMetadataFields' flag is true/false. This new option also documented on wiki: https://wiki.duraspace.org/display/DSPACE/AipBackupRestore
git-svn-id: http://scm.dspace.org/svn/repo/dspace/trunk@5290 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
@@ -479,7 +479,7 @@ public abstract class AbstractMETSIngester
|
||||
|
||||
// Subclass hook for final checks and rearrangements
|
||||
// (this allows subclasses to do some final validation / changes as necessary)
|
||||
finishObject(context, dso);
|
||||
finishObject(context, dso, params);
|
||||
|
||||
// Update the object to make sure all changes are committed
|
||||
PackageUtils.updateDSpaceObject(dso);
|
||||
@@ -602,7 +602,7 @@ public abstract class AbstractMETSIngester
|
||||
|
||||
// Subclass hook for final checks and rearrangements
|
||||
// (this allows subclasses to do some final validation / changes as necessary)
|
||||
finishObject(context, dso);
|
||||
finishObject(context, dso, params);
|
||||
|
||||
// Update the object to make sure all changes are committed
|
||||
PackageUtils.updateDSpaceObject(dso);
|
||||
@@ -1247,8 +1247,11 @@ public abstract class AbstractMETSIngester
|
||||
* necessary.
|
||||
*
|
||||
* @param context the DSpace context
|
||||
* @param dso the DSpace Object
|
||||
* @param params the Packager Parameters
|
||||
*/
|
||||
abstract public void finishObject(Context context, DSpaceObject dso)
|
||||
abstract public void finishObject(Context context, DSpaceObject dso,
|
||||
PackageParameters params)
|
||||
throws PackageValidationException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException;
|
||||
|
||||
|
@@ -49,10 +49,15 @@ import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.NonUniqueMetadataException;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.content.crosswalk.MetadataValidationException;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Constants;
|
||||
|
||||
@@ -103,6 +108,7 @@ public class DSpaceAIPIngester
|
||||
/**
|
||||
* Ensure it's an AIP generated by the complementary AIP disseminator.
|
||||
*/
|
||||
@Override
|
||||
void checkManifest(METSManifest manifest)
|
||||
throws MetadataValidationException
|
||||
{
|
||||
@@ -124,6 +130,7 @@ public class DSpaceAIPIngester
|
||||
* same GROUPID<br>
|
||||
* 4. Crosswalk remaining DMDs not eliminated already.
|
||||
*/
|
||||
@Override
|
||||
public void crosswalkObjectDmd(Context context, DSpaceObject dso,
|
||||
METSManifest manifest,
|
||||
AbstractMETSIngester.MdrefManager callback,
|
||||
@@ -203,6 +210,7 @@ public class DSpaceAIPIngester
|
||||
* default deposit license.
|
||||
* Normally the rightsMD crosswalks should provide a license.
|
||||
*/
|
||||
@Override
|
||||
public void addLicense(Context context, Item item, String license,
|
||||
Collection collection, PackageParameters params)
|
||||
throws PackageValidationException,
|
||||
@@ -229,18 +237,39 @@ public class DSpaceAIPIngester
|
||||
}
|
||||
|
||||
/**
|
||||
* Last change to fix up a DSpace Object
|
||||
* Last change to fix up a DSpace Object.
|
||||
* <P>
|
||||
* For AIPs, if the object is an Item, we may want to make sure all of its
|
||||
* metadata fields already exist in the database (otherwise, the database
|
||||
* will throw errors when we attempt to save/update the Item)
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param dso DSpace object
|
||||
* @param params Packager Parameters
|
||||
*/
|
||||
public void finishObject(Context context, DSpaceObject dso)
|
||||
@Override
|
||||
public void finishObject(Context context, DSpaceObject dso, PackageParameters params)
|
||||
throws PackageValidationException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
// nothing to do.
|
||||
if(dso.getType()==Constants.ITEM)
|
||||
{
|
||||
// Check if 'createMetadataFields' option is enabled (default=true)
|
||||
// This defaults to true as by default we should attempt to restore as much metadata as we can.
|
||||
// When 'createMetadataFields' is set to false, an ingest will fail if it attempts to ingest content to a missing metadata field.
|
||||
if (params.getBooleanProperty("createMetadataFields", true))
|
||||
{
|
||||
// We want to verify that all the Metadata Fields we've crosswalked
|
||||
// actually *exist* in the DB. If not, we'll try to create them
|
||||
createMissingMetadataFields(context, (Item) dso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nothing extra to do to bitstream after ingestion.
|
||||
*/
|
||||
@Override
|
||||
public void finishBitstream(Context context,
|
||||
Bitstream bs,
|
||||
Element mfile,
|
||||
@@ -255,6 +284,7 @@ public class DSpaceAIPIngester
|
||||
* Return the type of DSpaceObject in this package; it is
|
||||
* in the TYPE attribute of the mets:mets element.
|
||||
*/
|
||||
@Override
|
||||
public int getObjectType(METSManifest manifest)
|
||||
throws PackageValidationException
|
||||
{
|
||||
@@ -273,9 +303,85 @@ public class DSpaceAIPIngester
|
||||
/**
|
||||
* Name used to distinguish DSpace Configuration entries for this subclass.
|
||||
*/
|
||||
@Override
|
||||
public String getConfigurationName()
|
||||
{
|
||||
return "dspaceAIP";
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all the unsaved, crosswalked metadata fields that have
|
||||
* been added to an Item actually exist in our Database. If they don't
|
||||
* exist, they are created within the proper database tables.
|
||||
* <P>
|
||||
* This method must be called *before* item.update(), as the call to update()
|
||||
* will throw a SQLException when attempting to save any fields which
|
||||
* don't already exist in the database.
|
||||
* <P>
|
||||
* NOTE: This will NOT create a missing Metadata Schema (e.g. "dc" schema),
|
||||
* as we do not have enough info to create schemas on the fly.
|
||||
*
|
||||
* @param context - DSpace Context
|
||||
* @param item - Item whose unsaved metadata fields we are testing
|
||||
* @throws AuthorizeException if a metadata field doesn't exist and current user is not authorized to create it (i.e. not an Admin)
|
||||
* @throws PackageValidationException if a metadata schema doesn't exist, as we cannot autocreate a schema
|
||||
*/
|
||||
protected static void createMissingMetadataFields(Context context, Item item)
|
||||
throws PackageValidationException, AuthorizeException, IOException, SQLException
|
||||
{
|
||||
// Get all metadata fields/values currently added to this Item
|
||||
DCValue allMD[] = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||
|
||||
// For each field, we'll check if it exists. If not, we'll create it.
|
||||
for(DCValue md : allMD)
|
||||
{
|
||||
MetadataSchema mdSchema = null;
|
||||
MetadataField mdField = null;
|
||||
try
|
||||
{
|
||||
//Try to access this Schema
|
||||
mdSchema = MetadataSchema.find(context, md.schema);
|
||||
//If Schema found, try to locate field from database
|
||||
if(mdSchema!=null)
|
||||
{
|
||||
mdField = MetadataField.findByElement(context, mdSchema.getSchemaID(), md.element, md.qualifier);
|
||||
}
|
||||
}
|
||||
catch(SQLException se)
|
||||
{
|
||||
//If a SQLException error is thrown, then this field does NOT exist in DB
|
||||
//Set field to null, so we know we need to create it
|
||||
mdField = null;
|
||||
}
|
||||
|
||||
// If our Schema was not found, we have a problem
|
||||
// We cannot easily create a Schema automatically -- as we don't know its Namespace
|
||||
if(mdSchema==null)
|
||||
{
|
||||
throw new PackageValidationException("Unknown Metadata Schema encountered (" + md.schema + ") when attempting to ingest an Item. You will need to create this Metadata Schema in DSpace Schema Registry before the Item can be ingested.");
|
||||
}
|
||||
|
||||
// If our Metadata Field is null, we will attempt to create it in the proper Schema
|
||||
if(mdField==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//initialize field (but don't set a scope note) & create it
|
||||
mdField = new MetadataField(mdSchema, md.element, md.qualifier, null);
|
||||
// NOTE: Only Adminstrators can create Metadata Fields -- create() will throw an AuthorizationException for non-Admins
|
||||
mdField.create(context);
|
||||
//log that field was created
|
||||
log.info("Located a missing metadata field (schema:'" + mdSchema.getName() +"', element:'"+ md.element +"', qualifier:'"+ md.qualifier +"') while ingesting Item. This missing field has been created in the DSpace Metadata Field Registry.");
|
||||
}
|
||||
catch(NonUniqueMetadataException ne)
|
||||
{ // This exception should never happen, as we already checked to make sure the field doesn't exist.
|
||||
// But, we'll catch it anyways so that the Java compiler doesn't get upset
|
||||
throw new SQLException("Unable to create Metadata Field (element='" + md.element + "', qualifier='" + md.qualifier + "') in Schema "+ mdSchema.getName() +".", ne);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -188,7 +188,8 @@ public class DSpaceMETSIngester
|
||||
PackageUtils.addDepositLicense(context, license, item, collection);
|
||||
}
|
||||
|
||||
public void finishObject(Context context, DSpaceObject dso)
|
||||
public void finishObject(Context context, DSpaceObject dso,
|
||||
PackageParameters params)
|
||||
throws PackageValidationException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
|
Reference in New Issue
Block a user