Simpliefied code of DOIIdentifierProvider. Enhanced Exception handling.

This commit is contained in:
Pascal-Nicolas Becker
2013-09-06 18:59:48 +02:00
parent 66c99dfae0
commit 404bc1c6bf
2 changed files with 287 additions and 329 deletions

View File

@@ -18,6 +18,7 @@ import org.dspace.content.FormatIdentifier;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.identifier.doi.DOIConnector;
import org.dspace.identifier.doi.DOIIdentifierException;
import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow;
import org.slf4j.Logger;
@@ -41,6 +42,20 @@ public class DOIIdentifierProvider
extends IdentifierProvider
{
private static final Logger log = LoggerFactory.getLogger(DOIIdentifierProvider.class);
/**
* A DOIConnector connects the DOIIdentifierProvider to the API of the DOI
* registration agency needed to register DOIs. To register DOIs we have to
* care about two APIs: the <link>IdentifierProvider</link> API of DSpace
* and the API of the DOI registration agency. The DOIIdentifierProvider
* manages the DOI database table, generates new DOIs, stores them as
* metadata in DSpace items and so on. To register DOIs at DOI registration
* agencies it uses a DOIConnector. A DOI connector has to register and
* reserve DOIs using the API of the DOI registration agency. If requested
* by the registration agency it has to convert and send metadata of the
* DSpace items.
*/
private DOIConnector connector;
static final String CFG_PREFIX = "identifier.doi.prefix";
static final String CFG_NAMESPACE_SEPARATOR = "identifier.doi.namespaceseparator";
@@ -51,9 +66,6 @@ public class DOIIdentifierProvider
public static final String DOI_ELEMENT = "identifier";
public static final String DOI_QUALIFIER = null;
// How many times do we want to try to find a new unique DOI?
private static final int THRESHOLD_UNIQUE_DOI = 1000;
/**
* Prefix of DOI namespace. Set in dspace.cfg.
*/
@@ -61,7 +73,7 @@ public class DOIIdentifierProvider
/**
* Part of DOI to separate several applications that generate DOIs.
* E.g. it could be 'dspace/' if DOIs generated by DSpace should have the form
* E.g. it could be 'dspace/' if DOIs generated by DSpace should have the form
* prefix/dspace/uniqueString. Set it to the empty String if DSpace must
* generate DOIs directly after the DOI Prefix. Set in dspace.cfg.
*/
@@ -96,9 +108,6 @@ public class DOIIdentifierProvider
return this.NAMESPACE_SEPARATOR;
}
private DOIConnector connector;
@Required
public void setDOIConnector(DOIConnector connector)
{
@@ -132,10 +141,10 @@ public class DOIIdentifierProvider
{
try {
DOI.formatIdentifier(identifier);
} catch (IdentifierException e) {
} catch (IdentifierException e) {
return false;
}
return true;
return true;
}
@@ -155,56 +164,35 @@ public class DOIIdentifierProvider
throws IdentifierException
{
String doi = DOI.formatIdentifier(identifier);
TableRow doiRow = null;
String status;
if (null != doi) {
try {
// get DOI object from Database
// remove DOI.SCHEME before searching in DB.
doiRow = DatabaseManager.findByUnique(context, "Doi",
"doi", doi.substring(DOI.SCHEME.length()));
if (null == doiRow) {
try {
createNewIdentifier(context, dso, doi);
}
catch (Exception e)
{
// TODO: better exception handling
throw new RuntimeException(e);
}
log.warn("Trying to register DOI {}, that not exist in DB.", doi);
} else {
if (doiRow.getIntColumn("resource_id") != dso.getID()
|| doiRow.getIntColumn("resource_type_id") != dso.getType()) {
throw new IdentifierException("Trying to reserve a DOI "
+ "that is reserved for another object.");
}
if ("isRegistered".equals(doiRow.getStringColumn("status")))
{
return;
}
doiRow.setColumn("status", "toBeRegistered");
DatabaseManager.update(context, doiRow);
}
} catch (SQLException ex) {
log.error("Error while trying to change doi status "
+ dso.getTypeText() + " with ID " + dso.getID() + ".");
throw new RuntimeException("Error while while trying to change doi status "
+ "for a DOI " + dso.getTypeText()
+ " with ID " + dso.getID() + ".", ex);
}
// search DOI in our db
try
{
doiRow = loadOrCreateDOI(context, dso, doi);
} catch (SQLException ex) {
log.error("Error in databse connection: " + ex.getMessage());
throw new RuntimeException("Error in database conncetion.", ex);
}
// Check status of DOI
if ("isRegistered".equals(doiRow.getStringColumn("status")))
{
return;
}
// change status of DOI
doiRow.setColumn("status", "toBeRegistered");
try {
DatabaseManager.update(context, doiRow);
}
catch (SQLException sqle)
{
log.warn("SQLException while changing status of DOI {} to be registered.", doi);
throw new RuntimeException(sqle);
}
// safe DOI as metadata of the item
try {
saveDOIToObject(context, dso, doi);
}
@@ -212,9 +200,9 @@ public class DOIIdentifierProvider
{
throw new IdentifierException("Not authorized to save a DOI as metadata of an dso!", ae);
}
catch (SQLException e)
catch (SQLException sqle)
{
throw new RuntimeException(e);
throw new RuntimeException(sqle);
}
}
@@ -236,158 +224,145 @@ public class DOIIdentifierProvider
@Override
public void reserve(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException
{
this.reserveDOI(context, dso, identifier);
}
private void reserveDOI(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException
{
String doi = DOI.formatIdentifier(identifier);
TableRow doiRow = null;
// ensure that the DOI is in our DOI table and is not reserved online
// for another object than dso
try {
createNewIdentifier(context, dso, doi);
doiRow = DatabaseManager.findByUnique(context, "Doi",
"doi", doi.substring(DOI.SCHEME.length()));
if (null == doiRow) {
log.warn("Trying to reserve DOI {}, that not exist in DB.", doi);
throw new IdentifierException("Trying to reserve a DOI "
+ "that not exist in DB.");
} else {
if (doiRow.getIntColumn("resource_id") != dso.getID()
|| doiRow.getIntColumn("resource_type_id") != dso.getType()) {
throw new IdentifierException("Trying to reserve a DOI "
+ "that is reserved for another object.");
}
if (!doiRow.isColumnNull("status")) {
return;
}
doiRow.setColumn("status", "toBeReserved");
DatabaseManager.update(context, doiRow);
}
} catch (IllegalArgumentException ex) {
throw new IdentifierException("DOI is reserved for another object.");
} catch (SQLException ex) {
throw new RuntimeException("Error in database connection: " + ex.getMessage());
// if the doi is in our db already loadOrCreateDOI just returns.
// if it is not loadOrCreateDOI safes the doi.
doiRow = loadOrCreateDOI(context, dso, doi);
}
catch (SQLException sqle)
{
throw new RuntimeException(sqle);
}
if (!doiRow.isColumnNull("status")) {
return;
}
doiRow.setColumn("status", "toBeReserved");
try
{
DatabaseManager.update(context, doiRow);
}
catch (SQLException sqle)
{
throw new RuntimeException(sqle);
}
}
public void reserveDOIOnline(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException, SQLException {
public void reserveOnline(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException, SQLException
{
String doi = DOI.formatIdentifier(identifier);
// ensure that the DOI is in our DOI table and is not reserved online
// for another object than dso
try {
createNewIdentifier(context, dso, doi);
} catch (IllegalArgumentException ex) {
throw new IdentifierException("DOI is reserved for another object.");
} catch (SQLException ex) {
throw new RuntimeException("Error in database connection: " + ex.getMessage());
}
// check if DOI is reserved at the registration agency for the specific dso
if (connector.isDOIReserved(context, dso, doi)) {
// TODO: Send metadata update anyway!
return;
}
// check if doi is already reserved for another object
if (connector.isDOIReserved(context, doi)) {
log.warn("Trying to reserve a DOI {} that is reserved for "
+ "another object.", doi);
throw new IdentifierException("Trying to reserve a DOI "
+ "that is reserved for another object.");
}
// get TableRow and ensure DOI belongs to dso regarding our db
TableRow doiRow = loadOrCreateDOI(context, dso, doi);
// try to reserve the doi
if (!connector.reserveDOI(context, dso, doi)) {
throw new IdentifierException("It was impossible to reserve the DOI "
+ doi + ". Take a look into the logs for further details.");
// check if DOI is reserved at the registration agency
if (connector.isDOIReserved(context, doi))
{
// if doi is registered for this object we still should check its
// status in our database (see below).
// if it is registered for another object we should notify an admin
if (!connector.isDOIReserved(context, dso, doi))
{
log.warn("DOI {} is reserved for another object already.", doi);
throw new DOIIdentifierException(DOIIdentifierException.DOI_ALREADY_EXISTS);
}
}
else
{
TableRow doiRow = DatabaseManager.findByUnique(context, "Doi",
"doi", doi.substring(DOI.SCHEME.length()));
doiRow.setColumn("status", "isReserved");
try {
DatabaseManager.update(context, doiRow);
} catch (SQLException se) { ///muss ich sehenn
System.err.println("Caught SQLException: " + se.getMessage());
se.printStackTrace(System.err);
throw se;
}
connector.reserveDOI(context, dso, doi);
}
doiRow.setColumn("status", "isReserved");
DatabaseManager.update(context, doiRow);
}
public void registeredDOIOnline(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException, SQLException {
public void registereOnline(Context context, DSpaceObject dso, String identifier)
throws IdentifierException, IllegalArgumentException, SQLException
{
String doi = DOI.formatIdentifier(identifier);
// check if the DOI is already registered for this dso
if (connector.isDOIRegistered(context, dso, doi))
// get TableRow and ensure DOI belongs to dso regarding our db
TableRow doiRow = loadOrCreateDOI(context, dso, doi);
// check if the DOI is already registered online
if (connector.isDOIRegistered(context, doi))
{
return;
}
// check if DOI is registered for another object
if (connector.isDOIRegistered(context, doi)) {
log.warn("Trying to register DOI {}, that is already registered.", doi);
throw new IdentifierException("Trying to register a DOI that is "
+ "registered for another object.");
}
// check if doi is reserved for this specific dso
if (!connector.isDOIReserved(context, dso, doi)) {
// check if doi is already reserved for another dso
if (connector.isDOIReserved(context, doi)) {
log.warn("Trying to register DOI {}, that is reserved for "
+ "another dso.", doi);
throw new IdentifierException("Trying to register a DOI "
+ "that is reserved for another object.");
// if doi is registered for this object we still should check its
// status in our database (see below).
// if it is registered for another object we should notify an admin
if (!connector.isDOIRegistered(context, dso, doi))
{
// DOI is reserved for another object
log.warn("DOI {} is registered for another object already.", doi);
throw new DOIIdentifierException(DOIIdentifierException.DOI_ALREADY_EXISTS);
}
if (!connector.reserveDOI(context, dso, doi)) {
throw new IdentifierException("It was impossible to reserve the DOI "
+ doi + ". Take a look into the logs for further details.");
}
else
{
// register DOI Online
try {
connector.registerDOI(context, dso, doi);
}
catch (DOIIdentifierException die)
{
// do we have to reserve DOI before we can register it?
if (die.getCode() == DOIIdentifierException.REGISTER_FIRST)
{
this.reserveOnline(context, dso, identifier);
connector.registerDOI(context, dso, doi);
}
else
{
throw die;
}
}
}
if (!connector.registerDOI(context, dso, doi)) {
throw new IdentifierException("It was impossible to register the DOI "
+ doi + ". Take a look into the logs for further details.");
} else {
TableRow doiRow = DatabaseManager.findByUnique(context, "Doi",
"doi", doi.substring(DOI.SCHEME.length()));
doiRow.setColumn("status", "isRegistered");
DatabaseManager.update(context, doiRow);
doiRow.setColumn("status", "isRegistered");
DatabaseManager.update(context, doiRow);
}
public void updateMetadata(Context context, DSpaceObject dso, String identifier)
throws IdentifierException
{
String doi = DOI.formatIdentifier(identifier);
// ensure DOI belongs to dso regarding our db
TableRow doiRow = null;
try
{
doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi);
}
catch (SQLException sqle)
{
log.warn("SQLException while searching a DOI in our db.", sqle);
throw new RuntimeException("Unable to retrieve information about "+
"a DOI out of database.", sqle);
}
if (null == doiRow)
{
log.error("Cannot update metadata for DOI {}: unable to find it in "
+ "our db.", doi);
throw new DOIIdentifierException("Unable to find DOI.",
DOIIdentifierException.DOI_DOES_NOT_EXIST);
}
if (doiRow.getIntColumn("resource_id") != dso.getID() ||
doiRow.getIntColumn("resource_type_id") != dso.getType())
{
log.error("Refuse to update metadata of DOI {} with the metadata of "
+ " an object ({}/{}) the DOI is not dedicated to.",
new String[] {doi, dso.getTypeText(), Integer.toString(dso.getID())});
throw new DOIIdentifierException("Cannot update DOI metadata: "
+ "DOI and DSpaceObject does not match!",
DOIIdentifierException.MISMATCH);
}
connector.updateMetadata(context, dso, doi);
}
public void updateMetadata(Context context, DSpaceObject dso, String identifier )
throws IdentifierException
{
String doi = formatIdentifier(identifier);
if(connector.updateMetadata(context, dso, doi))
return;
throw new IdentifierException("it wasn't possible to update metadata for "
+ "the DOI" + identifier + ". Take a look into the logs"
+ " for further details.");
}
@Override
public String mint(Context context, DSpaceObject dso)
@@ -410,7 +385,9 @@ public class DOIIdentifierProvider
{
try
{
doi = createNewIdentifier(context, dso, null);
TableRow doiRow = loadOrCreateDOI(context, dso, null);
doi = DOI.SCHEME + doiRow.getStringColumn("doi");
}
catch (SQLException e)
{
@@ -432,16 +409,22 @@ public class DOIIdentifierProvider
try {
doi = DOI.formatIdentifier(identifier);
} catch (IdentifierException e) {
throw new IdentifierNotResolvableException(e.getMessage());
throw new IdentifierNotResolvableException(e);
}
try
{
return getObjectByDOI(context, doi);
DSpaceObject dso = getObjectByDOI(context, doi);
if (null == dso)
{
throw new IdentifierNotFoundException();
}
return dso;
}
catch (SQLException e)
catch (SQLException sqle)
{
log.error("SQLException while searching a DOI in our db.", sqle);
throw new RuntimeException("Unable to retrieve information about "+
"a DOI out of database.", e);
"a DOI out of database.", sqle);
}
catch (IdentifierException e)
{
@@ -464,8 +447,10 @@ public class DOIIdentifierProvider
}
if (null == doi)
{
throw new IdentifierNotFoundException("No DOI for DSpaceObject of type "
+ dso.getTypeText() + " with ID " + dso.getID() + " found.");
}
return doi;
}
@@ -481,8 +466,7 @@ public class DOIIdentifierProvider
catch (SQLException e)
{
log.error("Error while attemping to retrieve information about a DOI for "
+ dso.getTypeText() + " with ID " + dso.getID() + ".");
log.error(e.getMessage());
+ dso.getTypeText() + " with ID " + dso.getID() + ".", e);
throw new RuntimeException("Error while attempting to retrieve " +
"information about a DOI for " + dso.getTypeText() +
" with ID " + dso.getID() + ".", e);
@@ -490,7 +474,7 @@ public class DOIIdentifierProvider
if (doi == null)
{
// doi is not in DB. Is it in dso metadata?
doi = this.getDOIOutOfObject(dso);
doi = getDOIOutOfObject(dso);
}
if (doi != null)
{
@@ -502,27 +486,41 @@ public class DOIIdentifierProvider
public void delete(Context context, DSpaceObject dso, String identifier)
throws IdentifierException
{
deleteDOI(context, dso, identifier);
}
private void deleteDOI(Context context, DSpaceObject dso, String identifier)
throws IdentifierException
{
log.debug("delete {} from {}", identifier, dso);
String doi = DOI.formatIdentifier(identifier);
log.debug("formated identifier as {}", doi);
TableRow doiRow = null;
String oldStatus = null;
// look for doi in DB
// if it exists compare resource type and id
// if not okay throw exception
try
{
doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi);
}
catch (SQLException sqle)
{
throw new RuntimeException(sqle);
}
// check if DOI belongs to dso
if (null != doiRow)
{
if (doiRow.getIntColumn("resource_id") != dso.getID() ||
doiRow.getIntColumn("resource_type_id") != dso.getType())
{
throw new DOIIdentifierException("Trying to delete a DOI out of "
+ "an object that is not addressed by the DOI.",
DOIIdentifierException.MISMATCH);
}
}
// remove DOI from metadata
try
{
removeDOIFromObject(context, dso, doi);
}
catch (AuthorizeException ex)
{
log.error("Not authorized to delete a DOI out of an Item.");
throw new IdentifierException("Not authorized to delete DOI.", ex);
log.error("Not authorized to delete a DOI out of an Item.", ex);
throw new DOIIdentifierException("Not authorized to delete DOI.",
ex, DOIIdentifierException.UNAUTHORIZED_METADATA_MANIPULATION);
}
catch (SQLException ex)
{
@@ -532,64 +530,23 @@ public class DOIIdentifierProvider
"metadata of an Item " + dso.getID(), ex);
}
// DOIs are persistent identifier and should not be deleted at all.
// DataCite, for example, can mark a DOI as inactive and uses http delete
// method to do so.
// DOIConnector returns boolean, try to delete DOI:
if(!connector.deleteDOI(context, doi))
// change doi status in db if necessary.
if (null != doiRow)
{
// It was not possible to delete a DOI at the registry agency. We
// already removed the DOI out of the object's metadata,
// so we should restore this information.
try
{
saveDOIToObject(context, dso, doi);
}
catch (AuthorizeException e)
{
log.error("We were authorized to delete a DOI out of an Item, " +
"but we can't restore these informations?!");
log.error("DSO-Type: " + dso.getTypeText() + ", ID: " +
dso.getID() + ", DOI: " + doi + ".");
throw new IllegalStateException("We were authorized to delete " +
"a DOI out of an Item, but we can't restore these informations?!", e);
}
catch (SQLException ex)
{
log.error("SQLError while restoring DOI " + doi +
" for Object of Type " + dso.getTypeText() + " with ID "
+ dso.getID() + ".");
log.error("Exception message: " + ex.getMessage());
throw new RuntimeException("Error while restoring a DOI as " +
"metadata of an Item " + dso.getID(), ex);
}
throw new IdentifierException("Unable to delete DOI " + doi +
". Take a look into the logs for further details.");
}
// last thing to do is to delete the relation between DOI and item
try{
TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi);
if (doiRow != null)
{
// Set ressource_id and type_id to null. In opposition to
// HandleIdentifierProvider we don't want to reuse DOIs at all!
doiRow.setColumnNull("resource_id");
doiRow.setColumnNull("resource_type_id");
doiRow.setColumn("status", "deleted");
try {
DatabaseManager.update(context, doiRow);
}
else
catch (SQLException sqle)
{
log.warn("Cannot find entry for DOI " + doi +". Wanted to "
+ "the doi for object " + dso.getTypeText() + " id="
+ dso.getID());
log.warn("SQLException while changing status of DOI {} to be registered.", doi);
throw new RuntimeException(sqle);
}
}
catch(SQLException sqe)
{
throw new IdentifierException(sqe.getMessage(),sqe);
}
log.info("Deleted {}", doi);
}
// DOI is a permanent identifier. DataCite for example does not delete
// DOIS. But it is possible to mark a DOI as "inactive".
connector.deleteDOI(context, doi);
}
@@ -597,24 +554,29 @@ public class DOIIdentifierProvider
* Returns a DSpaceObject depending on its DOI.
* @param context the context
* @param identifier The DOI in a format that is accepted by
* {@link DOI.formatIdentifier(String)}.
* {@link formatIdentifier(String)}.
* @return Null if the DOI couldn't be found or the associated DSpaceObject.
* @throws SQLException
* @throws IdentifierException If {@code identifier} is null or an empty string.
* @throws IllegalArgumentException If the identifier couldn't be recognized as DOI.
*/
public static DSpaceObject getObjectByDOI(Context context, String identifier)
throws SQLException, IdentifierException, IllegalArgumentException
throws SQLException, DOIIdentifierException, IllegalArgumentException
{
String doi = DOI.formatIdentifier(identifier);
TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi);
TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", "doi",
doi.substring(DOI.SCHEME.length()));
if (null == doiRow)
{
return null;
}
if (doiRow.isColumnNull("resource_type_id") ||
doiRow.isColumnNull("resource_id"))
{
log.error("Found DOI " + doi +
" in database, but no assigned Object could be found.");
throw new IllegalStateException("Found DOI " + doi +
" in database, but no assigned Object could be found.");
}
@@ -641,7 +603,9 @@ public class DOIIdentifierProvider
TableRow doiRow = DatabaseManager.querySingleTable(context,
"Doi", sql, dso.getType(), dso.getID());
if (null == doiRow)
{
return null;
}
if (doiRow.isColumnNull("doi"))
{
@@ -656,118 +620,105 @@ public class DOIIdentifierProvider
}
/**
* Creates a new DOI and saves it to the database.
* Load a DOI from the database or creates it if it does not exist. This
* method can be used to ensure that a DOI exists in the database and to
* load the appropriate TableRow. As protected method we don't check if the
* DOI is in a decent format, use DOI.formatIdentifier(String) if necessary.
*
* @param context
* @param dso The DSpaceObject the DOI should be created for.
* @param doi A DOI or null if DOI should be generated.
* @return The generated DOI or {@code doi} if it was saved to the database.
* @param dso The DSpaceObject the DOI should be loaded or created for.
* @param doi A DOI or null if a DOI should be generated. The generated DOI
* can be found in the appropriate column for the TableRow.
* @return The database row of the object.
* @throws SQLException In case of an error using the database.
* @throws IllegalArgumentException If the given DOI already exists for an other object.
* @throws IdentifierException If {@code doi} is not part of our prefix or
* the doi registry assumes that the DOI belongs
* to another party.
* @throws DOIIdentifierException If {@code doi} is not part of our prefix or
* DOI is registered for another object already.
*/
protected String createNewIdentifier(Context context, DSpaceObject dso, String doi)
throws SQLException, IllegalArgumentException, IdentifierException
protected TableRow loadOrCreateDOI(Context context, DSpaceObject dso, String doi)
throws SQLException, DOIIdentifierException
{
TableRow doiRow = null;
if (null != doi)
{
// we expect DOIs to have the DOI-Scheme except inside the doi table:
doi = doi.substring(DOI.SCHEME.length());
// check if DOI is already in Database
// remove DOI.SCHEME before searching in DB.
doiRow = DatabaseManager.findByUnique(context, "Doi",
"doi", doi.substring(DOI.SCHEME.length()));
doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi);
if (null != doiRow)
{
// check if DOI already belongs to dso
if (doiRow.getIntColumn("resource_id") == dso.getID() &&
doiRow.getIntColumn("resource_type_id") == dso.getType())
{
return doi;
return doiRow;
}
else
{
throw new IllegalArgumentException("Trying to save a DOI " +
"that is already reserved for another object.");
throw new DOIIdentifierException("Trying to create a DOI " +
"that is already reserved for another object.",
DOIIdentifierException.DOI_ALREADY_EXISTS);
}
}
else
{
// doi is not null but was not found in db
// check if it is reserved online for another object
if (!connector.isDOIReserved(context, dso, doi) &&
connector.isDOIReserved(context, doi))
{
throw new IdentifierException("Trying to save a DOI " +
"that is already reserved for another object.");
}
// safe it to db (see below after end of if-else-statement)
}
}
doiRow = DatabaseManager.create(context, "Doi");
if (null != doi)
{
doi = doi.substring(DOI.SCHEME.length());
// check prefix
if (!doi.startsWith(this.getPrefix() + "/"))
throw new IdentifierException("Trying to create a DOI " +
"that's not part of our Namespace!");
{
throw new DOIIdentifierException("Trying to create a DOI " +
"that's not part of our Namespace!",
DOIIdentifierException.FOREIGN_DOI);
}
// prepare new doiRow
doiRow = DatabaseManager.create(context, "Doi");
}
else
{
// We need to generate a new DOI.
// We can register a DOI that was not minted, so we can have DOIs
// that have not the suffix of the doi_id column.
// Generate a new doi_id and check if we already have a DOI with the
// same suffix. Try max. THRESHOLD_UNIQUE_DOI times.
int i = 0;
for ( ; i < THRESHOLD_UNIQUE_DOI ; ++i)
{
doi = this.getPrefix() + "/" + this.getNamespaceSeparator() +
doiRow = DatabaseManager.create(context, "Doi");
doi = this.getPrefix() + "/" + this.getNamespaceSeparator() +
doiRow.getIntColumn("doi_id");
if (null == DatabaseManager.findByUnique(context, "Doi", "doi", doi))
{
break;
}
doiRow = DatabaseManager.create(context, "Doi");
}
if (null != DatabaseManager.findByUnique(context, "Doi", "doi", doi))
{
// We were unable to find a new DOI that does noch already exist.
// TODO: throw usefull Exception
throw new RuntimeException();
}
}
doiRow.setColumn("doi", doi);
doiRow.setColumn("resource_type_id", dso.getType());
doiRow.setColumn("resource_id", dso.getID());
doiRow.setColumnNull("status");
DatabaseManager.update(context, doiRow);
if (0 == DatabaseManager.update(context, doiRow))
{
throw new RuntimeException("Cannot save DOI to databse for unkown reason.");
}
return DOI.SCHEME + doi;
return doiRow;
}
/**
* Loads a DOI out of the metadata of an DSpaceObject.
* @param dso
* @return The DOI or null if no DOI was found.
*/
public static String getDOIOutOfObject(DSpaceObject dso) {
// FIXME
if (!(dso instanceof Item))
throw new IllegalArgumentException("Unsupported type " + dso.getTypeText());
{
throw new IllegalArgumentException("We currently support DOIs for "
+ "Items only, not for " + dso.getTypeText() + ".");
}
Item item = (Item)dso;
DCValue[] metadata = item.getMetadata(MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
for (DCValue id : metadata)
{
if (!id.value.startsWith(DOI.SCHEME))
if (id.value.startsWith(DOI.SCHEME))
{
return id.value;
}
}
return null;
}
/**
* Adds a DOI to the Metadata of an item.
* Adds a DOI to the metadata of an item.
*
* @param context
* @param dso DSpaceObject the DOI should be added to.
@@ -780,9 +731,12 @@ public class DOIIdentifierProvider
{
// FIXME
if (!(dso instanceof Item))
throw new IllegalArgumentException("Unsupported type " + dso.getTypeText());
{
throw new IllegalArgumentException("We currently support DOIs for "
+ "Items only, not for " + dso.getTypeText() + ".");
}
Item item = (Item) dso;
item.addMetadata(MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null, doi);
try
{
@@ -810,8 +764,10 @@ public class DOIIdentifierProvider
{
// FIXME
if (!(dso instanceof Item))
throw new IllegalArgumentException("Unsupported type " + dso.getTypeText());
{
throw new IllegalArgumentException("We currently support DOIs for "
+ "Items only, not for " + dso.getTypeText() + ".");
}
Item item = (Item)dso;
DCValue[] metadata = item.getMetadata(MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
@@ -820,7 +776,9 @@ public class DOIIdentifierProvider
for (DCValue id : metadata)
{
if (!id.value.equals(doi))
{
remainder.add(id.value);
}
}
item.clearMetadata(MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);