DS-2701 Reformat code according to DSpace code conventions

This commit is contained in:
Andrea Schweer
2015-08-24 09:50:39 +12:00
parent 09270f922f
commit eb63f024f0
77 changed files with 10667 additions and 9247 deletions

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -18,24 +18,25 @@ import org.dspace.content.DSpaceObject;
*/
public abstract class ATOMCollectionGenerator
{
/** the sword service definition */
protected SWORDService swordService;
/** the sword service definition */
protected SWORDService swordService;
/**
* Create a new ATOM collection generator using the given sword service.
*
* @param service
*/
public ATOMCollectionGenerator(SWORDService service)
{
this.swordService = service;
}
/**
* Create a new ATOM collection generator using the given sword service.
*
* @param service
*/
public ATOMCollectionGenerator(SWORDService service)
{
this.swordService = service;
}
/**
* Build the ATOM Collection which represents the given DSpace Object.
*
* @param dso
* @throws DSpaceSWORDException
*/
public abstract Collection buildCollection(DSpaceObject dso) throws DSpaceSWORDException;
/**
* Build the ATOM Collection which represents the given DSpace Object.
*
* @param dso
* @throws DSpaceSWORDException
*/
public abstract Collection buildCollection(DSpaceObject dso)
throws DSpaceSWORDException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -28,246 +28,253 @@ import java.util.List;
*/
public class BitstreamEntryGenerator extends DSpaceATOMEntry
{
/** logger */
private static Logger log = Logger.getLogger(BitstreamEntryGenerator.class);
/** logger */
private static Logger log = Logger.getLogger(BitstreamEntryGenerator.class);
/**
* Create a new ATOM Entry generator which can provide a SWORD Entry for
* a bitstream
*
* @param service
*/
protected BitstreamEntryGenerator(SWORDService service)
{
super(service);
log.debug("Create new instance of BitstreamEntryGenerator");
}
/**
* Create a new ATOM Entry generator which can provide a SWORD Entry for
* a bitstream
*
* @param service
*/
protected BitstreamEntryGenerator(SWORDService service)
{
super(service);
log.debug("Create new instance of BitstreamEntryGenerator");
}
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories()
{
// do nothing
}
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories()
{
// do nothing
}
/**
* Set the content type that DSpace received.
*
*/
protected void addContentElement()
throws DSpaceSWORDException
{
try
{
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Set the content type that DSpace received.
*
*/
protected void addContentElement()
throws DSpaceSWORDException
{
try
{
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
return;
}
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
return;
}
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
BitstreamFormat bf = null;
try {
bf = this.bitstream.getFormat(swordService.getContext());
} catch (SQLException e) {
log.error("Exception caught: ", e);
throw new DSpaceSWORDException(e);
}
String format = "application/octet-stream";
if (bf != null)
{
format = bf.getMIMEType();
}
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
BitstreamFormat bf = null;
try
{
bf = this.bitstream.getFormat(swordService.getContext());
}
catch (SQLException e)
{
log.error("Exception caught: ", e);
throw new DSpaceSWORDException(e);
}
String format = "application/octet-stream";
if (bf != null)
{
format = bf.getMIMEType();
}
Content con = new Content();
con.setType(format);
con.setSource(bsurl);
entry.setContent(con);
Content con = new Content();
con.setType(format);
con.setSource(bsurl);
entry.setContent(con);
log.debug("Adding content element with url=" + bsurl);
}
catch (InvalidMediaTypeException e)
{
log.error("caught and swallowed exception: ", e);
// do nothing; we'll live without the content type declaration!
}
}
log.debug("Adding content element with url=" + bsurl);
}
catch (InvalidMediaTypeException e)
{
log.error("caught and swallowed exception: ", e);
// do nothing; we'll live without the content type declaration!
}
}
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
protected void addIdentifier()
throws DSpaceSWORDException
{
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
// just use the dspace url as the
// property
String cfg = ConfigurationManager.getProperty("dspace.url");
entry.setId(cfg);
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
protected void addIdentifier()
throws DSpaceSWORDException
{
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
// just use the dspace url as the
// property
String cfg = ConfigurationManager.getProperty("dspace.url");
entry.setId(cfg);
return;
}
return;
}
SWORDUrlManager urlManager = swordService.getUrlManager();
SWORDUrlManager urlManager = swordService.getUrlManager();
// for a bitstream, we just use the url for the bitstream
// as the identifier
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
entry.setId(bsurl);
log.debug("Added identifier for bitstream with url=" + bsurl);
return;
// for a bitstream, we just use the url for the bitstream
// as the identifier
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
entry.setId(bsurl);
log.debug("Added identifier for bitstream with url=" + bsurl);
return;
// FIXME: later on we will maybe have a workflow page supplied
// by the sword interface?
}
// FIXME: later on we will maybe have a workflow page supplied
// by the sword interface?
}
/**
* Add links associated with this item.
*
*/
protected void addLinks()
throws DSpaceSWORDException
{
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
return;
}
/**
* Add links associated with this item.
*
*/
protected void addLinks()
throws DSpaceSWORDException
{
// if this is a deposit which is no op we can't do anything here
if (this.deposit != null && this.deposit.isNoOp())
{
return;
}
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
BitstreamFormat bf;
try
{
bf = this.bitstream.getFormat(swordService.getContext());
}
catch (SQLException e)
{
log.error("Exception caught: ", e);
throw new DSpaceSWORDException(e);
}
String format = "application/octet-stream";
if (bf != null)
{
format = bf.getMIMEType();
}
String bsurl = urlManager.getBitstreamUrl(this.bitstream);
BitstreamFormat bf;
try {
bf = this.bitstream.getFormat(swordService.getContext());
} catch (SQLException e) {
log.error("Exception caught: ", e);
throw new DSpaceSWORDException(e);
}
String format = "application/octet-stream";
if (bf != null)
{
format = bf.getMIMEType();
}
Link link = new Link();
link.setType(format);
link.setHref(bsurl);
link.setRel("alternate");
entry.addLink(link);
Link link = new Link();
link.setType(format);
link.setHref(bsurl);
link.setRel("alternate");
entry.addLink(link);
log.debug("Added link entity to entry for url " + bsurl);
}
log.debug("Added link entity to entry for url " + bsurl);
}
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate()
{
// do nothing
}
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate()
{
// do nothing
}
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
protected void addRights()
throws DSpaceSWORDException
{
try
{
// work our way up to the item
List<BundleBitstream> bundle2bitstreams = this.bitstream
.getBundles();
if (bundle2bitstreams.isEmpty())
{
log.error("Found orphaned bitstream: " + bitstream.getID());
throw new DSpaceSWORDException("Orphaned bitstream discovered");
}
Bundle bundle = bundle2bitstreams.get(0).getBundle();
List<Item> items = bundle.getItems();
if (items.isEmpty())
{
log.error("Found orphaned bundle: " + bundle.getID());
throw new DSpaceSWORDException("Orphaned bundle discovered");
}
Item item = items.get(0);
// now get the licence out of the item
SWORDUrlManager urlManager = swordService.getUrlManager();
StringBuilder rightsString = new StringBuilder();
List<Bundle> lbundles = item.getBundles();
for (Bundle lbundle : lbundles)
{
if (!Constants.LICENSE_BUNDLE_NAME.equals(lbundle.getName()))
{
// skip non-license bundles
continue;
}
List<BundleBitstream> bss = lbundle.getBitstreams();
for (BundleBitstream b2b : bss)
{
Bitstream bs = b2b.getBitstream();
String url = urlManager.getBitstreamUrl(bs);
rightsString.append(url).append(" ");
}
}
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
protected void addRights()
throws DSpaceSWORDException
{
try
{
// work our way up to the item
List<BundleBitstream> bundle2bitstreams = this.bitstream.getBundles();
if (bundle2bitstreams.isEmpty())
{
log.error("Found orphaned bitstream: " + bitstream.getID());
throw new DSpaceSWORDException("Orphaned bitstream discovered");
}
Bundle bundle = bundle2bitstreams.get(0).getBundle();
List<Item> items = bundle.getItems();
if (items.isEmpty())
{
log.error("Found orphaned bundle: " + bundle.getID());
throw new DSpaceSWORDException("Orphaned bundle discovered");
}
Item item = items.get(0);
Rights rights = new Rights();
rights.setContent(rightsString.toString());
rights.setType(ContentType.TEXT);
entry.setRights(rights);
log.debug("Added rights entry to entity");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
}
// now get the licence out of the item
SWORDUrlManager urlManager = swordService.getUrlManager();
StringBuilder rightsString = new StringBuilder();
List<Bundle> lbundles = item.getBundles();
for (Bundle lbundle : lbundles) {
if (!Constants.LICENSE_BUNDLE_NAME.equals(lbundle.getName()))
{
// skip non-license bundles
continue;
}
List<BundleBitstream> bss = lbundle.getBitstreams();
for (BundleBitstream b2b : bss) {
Bitstream bs = b2b.getBitstream();
String url = urlManager.getBitstreamUrl(bs);
rightsString.append(url).append(" ");
}
}
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
protected void addSummary()
{
// do nothing
}
Rights rights = new Rights();
rights.setContent(rightsString.toString());
rights.setType(ContentType.TEXT);
entry.setRights(rights);
log.debug("Added rights entry to entity");
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
}
/**
* Add the title from the bibliographic metadata
*
*/
protected void addTitle()
{
Title title = new Title();
title.setContent(this.bitstream.getName());
title.setType(ContentType.TEXT);
entry.setTitle(title);
log.debug("Added title to entry");
}
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
protected void addSummary()
{
// do nothing
}
/**
* Add the title from the bibliographic metadata
*
*/
protected void addTitle()
{
Title title = new Title();
title.setContent(this.bitstream.getName());
title.setType(ContentType.TEXT);
entry.setTitle(title);
log.debug("Added title to entry");
}
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate()
{
// do nothing
}
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate()
{
// do nothing
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -24,111 +24,120 @@ import java.util.List;
*/
public class CollectionCollectionGenerator extends ATOMCollectionGenerator
{
/** logger */
private static Logger log = Logger.getLogger(CollectionCollectionGenerator.class);
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
/** logger */
private static Logger log = Logger
.getLogger(CollectionCollectionGenerator.class);
/**
* Construct an object taking the sword service instance an argument
* @param service
*/
public CollectionCollectionGenerator(SWORDService service)
{
super(service);
log.debug("Create new instance of CollectionCollectionGenerator");
}
protected CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
/**
* Build the collection for the given DSpaceObject. In this implementation,
* if the object is not a DSpace Collection, it will throw an exception.
* @param dso
* @throws DSpaceSWORDException
*/
public Collection buildCollection(DSpaceObject dso) throws DSpaceSWORDException
{
if (!(dso instanceof org.dspace.content.Collection))
{
log.error("buildCollection passed argument which is not of type Collection");
throw new DSpaceSWORDException("Incorrect ATOMCollectionGenerator instantiated");
}
/**
* Construct an object taking the sword service instance an argument
* @param service
*/
public CollectionCollectionGenerator(SWORDService service)
{
super(service);
log.debug("Create new instance of CollectionCollectionGenerator");
}
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Build the collection for the given DSpaceObject. In this implementation,
* if the object is not a DSpace Collection, it will throw an exception.
* @param dso
* @throws DSpaceSWORDException
*/
public Collection buildCollection(DSpaceObject dso)
throws DSpaceSWORDException
{
if (!(dso instanceof org.dspace.content.Collection))
{
log.error(
"buildCollection passed argument which is not of type Collection");
throw new DSpaceSWORDException(
"Incorrect ATOMCollectionGenerator instantiated");
}
org.dspace.content.Collection col = (org.dspace.content.Collection) dso;
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
Collection scol = new Collection();
org.dspace.content.Collection col = (org.dspace.content.Collection) dso;
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(col);
Collection scol = new Collection();
// collection title is just its name
String title = collectionService.getMetadata(col, "name");
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(col);
// the collection policy is the licence to which the collection adheres
String collectionPolicy = collectionService.getLicense(col);
// collection title is just its name
String title = collectionService.getMetadata(col, "name");
// FIXME: what is the treatment? Doesn't seem appropriate for DSpace
// String treatment = " ";
// the collection policy is the licence to which the collection adheres
String collectionPolicy = collectionService.getLicense(col);
// abstract is the short description of the collection
String dcAbstract = collectionService.getMetadata(col, "short_description");
// FIXME: what is the treatment? Doesn't seem appropriate for DSpace
// String treatment = " ";
// we just do support mediation
boolean mediation = swordConfig.isMediated();
// abstract is the short description of the collection
String dcAbstract = collectionService
.getMetadata(col, "short_description");
// load up the sword collection
scol.setLocation(location);
// we just do support mediation
boolean mediation = swordConfig.isMediated();
// add the title if it exists
if (title != null && !"".equals(title))
{
scol.setTitle(title);
}
// load up the sword collection
scol.setLocation(location);
// add the collection policy if it exists
if (collectionPolicy != null && !"".equals(collectionPolicy))
{
scol.setCollectionPolicy(collectionPolicy);
}
// add the title if it exists
if (title != null && !"".equals(title))
{
scol.setTitle(title);
}
// FIXME: leave the treatment out for the time being,
// as there is no analogue
// scol.setTreatment(treatment);
// add the collection policy if it exists
if (collectionPolicy != null && !"".equals(collectionPolicy))
{
scol.setCollectionPolicy(collectionPolicy);
}
// add the abstract if it exists
if (dcAbstract != null && !"".equals(dcAbstract))
{
scol.setAbstract(dcAbstract);
}
// FIXME: leave the treatment out for the time being,
// as there is no analogue
// scol.setTreatment(treatment);
scol.setMediation(mediation);
// add the abstract if it exists
if (dcAbstract != null && !"".equals(dcAbstract))
{
scol.setAbstract(dcAbstract);
}
List<String> accepts = swordService.getSwordConfig().getCollectionAccepts();
scol.setMediation(mediation);
List<String> accepts = swordService.getSwordConfig()
.getCollectionAccepts();
for (String accept : accepts)
{
scol.addAccepts(accept);
}
// add the accept packaging values
Map<String, Float> aps = swordConfig.getAcceptPackaging(col);
for (Map.Entry<String, Float> ap : aps.entrySet())
{
scol.addAcceptPackaging(ap.getKey(), ap.getValue());
}
// add the accept packaging values
Map<String, Float> aps = swordConfig.getAcceptPackaging(col);
for (Map.Entry<String, Float> ap : aps.entrySet())
{
scol.addAcceptPackaging(ap.getKey(), ap.getValue());
}
// should we offer the items in the collection up as deposit
// targets?
boolean itemService = ConfigurationManager.getBooleanProperty("sword-server", "expose-items");
if (itemService)
{
String subService = urlManager.constructSubServiceUrl(col);
scol.setService(subService);
}
// should we offer the items in the collection up as deposit
// targets?
boolean itemService = ConfigurationManager
.getBooleanProperty("sword-server", "expose-items");
if (itemService)
{
String subService = urlManager.constructSubServiceUrl(col);
scol.setService(subService);
}
log.debug("Created ATOM Collection for DSpace Collection");
log.debug("Created ATOM Collection for DSpace Collection");
return scol;
}
return scol;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -40,130 +40,152 @@ import java.util.List;
*/
public class CollectionDepositor extends Depositor
{
/** logger */
private static Logger log = Logger.getLogger(CollectionDepositor.class);
/** logger */
private static Logger log = Logger.getLogger(CollectionDepositor.class);
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
/**
* The DSpace Collection we are depositing into
*/
private Collection collection;
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
/**
* Construct a depositor for the given service instance on the
* given DSpaceObject. If the DSpaceObject is not an instance of Collection
* this constructor will throw an Exception
*
* @param swordService
* @param dso
* @throws DSpaceSWORDException
*/
public CollectionDepositor(SWORDService swordService, DSpaceObject dso)
throws DSpaceSWORDException
{
super(swordService, dso);
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException("You tried to initialise the collection depositor with something" +
"other than a collection object");
}
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
this.collection = (Collection) dso;
/**
* The DSpace Collection we are depositing into
*/
private Collection collection;
log.debug("Created instance of CollectionDepositor");
}
/**
* Construct a depositor for the given service instance on the
* given DSpaceObject. If the DSpaceObject is not an instance of Collection
* this constructor will throw an Exception
*
* @param swordService
* @param dso
* @throws DSpaceSWORDException
*/
public CollectionDepositor(SWORDService swordService, DSpaceObject dso)
throws DSpaceSWORDException
{
super(swordService, dso);
/**
* Perform a deposit, using the supplied SWORD Deposit object.
*
* @param deposit
* @throws SWORDErrorException
* @throws DSpaceSWORDException
*/
public DepositResult doDeposit(Deposit deposit)
throws SWORDErrorException, DSpaceSWORDException
{
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException(
"You tried to initialise the collection depositor with something" +
"other than a collection object");
}
// FIXME: the spec is unclear what to do in this situation. I'm going
// the throw a 415 (ERROR_CONTENT) until further notice
//
// determine if this is an acceptable file format
if (!swordConfig.isAcceptableContentType(context, deposit.getContentType(), collection))
{
log.error("Unacceptable content type detected: " + deposit.getContentType() + " for collection " + collection.getID());
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable content type in deposit request: " + deposit.getContentType());
}
this.collection = (Collection) dso;
// determine if this is an acceptable packaging type for the deposit
// if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
if (!swordConfig.isSupportedMediaType(deposit.getPackaging(), this.collection))
{
log.error("Unacceptable packaging type detected: " + deposit.getPackaging() + "for collection" + collection.getID());
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable packaging type in deposit request: " + deposit.getPackaging());
}
log.debug("Created instance of CollectionDepositor");
}
// Obtain the relevant ingester from the factory
SWORDIngester si = SWORDIngesterFactory.getInstance(context, deposit, collection);
swordService.message("Loaded ingester: " + si.getClass().getName());
/**
* Perform a deposit, using the supplied SWORD Deposit object.
*
* @param deposit
* @throws SWORDErrorException
* @throws DSpaceSWORDException
*/
public DepositResult doDeposit(Deposit deposit)
throws SWORDErrorException, DSpaceSWORDException
{
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
// do the deposit
DepositResult result = si.ingest(swordService, deposit, collection);
swordService.message("Archive ingest completed successfully");
// FIXME: the spec is unclear what to do in this situation. I'm going
// the throw a 415 (ERROR_CONTENT) until further notice
//
// determine if this is an acceptable file format
if (!swordConfig
.isAcceptableContentType(context, deposit.getContentType(),
collection))
{
log.error("Unacceptable content type detected: " +
deposit.getContentType() + " for collection " +
collection.getID());
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable content type in deposit request: " +
deposit.getContentType());
}
// if there's an item availalble, and we want to keep the original
// then do that
try
{
if (swordConfig.isKeepOriginal())
{
swordService.message("DSpace will store an original copy of the deposit, " +
"as well as ingesting the item into the archive");
// determine if this is an acceptable packaging type for the deposit
// if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
if (!swordConfig
.isSupportedMediaType(deposit.getPackaging(), this.collection))
{
log.error("Unacceptable packaging type detected: " +
deposit.getPackaging() + "for collection" +
collection.getID());
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable packaging type in deposit request: " +
deposit.getPackaging());
}
// in order to be allowed to add the file back to the item, we need to ignore authorisations
// for a moment
context.turnOffAuthorisationSystem();
// Obtain the relevant ingester from the factory
SWORDIngester si = SWORDIngesterFactory
.getInstance(context, deposit, collection);
swordService.message("Loaded ingester: " + si.getClass().getName());
String bundleName = ConfigurationManager.getProperty("sword-server", "bundle.name");
if (bundleName == null || "".equals(bundleName))
{
bundleName = "SWORD";
}
Item item = result.getItem();
List<Bundle> bundles = item.getBundles();
Bundle swordBundle = null;
for (Bundle bundle : bundles)
{
if (bundleName.equals(bundle.getName()))
{
// we found one
swordBundle = bundle;
break;
}
}
if (swordBundle == null)
{
swordBundle = bundleService.create(context, item, bundleName);
}
// do the deposit
DepositResult result = si.ingest(swordService, deposit, collection);
swordService.message("Archive ingest completed successfully");
String fn = swordService.getFilename(context, deposit, true);
// if there's an item availalble, and we want to keep the original
// then do that
try
{
if (swordConfig.isKeepOriginal())
{
swordService.message(
"DSpace will store an original copy of the deposit, " +
"as well as ingesting the item into the archive");
// in order to be allowed to add the file back to the item, we need to ignore authorisations
// for a moment
context.turnOffAuthorisationSystem();
String bundleName = ConfigurationManager
.getProperty("sword-server", "bundle.name");
if (bundleName == null || "".equals(bundleName))
{
bundleName = "SWORD";
}
Item item = result.getItem();
List<Bundle> bundles = item.getBundles();
Bundle swordBundle = null;
for (Bundle bundle : bundles)
{
if (bundleName.equals(bundle.getName()))
{
// we found one
swordBundle = bundle;
break;
}
}
if (swordBundle == null)
{
swordBundle = bundleService
.create(context, item, bundleName);
}
String fn = swordService.getFilename(context, deposit, true);
Bitstream bitstream;
FileInputStream fis = null;
FileInputStream fis = null;
try
{
fis = new FileInputStream(deposit.getFile());
bitstream = bitstreamService.create(context, swordBundle, fis);
bitstream = bitstreamService
.create(context, swordBundle, fis);
}
finally
{
@@ -176,56 +198,58 @@ public class CollectionDepositor extends Depositor
bitstream.setName(context, fn);
bitstream.setDescription(context, "SWORD deposit package");
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getContentType());
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getContentType());
if (bf != null)
{
bitstreamService.setFormat(context, bitstream, bf);
bitstreamService.setFormat(context, bitstream, bf);
}
bitstreamService.update(context, bitstream);
bundleService.update(context, swordBundle);
itemService.update(context, item);
bitstreamService.update(context, bitstream);
bundleService.update(context, swordBundle);
itemService.update(context, item);
swordService.message("Original package stored as " + fn + ", in item bundle " + swordBundle);
swordService.message("Original package stored as " + fn +
", in item bundle " + swordBundle);
// now reset the context ignore authorisation
context.restoreAuthSystemState();
// now reset the context ignore authorisation
context.restoreAuthSystemState();
// set the media link for the created item
result.setMediaLink(urlManager.getMediaLink(bitstream));
}
else
{
// set the vanilla media link, which doesn't resolve to anything
result.setMediaLink(urlManager.getBaseMediaLinkUrl());
}
}
catch (SQLException | AuthorizeException | IOException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
// set the media link for the created item
result.setMediaLink(urlManager.getMediaLink(bitstream));
}
else
{
// set the vanilla media link, which doesn't resolve to anything
result.setMediaLink(urlManager.getBaseMediaLinkUrl());
}
}
catch (SQLException | AuthorizeException | IOException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
return result;
}
return result;
}
/**
* Reverse any changes which may have resulted as the consequence of a deposit.
*
* This is inteded for use during no-op deposits, and should be called at the
* end of such a deposit process in order to remove any temporary files and
* to abort the database connection, so no changes are written.
*
* @param result
* @throws DSpaceSWORDException
*/
public void undoDeposit(DepositResult result) throws DSpaceSWORDException
{
SWORDContext sc = swordService.getSwordContext();
/**
* Reverse any changes which may have resulted as the consequence of a deposit.
*
* This is inteded for use during no-op deposits, and should be called at the
* end of such a deposit process in order to remove any temporary files and
* to abort the database connection, so no changes are written.
*
* @param result
* @throws DSpaceSWORDException
*/
public void undoDeposit(DepositResult result) throws DSpaceSWORDException
{
SWORDContext sc = swordService.getSwordContext();
// abort the context, so no database changes are written
// uploaded files will be deleted by the cleanup script
sc.abort();
swordService.message("Database changes aborted");
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -31,111 +31,119 @@ import org.dspace.handle.service.HandleService;
*/
public class CollectionLocation
{
/** Log4j logger */
public static final Logger log = Logger.getLogger(CollectionLocation.class);
/** Log4j logger */
public static final Logger log = Logger.getLogger(CollectionLocation.class);
protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
/**
* Obtain the deposit URL for the given collection. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param collection
* @return The Deposit URL
* @throws DSpaceSWORDException
*/
public String getLocation(Collection collection)
throws DSpaceSWORDException
{
return this.getBaseUrl() + "/" + collection.getHandle();
}
/**
* Obtain the deposit URL for the given collection. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param collection
* @return The Deposit URL
* @throws DSpaceSWORDException
*/
public String getLocation(Collection collection)
throws DSpaceSWORDException
{
return this.getBaseUrl() + "/" + collection.getHandle();
}
/**
* Obtain the collection which is represented by the given
* URL
*
* @param context the DSpace context
* @param location the URL to resolve to a collection
* @return The collection to which the url resolves
* @throws DSpaceSWORDException
*/
public Collection getCollection(Context context, String location)
throws DSpaceSWORDException
{
try
{
String baseUrl = this.getBaseUrl();
if (baseUrl.length() == location.length())
{
throw new DSpaceSWORDException("The deposit URL is incomplete");
}
String handle = location.substring(baseUrl.length());
if (handle.startsWith("/"))
{
handle = handle.substring(1);
}
if ("".equals(handle))
{
throw new DSpaceSWORDException("The deposit URL is incomplete");
}
/**
* Obtain the collection which is represented by the given
* URL
*
* @param context the DSpace context
* @param location the URL to resolve to a collection
* @return The collection to which the url resolves
* @throws DSpaceSWORDException
*/
public Collection getCollection(Context context, String location)
throws DSpaceSWORDException
{
try
{
String baseUrl = this.getBaseUrl();
if (baseUrl.length() == location.length())
{
throw new DSpaceSWORDException("The deposit URL is incomplete");
}
String handle = location.substring(baseUrl.length());
if (handle.startsWith("/"))
{
handle = handle.substring(1);
}
if ("".equals(handle))
{
throw new DSpaceSWORDException("The deposit URL is incomplete");
}
DSpaceObject dso = handleService.resolveToObject(context, handle);
DSpaceObject dso = handleService.resolveToObject(context, handle);
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException("The deposit URL does not resolve to a valid collection");
}
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException(
"The deposit URL does not resolve to a valid collection");
}
return (Collection) dso;
}
catch (SQLException e)
{
log.error("Caught exception:", e);
throw new DSpaceSWORDException("There was a problem resolving the collection", e);
}
}
return (Collection) dso;
}
catch (SQLException e)
{
log.error("Caught exception:", e);
throw new DSpaceSWORDException(
"There was a problem resolving the collection", e);
}
}
/**
* Get the base deposit URL for the DSpace SWORD implementation. This
* is effectively the URL of the servlet which deals with deposit
* requests, and is used as the basis for the individual Collection
* URLs
*
* If the configuration sword.deposit.url is set, this will be returned,
* but if not, it will construct the url as follows:
*
* [dspace.baseUrl]/sword/deposit
*
* where dspace.baseUrl is also in the configuration file.
*
* @return the base URL for sword deposit
* @throws DSpaceSWORDException
*/
private String getBaseUrl()
throws DSpaceSWORDException
{
String depositUrl = ConfigurationManager.getProperty("sword-server", "deposit.url");
if (depositUrl == null || "".equals(depositUrl))
{
String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSWORDException("Unable to construct deposit urls, due to missing/invalid config in sword.deposit.url and/or dspace.baseUrl");
}
/**
* Get the base deposit URL for the DSpace SWORD implementation. This
* is effectively the URL of the servlet which deals with deposit
* requests, and is used as the basis for the individual Collection
* URLs
*
* If the configuration sword.deposit.url is set, this will be returned,
* but if not, it will construct the url as follows:
*
* [dspace.baseUrl]/sword/deposit
*
* where dspace.baseUrl is also in the configuration file.
*
* @return the base URL for sword deposit
* @throws DSpaceSWORDException
*/
private String getBaseUrl()
throws DSpaceSWORDException
{
String depositUrl = ConfigurationManager
.getProperty("sword-server", "deposit.url");
if (depositUrl == null || "".equals(depositUrl))
{
String dspaceUrl = ConfigurationManager
.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSWORDException(
"Unable to construct deposit urls, due to missing/invalid config in sword.deposit.url and/or dspace.baseUrl");
}
try
{
URL url = new URL(dspaceUrl);
depositUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/sword/deposit").toString();
depositUrl = new URL(url.getProtocol(), url.getHost(),
url.getPort(), "/sword/deposit").toString();
}
catch (MalformedURLException e)
{
throw new DSpaceSWORDException("Unable to construct deposit urls, due to invalid dspace.baseUrl " + e.getMessage(),e);
throw new DSpaceSWORDException(
"Unable to construct deposit urls, due to invalid dspace.baseUrl " +
e.getMessage(), e);
}
}
return depositUrl;
}
}
return depositUrl;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -20,70 +20,75 @@ import java.util.List;
public class CommunityCollectionGenerator extends ATOMCollectionGenerator
{
private static Logger log = Logger.getLogger(CommunityCollectionGenerator.class);
private static Logger log = Logger
.getLogger(CommunityCollectionGenerator.class);
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected CommunityService communityService = ContentServiceFactory
.getInstance().getCommunityService();
public CommunityCollectionGenerator(SWORDService service)
{
super(service);
log.debug("Created instance of CommunityCollectionGenerator");
}
public CommunityCollectionGenerator(SWORDService service)
{
super(service);
log.debug("Created instance of CommunityCollectionGenerator");
}
public Collection buildCollection(DSpaceObject dso)
throws DSpaceSWORDException
{
if (!(dso instanceof Community))
{
log.error("buildCollection passed something other than a Community object");
throw new DSpaceSWORDException("Incorrect ATOMCollectionGenerator instantiated");
}
public Collection buildCollection(DSpaceObject dso)
throws DSpaceSWORDException
{
if (!(dso instanceof Community))
{
log.error(
"buildCollection passed something other than a Community object");
throw new DSpaceSWORDException(
"Incorrect ATOMCollectionGenerator instantiated");
}
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
Community com = (Community) dso;
Collection scol = new Collection();
Community com = (Community) dso;
Collection scol = new Collection();
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(com);
scol.setLocation(location);
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(com);
scol.setLocation(location);
// collection title is just the community name
String title = communityService.getName(com);
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// collection title is just the community name
String title = communityService.getName(com);
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// FIXME: the community has no obvious licence
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// FIXME: the community has no obvious licence
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// abstract is the short description of the collection
List<MetadataValue> abstracts = communityService.getMetadataByMetadataString(com, "short_description");
if (abstracts != null && !abstracts.isEmpty())
{
String firstValue = abstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
// abstract is the short description of the collection
List<MetadataValue> abstracts = communityService
.getMetadataByMetadataString(com, "short_description");
if (abstracts != null && !abstracts.isEmpty())
{
String firstValue = abstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
// do we support mediated deposit
scol.setMediation(swordConfig.isMediated());
// do we support mediated deposit
scol.setMediation(swordConfig.isMediated());
// NOTE: for communities, there are no MIME types that it accepts.
// the list of mime types that we accept
// NOTE: for communities, there are no MIME types that it accepts.
// the list of mime types that we accept
// offer up the collections from this item as deposit targets
String subService = urlManager.constructSubServiceUrl(com);
scol.setService(subService);
// offer up the collections from this item as deposit targets
String subService = urlManager.constructSubServiceUrl(com);
scol.setService(subService);
log.debug("Created ATOM Collection for DSpace Community");
log.debug("Created ATOM Collection for DSpace Community");
return scol;
}
return scol;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -30,290 +30,291 @@ import org.purl.sword.atom.Generator;
*/
public abstract class DSpaceATOMEntry
{
/** the SWORD ATOM entry which this class effectively decorates */
protected SWORDEntry entry;
/** the SWORD ATOM entry which this class effectively decorates */
protected SWORDEntry entry;
/** the item this ATOM entry represents */
protected Item item = null;
/** the item this ATOM entry represents */
protected Item item = null;
/** The bitstream this ATOM entry represents */
protected Bitstream bitstream = null;
/** The bitstream this ATOM entry represents */
protected Bitstream bitstream = null;
/** the deposit result */
protected DepositResult result = null;
/** the deposit result */
protected DepositResult result = null;
/** sword service implementation */
protected SWORDService swordService;
/** sword service implementation */
protected SWORDService swordService;
/** the original deposit */
protected Deposit deposit = null;
/** the original deposit */
protected Deposit deposit = null;
/**
* Create a new atom entry object around the given service
*
* @param service
*/
protected DSpaceATOMEntry(SWORDService service)
{
this.swordService = service;
}
/**
* Create a new atom entry object around the given service
*
* @param service
*/
protected DSpaceATOMEntry(SWORDService service)
{
this.swordService = service;
}
/**
* Reset all the internal variables of the class to their original values
*/
public void reset()
{
this.entry = new SWORDEntry();
this.item = null;
this.bitstream = null;
this.result = null;
this.deposit = null;
}
/**
* Reset all the internal variables of the class to their original values
*/
public void reset()
{
this.entry = new SWORDEntry();
this.item = null;
this.bitstream = null;
this.result = null;
this.deposit = null;
}
/**
* Get the SWORD entry for the given DSpace object. In this case,
* we should be responding to requests for the media link, so this
* method will throw an error unless the DSpace object is an instance
* of the Bitstream.
*
* @param dso
* @throws DSpaceSWORDException
*/
public SWORDEntry getSWORDEntry(DSpaceObject dso)
throws DSpaceSWORDException
{
// reset the object, just in case
this.reset();
/**
* Get the SWORD entry for the given DSpace object. In this case,
* we should be responding to requests for the media link, so this
* method will throw an error unless the DSpace object is an instance
* of the Bitstream.
*
* @param dso
* @throws DSpaceSWORDException
*/
public SWORDEntry getSWORDEntry(DSpaceObject dso)
throws DSpaceSWORDException
{
// reset the object, just in case
this.reset();
// NOTE: initially this exists just for the purposes of responding to media-link
// requests, so should only ever respond to entries on Bitstreams
if (dso instanceof Bitstream)
{
this.bitstream = (Bitstream) dso;
}
else
{
throw new DSpaceSWORDException("Can only recover a sword entry for a bitstream via this method");
}
// NOTE: initially this exists just for the purposes of responding to media-link
// requests, so should only ever respond to entries on Bitstreams
if (dso instanceof Bitstream)
{
this.bitstream = (Bitstream) dso;
}
else
{
throw new DSpaceSWORDException(
"Can only recover a sword entry for a bitstream via this method");
}
this.constructEntry();
this.constructEntry();
return entry;
}
return entry;
}
/**
* Construct the SWORDEntry object which represents the given
* item with the given handle. An argument as to whether this
* is a NoOp request is required because in that event the
* assigned identifier for the item will not be added to the
* SWORDEntry as it will be invalid.
*
* @param result the result of the deposit operation
* @param deposit the original deposit request
* @return the SWORDEntry for the item
*/
public SWORDEntry getSWORDEntry(DepositResult result, Deposit deposit)
throws DSpaceSWORDException
{
this.reset();
/**
* Construct the SWORDEntry object which represents the given
* item with the given handle. An argument as to whether this
* is a NoOp request is required because in that event the
* assigned identifier for the item will not be added to the
* SWORDEntry as it will be invalid.
*
* @param result the result of the deposit operation
* @param deposit the original deposit request
* @return the SWORDEntry for the item
*/
public SWORDEntry getSWORDEntry(DepositResult result, Deposit deposit)
throws DSpaceSWORDException
{
this.reset();
this.entry = new SWORDEntry();
this.item = result.getItem();
this.bitstream = result.getBitstream();
this.result = result;
this.deposit = deposit;
this.entry = new SWORDEntry();
this.item = result.getItem();
this.bitstream = result.getBitstream();
this.result = result;
this.deposit = deposit;
this.constructEntry();
this.constructEntry();
return entry;
}
return entry;
}
/**
* Construct the entry
*
* @throws DSpaceSWORDException
*/
protected void constructEntry()
throws DSpaceSWORDException
{
// set the generator
this.addGenerator();
/**
* Construct the entry
*
* @throws DSpaceSWORDException
*/
protected void constructEntry()
throws DSpaceSWORDException
{
// set the generator
this.addGenerator();
// add the authors to the sword entry
this.addAuthors();
// add the authors to the sword entry
this.addAuthors();
// add the category information to the sword entry
this.addCategories();
// add the category information to the sword entry
this.addCategories();
// add a content element to the sword entry
this.addContentElement();
// add a content element to the sword entry
this.addContentElement();
// add a packaging element to the sword entry
this.addPackagingElement();
// add a packaging element to the sword entry
this.addPackagingElement();
// add contributors (authors plus any other bits) to the sword entry
this.addContributors();
// add contributors (authors plus any other bits) to the sword entry
this.addContributors();
// add the identifier for the item, if the id is going
// to be valid by the end of the request
this.addIdentifier();
// add the identifier for the item, if the id is going
// to be valid by the end of the request
this.addIdentifier();
// add any appropriate links
this.addLinks();
// add any appropriate links
this.addLinks();
// add the publish date
this.addPublishDate();
// add the publish date
this.addPublishDate();
// add the rights information
this.addRights();
// add the rights information
this.addRights();
// add the summary of the item
this.addSummary();
// add the summary of the item
this.addSummary();
// add the title of the item
this.addTitle();
// add the title of the item
this.addTitle();
// add the date on which the entry was last updated
this.addLastUpdatedDate();
// add the date on which the entry was last updated
this.addLastUpdatedDate();
// set the treatment
this.addTreatment();
}
// set the treatment
this.addTreatment();
}
/**
* Add deposit treatment text
*/
protected void addTreatment()
{
if (result != null)
{
entry.setTreatment(result.getTreatment());
}
}
/**
* Add deposit treatment text
*/
protected void addTreatment()
{
if (result != null)
{
entry.setTreatment(result.getTreatment());
}
}
/**
* add the generator field content
*/
protected void addGenerator()
{
boolean identify = ConfigurationManager.getBooleanProperty("sword-server", "identify-version");
SWORDUrlManager urlManager = swordService.getUrlManager();
String softwareUri = urlManager.getGeneratorUrl();
if (identify)
{
Generator generator = new Generator();
generator.setUri(softwareUri);
generator.setVersion(SWORDProperties.VERSION);
entry.setGenerator(generator);
}
}
/**
* add the generator field content
*/
protected void addGenerator()
{
boolean identify = ConfigurationManager
.getBooleanProperty("sword-server", "identify-version");
SWORDUrlManager urlManager = swordService.getUrlManager();
String softwareUri = urlManager.getGeneratorUrl();
if (identify)
{
Generator generator = new Generator();
generator.setUri(softwareUri);
generator.setVersion(SWORDProperties.VERSION);
entry.setGenerator(generator);
}
}
/**
* set the packaging format of the deposit
*/
protected void addPackagingElement()
{
if (deposit != null)
{
entry.setPackaging(deposit.getPackaging());
}
}
/**
* set the packaging format of the deposit
*/
protected void addPackagingElement()
{
if (deposit != null)
{
entry.setPackaging(deposit.getPackaging());
}
}
/**
* add the author names from the bibliographic metadata. Does
* not supply email addresses or URIs, both for privacy, and
* because the data is not so readily available in DSpace.
*
*/
protected void addAuthors()
{
if (deposit != null)
{
String username = this.deposit.getUsername();
Author author = new Author();
author.setName(username);
entry.addAuthors(author);
}
}
/**
* add the author names from the bibliographic metadata. Does
* not supply email addresses or URIs, both for privacy, and
* because the data is not so readily available in DSpace.
*
*/
protected void addAuthors()
{
if (deposit != null)
{
String username = this.deposit.getUsername();
Author author = new Author();
author.setName(username);
entry.addAuthors(author);
}
}
/**
* Add the list of contributors to the item. This will include
* the authors, and any other contributors that are supplied
* in the bibliographic metadata
*
*/
protected void addContributors()
{
if (deposit != null)
{
String obo = deposit.getOnBehalfOf();
if (obo != null)
{
Contributor cont = new Contributor();
cont.setName(obo);
entry.addContributor(cont);
}
}
}
/**
* Add the list of contributors to the item. This will include
* the authors, and any other contributors that are supplied
* in the bibliographic metadata
*
*/
protected void addContributors()
{
if (deposit != null)
{
String obo = deposit.getOnBehalfOf();
if (obo != null)
{
Contributor cont = new Contributor();
cont.setName(obo);
entry.addContributor(cont);
}
}
}
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
abstract void addCategories() throws DSpaceSWORDException;
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
abstract void addCategories() throws DSpaceSWORDException;
/**
* Set the content type that DSpace received. This is just
* "application/zip" in this default implementation.
*
*/
abstract void addContentElement() throws DSpaceSWORDException;
/**
* Set the content type that DSpace received. This is just
* "application/zip" in this default implementation.
*
*/
abstract void addContentElement() throws DSpaceSWORDException;
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
abstract void addIdentifier() throws DSpaceSWORDException;
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
abstract void addIdentifier() throws DSpaceSWORDException;
/**
* Add links associated with this item.
*
*/
abstract void addLinks() throws DSpaceSWORDException;
/**
* Add links associated with this item.
*
*/
abstract void addLinks() throws DSpaceSWORDException;
/**
* Add the date of publication from the bibliographic metadata
*
*/
abstract void addPublishDate() throws DSpaceSWORDException;
/**
* Add the date of publication from the bibliographic metadata
*
*/
abstract void addPublishDate() throws DSpaceSWORDException;
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
abstract void addRights() throws DSpaceSWORDException;
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
abstract void addRights() throws DSpaceSWORDException;
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
abstract void addSummary() throws DSpaceSWORDException;
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
abstract void addSummary() throws DSpaceSWORDException;
/**
* Add the title from the bibliographic metadata
*
*/
abstract void addTitle() throws DSpaceSWORDException;
/**
* Add the title from the bibliographic metadata
*
*/
abstract void addTitle() throws DSpaceSWORDException;
/**
* Add the date that this item was last updated
*
*/
abstract void addLastUpdatedDate() throws DSpaceSWORDException;
/**
* Add the date that this item was last updated
*
*/
abstract void addLastUpdatedDate() throws DSpaceSWORDException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -12,30 +12,38 @@ package org.dspace.sword;
*/
public interface DSpaceSWORDErrorCodes
{
/** if unpackaging the package fails */
public static final String UNPACKAGE_FAIL = SWORDProperties.SOFTWARE_URI + "/errors/UnpackageFail";
/** if unpackaging the package fails */
public static final String UNPACKAGE_FAIL =
SWORDProperties.SOFTWARE_URI + "/errors/UnpackageFail";
/** if the url of the request does not resolve to something meaningful */
public static final String BAD_URL = SWORDProperties.SOFTWARE_URI + "/errors/BadUrl";
/** if the url of the request does not resolve to something meaningful */
public static final String BAD_URL =
SWORDProperties.SOFTWARE_URI + "/errors/BadUrl";
/** if the media requested is unavailable */
public static final String MEDIA_UNAVAILABLE = SWORDProperties.SOFTWARE_URI + "/errors/MediaUnavailable";
/** if the media requested is unavailable */
public static final String MEDIA_UNAVAILABLE =
SWORDProperties.SOFTWARE_URI + "/errors/MediaUnavailable";
/* additional codes */
/** Invalid package */
public static final String PACKAGE_ERROR = SWORDProperties.SOFTWARE_URI + "/errors/PackageError";
public static final String PACKAGE_ERROR =
SWORDProperties.SOFTWARE_URI + "/errors/PackageError";
/** Missing resources in package */
public static final String PACKAGE_VALIDATION_ERROR = SWORDProperties.SOFTWARE_URI + "/errors/PackageValidationError";
public static final String PACKAGE_VALIDATION_ERROR =
SWORDProperties.SOFTWARE_URI + "/errors/PackageValidationError";
/** Crosswalk error */
public static final String CROSSWALK_ERROR = SWORDProperties.SOFTWARE_URI + "/errors/CrosswalkError";
public static final String CROSSWALK_ERROR =
SWORDProperties.SOFTWARE_URI + "/errors/CrosswalkError";
/** Invalid collection for linking */
public static final String COLLECTION_LINK_ERROR = SWORDProperties.SOFTWARE_URI + "/errors/CollectionLinkError";
public static final String COLLECTION_LINK_ERROR =
SWORDProperties.SOFTWARE_URI + "/errors/CollectionLinkError";
/** Database or IO Error when installing new item */
public static final String REPOSITORY_ERROR = SWORDProperties.SOFTWARE_URI + "/errors/RepositoryError";
public static final String REPOSITORY_ERROR =
SWORDProperties.SOFTWARE_URI + "/errors/RepositoryError";
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -17,24 +17,24 @@ package org.dspace.sword;
public class DSpaceSWORDException extends Exception
{
public DSpaceSWORDException()
{
super();
}
public DSpaceSWORDException()
{
super();
}
public DSpaceSWORDException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public DSpaceSWORDException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public DSpaceSWORDException(String arg0)
{
super(arg0);
}
public DSpaceSWORDException(String arg0)
{
super(arg0);
}
public DSpaceSWORDException(Throwable arg0)
{
super(arg0);
}
public DSpaceSWORDException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -33,157 +33,176 @@ import org.purl.sword.base.ServiceDocumentRequest;
*/
public class DSpaceSWORDServer implements SWORDServer
{
/** Log4j logger */
public static final Logger log = Logger.getLogger(DSpaceSWORDServer.class);
/** Log4j logger */
public static final Logger log = Logger.getLogger(DSpaceSWORDServer.class);
// methods required by SWORDServer interface
////////////////////////////////////////////
// methods required by SWORDServer interface
////////////////////////////////////////////
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doServiceDocument(org.purl.sword.base.ServiceDocumentRequest)
*/
public ServiceDocument doServiceDocument(ServiceDocumentRequest request)
throws SWORDAuthenticationException, SWORDException, SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doServiceDocument(org.purl.sword.base.ServiceDocumentRequest)
*/
public ServiceDocument doServiceDocument(ServiceDocumentRequest request)
throws SWORDAuthenticationException, SWORDException,
SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(request);
Context context = sc.getContext();
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(request);
Context context = sc.getContext();
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_do_service_document", ""));
}
if (log.isDebugEnabled())
{
log.debug(LogManager
.getHeader(context, "sword_do_service_document", ""));
}
// log the request
log.info(LogManager.getHeader(context, "sword_service_document_request", "username=" + request.getUsername() + ",on_behalf_of=" + request.getOnBehalfOf()));
// log the request
log.info(LogManager
.getHeader(context, "sword_service_document_request",
"username=" + request.getUsername() +
",on_behalf_of=" +
request.getOnBehalfOf()));
// prep the service request, then get the service document out of it
SWORDService service = new SWORDService(sc);
ServiceDocumentManager manager = new ServiceDocumentManager(service);
ServiceDocument doc = manager.getServiceDocument(request.getLocation());
// prep the service request, then get the service document out of it
SWORDService service = new SWORDService(sc);
ServiceDocumentManager manager = new ServiceDocumentManager(
service);
ServiceDocument doc = manager
.getServiceDocument(request.getLocation());
return doc;
}
catch (DSpaceSWORDException e)
{
log.error("caught exception: ", e);
throw new SWORDException("The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
return doc;
}
catch (DSpaceSWORDException e)
{
log.error("caught exception: ", e);
throw new SWORDException(
"The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
{
sc.abort();
}
}
}
}
}
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doSWORDDeposit(org.purl.sword.server.Deposit)
*/
public DepositResponse doDeposit(Deposit deposit)
throws SWORDAuthenticationException, SWORDException, SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doSWORDDeposit(org.purl.sword.server.Deposit)
*/
public DepositResponse doDeposit(Deposit deposit)
throws SWORDAuthenticationException, SWORDException,
SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(deposit);
Context context = sc.getContext();
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(deposit);
Context context = sc.getContext();
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_do_deposit", ""));
}
{
log.debug(
LogManager.getHeader(context, "sword_do_deposit", ""));
}
// log the request
log.info(LogManager.getHeader(context, "sword_deposit_request", "username=" + deposit.getUsername() + ",on_behalf_of=" + deposit.getOnBehalfOf()));
// log the request
log.info(LogManager.getHeader(context, "sword_deposit_request",
"username=" + deposit.getUsername() + ",on_behalf_of=" +
deposit.getOnBehalfOf()));
// prep and execute the deposit
SWORDService service = new SWORDService(sc);
service.setVerbose(deposit.isVerbose());
DepositManager dm = new DepositManager(service);
DepositResponse response = dm.deposit(deposit);
// prep and execute the deposit
SWORDService service = new SWORDService(sc);
service.setVerbose(deposit.isVerbose());
DepositManager dm = new DepositManager(service);
DepositResponse response = dm.deposit(deposit);
// if something hasn't killed it already (allowed), then complete the transaction
sc.commit();
// if something hasn't killed it already (allowed), then complete the transaction
sc.commit();
return response;
}
catch (DSpaceSWORDException e)
{
log.error("caught exception:", e);
throw new SWORDException("There was a problem depositing the item", e);
}
finally
{
// if, for some reason, we wind up here with a not null context
// then abort it (the above should commit it if everything works fine)
if (sc != null)
return response;
}
catch (DSpaceSWORDException e)
{
log.error("caught exception:", e);
throw new SWORDException("There was a problem depositing the item",
e);
}
finally
{
// if, for some reason, we wind up here with a not null context
// then abort it (the above should commit it if everything works fine)
if (sc != null)
{
sc.abort();
}
}
}
}
}
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doSWORDDeposit(org.purl.sword.server.Deposit)
*/
public AtomDocumentResponse doAtomDocument(AtomDocumentRequest adr)
throws SWORDAuthenticationException, SWORDException, SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
/* (non-Javadoc)
* @see org.purl.sword.SWORDServer#doSWORDDeposit(org.purl.sword.server.Deposit)
*/
public AtomDocumentResponse doAtomDocument(AtomDocumentRequest adr)
throws SWORDAuthenticationException, SWORDException,
SWORDErrorException
{
// gah. bloody variable scoping.
// set up a dummy sword context for the "finally" block
SWORDContext sc = null;
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(adr);
Context context = sc.getContext();
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SWORDAuthenticator auth = new SWORDAuthenticator();
sc = auth.authenticate(adr);
Context context = sc.getContext();
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_do_atom_document", ""));
}
if (log.isDebugEnabled())
{
log.debug(LogManager
.getHeader(context, "sword_do_atom_document", ""));
}
// log the request
log.info(LogManager.getHeader(context, "sword_atom_document_request", "username=" + adr.getUsername()));
// log the request
log.info(LogManager
.getHeader(context, "sword_atom_document_request",
"username=" + adr.getUsername()));
// prep the service request, then get the service document out of it
SWORDService service = new SWORDService(sc);
MediaEntryManager manager = new MediaEntryManager(service);
// prep the service request, then get the service document out of it
SWORDService service = new SWORDService(sc);
MediaEntryManager manager = new MediaEntryManager(service);
return manager.getMediaEntry(adr.getLocation());
}
catch (DSpaceSWORDException e)
{
log.error("caught exception: ", e);
throw new SWORDException("The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
return manager.getMediaEntry(adr.getLocation());
}
catch (DSpaceSWORDException e)
{
log.error("caught exception: ", e);
throw new SWORDException(
"The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
{
sc.abort();
}
}
}
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -38,113 +38,129 @@ import org.purl.sword.base.SWORDErrorException;
*/
public class DepositManager
{
/** Log4j logger */
public static final Logger log = Logger.getLogger(DepositManager.class);
/** Log4j logger */
public static final Logger log = Logger.getLogger(DepositManager.class);
/** The SWORD service implementation */
private SWORDService swordService;
/** The SWORD service implementation */
private SWORDService swordService;
/**
* Construct a new DepositManager using the given instantiation of
* the SWORD service implementation
*
* @param service
*/
public DepositManager(SWORDService service)
{
this.swordService = service;
log.debug("Created instance of DepositManager");
}
/**
* Construct a new DepositManager using the given instantiation of
* the SWORD service implementation
*
* @param service
*/
public DepositManager(SWORDService service)
{
this.swordService = service;
log.debug("Created instance of DepositManager");
}
public DSpaceObject getDepositTarget(Deposit deposit)
throws DSpaceSWORDException, SWORDErrorException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
Context context = swordService.getContext();
public DSpaceObject getDepositTarget(Deposit deposit)
throws DSpaceSWORDException, SWORDErrorException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
Context context = swordService.getContext();
// get the target collection
String loc = deposit.getLocation();
DSpaceObject dso = urlManager.getDSpaceObject(context, loc);
// get the target collection
String loc = deposit.getLocation();
DSpaceObject dso = urlManager.getDSpaceObject(context, loc);
swordService.message("Performing deposit using location: " + loc);
swordService.message("Performing deposit using location: " + loc);
if (dso instanceof Collection)
{
CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
swordService.message("Location resolves to collection with handle: " + dso.getHandle() +
" and name: " + collectionService.getName((Collection) dso));
}
else if (dso instanceof Item)
{
swordService.message("Location resolves to item with handle: " + dso.getHandle());
}
if (dso instanceof Collection)
{
CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
swordService.message(
"Location resolves to collection with handle: " +
dso.getHandle() +
" and name: " +
collectionService.getName((Collection) dso));
}
else if (dso instanceof Item)
{
swordService.message("Location resolves to item with handle: " +
dso.getHandle());
}
return dso;
}
return dso;
}
/**
* Once this object is fully prepared, this method will execute
* the deposit process. The returned DepositRequest can be
* used then to assemble the SWORD response.
*
* @return the response to the deposit request
* @throws DSpaceSWORDException
*/
public DepositResponse deposit(Deposit deposit)
throws DSpaceSWORDException, SWORDErrorException, SWORDAuthenticationException
{
// start the timer, and initialise the verboseness of the request
Date start = new Date();
swordService.message("Initialising verbose deposit");
/**
* Once this object is fully prepared, this method will execute
* the deposit process. The returned DepositRequest can be
* used then to assemble the SWORD response.
*
* @return the response to the deposit request
* @throws DSpaceSWORDException
*/
public DepositResponse deposit(Deposit deposit)
throws DSpaceSWORDException, SWORDErrorException,
SWORDAuthenticationException
{
// start the timer, and initialise the verboseness of the request
Date start = new Date();
swordService.message("Initialising verbose deposit");
// get the things out of the service that we need
SWORDContext swordContext = swordService.getSwordContext();
Context context = swordService.getContext();
// get the things out of the service that we need
SWORDContext swordContext = swordService.getSwordContext();
Context context = swordService.getContext();
// get the deposit target
DSpaceObject dso = this.getDepositTarget(deposit);
// get the deposit target
DSpaceObject dso = this.getDepositTarget(deposit);
// find out if the supplied SWORDContext can submit to the given
// dspace object
SWORDAuthenticator auth = new SWORDAuthenticator();
if (!auth.canSubmit(swordService, deposit, dso))
{
// throw an exception if the deposit can't be made
String oboEmail = "none";
if (swordContext.getOnBehalfOf() != null)
{
oboEmail = swordContext.getOnBehalfOf().getEmail();
}
log.info(LogManager.getHeader(context, "deposit_failed_authorisation", "user=" +
swordContext.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail));
throw new SWORDAuthenticationException("Cannot submit to the given collection with this context");
}
// find out if the supplied SWORDContext can submit to the given
// dspace object
SWORDAuthenticator auth = new SWORDAuthenticator();
if (!auth.canSubmit(swordService, deposit, dso))
{
// throw an exception if the deposit can't be made
String oboEmail = "none";
if (swordContext.getOnBehalfOf() != null)
{
oboEmail = swordContext.getOnBehalfOf().getEmail();
}
log.info(LogManager
.getHeader(context, "deposit_failed_authorisation",
"user=" +
swordContext.getAuthenticated().getEmail() +
",on_behalf_of=" + oboEmail));
throw new SWORDAuthenticationException(
"Cannot submit to the given collection with this context");
}
// make a note of the authentication in the verbose string
swordService.message("Authenticated user: " + swordContext.getAuthenticated().getEmail());
if (swordContext.getOnBehalfOf() != null)
{
swordService.message("Depositing on behalf of: " + swordContext.getOnBehalfOf().getEmail());
}
// make a note of the authentication in the verbose string
swordService.message("Authenticated user: " +
swordContext.getAuthenticated().getEmail());
if (swordContext.getOnBehalfOf() != null)
{
swordService.message("Depositing on behalf of: " +
swordContext.getOnBehalfOf().getEmail());
}
// determine which deposit engine we initialise
Depositor dep = null;
if (dso instanceof Collection)
{
swordService.message("Initialising depositor for an Item in a Collection");
dep = new CollectionDepositor(swordService, dso);
}
else if (dso instanceof Item)
{
swordService.message("Initialising depositor for a Bitstream in an Item");
dep = new ItemDepositor(swordService, dso);
}
// determine which deposit engine we initialise
Depositor dep = null;
if (dso instanceof Collection)
{
swordService.message(
"Initialising depositor for an Item in a Collection");
dep = new CollectionDepositor(swordService, dso);
}
else if (dso instanceof Item)
{
swordService.message(
"Initialising depositor for a Bitstream in an Item");
dep = new ItemDepositor(swordService, dso);
}
if (dep == null)
{
log.error("The specified deposit target does not exist, or is not a collection or an item");
throw new DSpaceSWORDException("Deposit target is not a collection or an item");
}
if (dep == null)
{
log.error(
"The specified deposit target does not exist, or is not a collection or an item");
throw new DSpaceSWORDException(
"Deposit target is not a collection or an item");
}
DepositResult result = null;
@@ -160,7 +176,7 @@ public class DepositManager
{
storePackageAsFile(deposit);
}
catch(IOException e2)
catch (IOException e2)
{
log.warn("Unable to store SWORD package as file: " + e);
}
@@ -168,58 +184,64 @@ public class DepositManager
throw e;
}
// now construct the deposit response. The response will be
// CREATED if the deposit is in the archive, or ACCEPTED if
// the deposit is in the workflow. We use a separate record
// for the handle because DSpace will not supply the Item with
// a record of the handle straight away.
String handle = result.getHandle();
int state = Deposit.CREATED;
if (StringUtils.isBlank(handle))
{
state = Deposit.ACCEPTED;
}
// now construct the deposit response. The response will be
// CREATED if the deposit is in the archive, or ACCEPTED if
// the deposit is in the workflow. We use a separate record
// for the handle because DSpace will not supply the Item with
// a record of the handle straight away.
String handle = result.getHandle();
int state = Deposit.CREATED;
if (StringUtils.isBlank(handle))
{
state = Deposit.ACCEPTED;
}
DepositResponse response = new DepositResponse(state);
response.setLocation(result.getMediaLink());
DepositResponse response = new DepositResponse(state);
response.setLocation(result.getMediaLink());
DSpaceATOMEntry dsatom = null;
if (result.getItem() != null)
{
swordService.message("Initialising ATOM entry generator for an Item");
dsatom = new ItemEntryGenerator(swordService);
}
else if (result.getBitstream() != null)
{
swordService.message("Initialising ATOM entry generator for a Bitstream");
dsatom = new BitstreamEntryGenerator(swordService);
}
if (dsatom == null)
{
log.error("The deposit failed, see exceptions for explanation");
throw new DSpaceSWORDException("Result of deposit did not yield an Item or a Bitstream");
}
SWORDEntry entry = dsatom.getSWORDEntry(result, deposit);
DSpaceATOMEntry dsatom = null;
if (result.getItem() != null)
{
swordService
.message("Initialising ATOM entry generator for an Item");
dsatom = new ItemEntryGenerator(swordService);
}
else if (result.getBitstream() != null)
{
swordService.message(
"Initialising ATOM entry generator for a Bitstream");
dsatom = new BitstreamEntryGenerator(swordService);
}
if (dsatom == null)
{
log.error("The deposit failed, see exceptions for explanation");
throw new DSpaceSWORDException(
"Result of deposit did not yield an Item or a Bitstream");
}
SWORDEntry entry = dsatom.getSWORDEntry(result, deposit);
// if this was a no-op, we need to remove the files we just
// deposited, and abort the transaction
if (deposit.isNoOp())
{
dep.undoDeposit(result);
swordService.message("NoOp Requested: Removed all traces of submission");
}
// if this was a no-op, we need to remove the files we just
// deposited, and abort the transaction
if (deposit.isNoOp())
{
dep.undoDeposit(result);
swordService.message(
"NoOp Requested: Removed all traces of submission");
}
entry.setNoOp(deposit.isNoOp());
entry.setNoOp(deposit.isNoOp());
Date finish = new Date();
long delta = finish.getTime() - start.getTime();
swordService.message("Total time for deposit processing: " + delta + " ms");
entry.setVerboseDescription(swordService.getVerboseDescription().toString());
Date finish = new Date();
long delta = finish.getTime() - start.getTime();
swordService
.message("Total time for deposit processing: " + delta + " ms");
entry.setVerboseDescription(
swordService.getVerboseDescription().toString());
response.setEntry(entry);
response.setEntry(entry);
return response;
}
return response;
}
/**
* Store original package on disk and companion file containing SWORD headers as found in the deposit object
@@ -234,22 +256,27 @@ public class DepositManager
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory())
{
throw new IOException("Directory does not exist for writing packages on ingest error.");
throw new IOException(
"Directory does not exist for writing packages on ingest error.");
}
String filenameBase = "sword-" + deposit.getUsername() + "-" + (new Date()).getTime();
String filenameBase =
"sword-" + deposit.getUsername() + "-" + (new Date()).getTime();
File packageFile = new File(path, filenameBase);
File headersFile = new File(path, filenameBase + "-headers");
InputStream is = new BufferedInputStream(new FileInputStream(deposit.getFile()));
OutputStream fos = new BufferedOutputStream(new FileOutputStream(packageFile));
InputStream is = new BufferedInputStream(
new FileInputStream(deposit.getFile()));
OutputStream fos = new BufferedOutputStream(
new FileOutputStream(packageFile));
Utils.copy(is, fos);
fos.close();
is.close();
//write companion file with headers
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(headersFile)));
PrintWriter pw = new PrintWriter(
new BufferedWriter(new FileWriter(headersFile)));
pw.println("Content-Disposition=" + deposit.getContentDisposition());
pw.println("Content-Type=" + deposit.getContentType());

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -20,81 +20,80 @@ import org.dspace.content.Bitstream;
*/
public class DepositResult
{
/** the handle assigned to the item, if available */
private String handle;
/** the handle assigned to the item, if available */
private String handle;
/** the item created during deposit */
private Item item;
/** the item created during deposit */
private Item item;
/** Bitstream created as a result of the deposit */
private Bitstream bitstream;
/** Bitstream created as a result of the deposit */
private Bitstream bitstream;
/** The treatment of the item during deposit */
private String treatment;
/** The treatment of the item during deposit */
private String treatment;
/** The media linkto the created object */
private String mediaLink;
/** The media linkto the created object */
private String mediaLink;
public Bitstream getBitstream()
{
return bitstream;
}
public Bitstream getBitstream()
{
return bitstream;
}
public void setBitstream(Bitstream bitstream)
{
this.bitstream = bitstream;
}
public void setBitstream(Bitstream bitstream)
{
this.bitstream = bitstream;
}
public String getTreatment()
{
return treatment;
}
public String getTreatment()
{
return treatment;
}
public void setTreatment(String treatment)
{
this.treatment = treatment;
}
public void setTreatment(String treatment)
{
this.treatment = treatment;
}
/**
* @return the item
*/
public Item getItem()
{
return item;
}
/**
* @return the item
*/
public Item getItem()
{
return item;
}
/**
* @param item the item to set
*/
public void setItem(Item item)
{
this.item = item;
}
/**
* @param item the item to set
*/
public void setItem(Item item)
{
this.item = item;
}
/**
* @return the handle
*/
public String getHandle()
{
return handle;
}
/**
* @return the handle
*/
public String getHandle()
{
return handle;
}
/**
* @param handle the item handle
*/
public void setHandle(String handle)
{
this.handle = handle;
}
/**
* @param handle the item handle
*/
public void setHandle(String handle)
{
this.handle = handle;
}
public String getMediaLink()
{
return mediaLink;
}
public String getMediaLink()
{
return mediaLink;
}
public void setMediaLink(String mediaLink)
{
this.mediaLink = mediaLink;
}
public void setMediaLink(String mediaLink)
{
this.mediaLink = mediaLink;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -18,38 +18,40 @@ import org.purl.sword.base.SWORDErrorException;
*/
public abstract class Depositor
{
/**
* The sword service implementation
*/
protected SWORDService swordService;
/**
* The sword service implementation
*/
protected SWORDService swordService;
/**
* Construct a new Depositor with the given sword service on the given
* dspace object. It is anticipated that extensions of this class will
* specialise in certain kinds of dspace object
*
* @param swordService
* @param dso
*/
public Depositor(SWORDService swordService, DSpaceObject dso)
{
this.swordService = swordService;
}
/**
* Construct a new Depositor with the given sword service on the given
* dspace object. It is anticipated that extensions of this class will
* specialise in certain kinds of dspace object
*
* @param swordService
* @param dso
*/
public Depositor(SWORDService swordService, DSpaceObject dso)
{
this.swordService = swordService;
}
/**
* Execute the deposit process with the given sword deposit.
*
* @param deposit
* @throws SWORDErrorException
* @throws DSpaceSWORDException
*/
public abstract DepositResult doDeposit(Deposit deposit) throws SWORDErrorException, DSpaceSWORDException;
/**
* Execute the deposit process with the given sword deposit.
*
* @param deposit
* @throws SWORDErrorException
* @throws DSpaceSWORDException
*/
public abstract DepositResult doDeposit(Deposit deposit)
throws SWORDErrorException, DSpaceSWORDException;
/**
* Undo any changes to the archive effected by the deposit
*
* @param result
* @throws DSpaceSWORDException
*/
public abstract void undoDeposit(DepositResult result) throws DSpaceSWORDException;
/**
* Undo any changes to the archive effected by the deposit
*
* @param result
* @throws DSpaceSWORDException
*/
public abstract void undoDeposit(DepositResult result)
throws DSpaceSWORDException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -24,84 +24,89 @@ import java.util.List;
*/
public class ItemCollectionGenerator extends ATOMCollectionGenerator
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public ItemCollectionGenerator(SWORDService service)
{
super(service);
}
public ItemCollectionGenerator(SWORDService service)
{
super(service);
}
/**
* Build the collection around the give DSpaceObject. If the object
* is not an instance of a DSpace Item this method will throw an
* exception.
*
* @param dso the dso for which the collection should be build
* @throws DSpaceSWORDException if the dso is not an instance of Item
*/
public Collection buildCollection(DSpaceObject dso) throws DSpaceSWORDException
{
if (!(dso instanceof Item))
{
throw new DSpaceSWORDException("Incorrect ATOMCollectionGenerator instantiated");
}
/**
* Build the collection around the give DSpaceObject. If the object
* is not an instance of a DSpace Item this method will throw an
* exception.
*
* @param dso the dso for which the collection should be build
* @throws DSpaceSWORDException if the dso is not an instance of Item
*/
public Collection buildCollection(DSpaceObject dso)
throws DSpaceSWORDException
{
if (!(dso instanceof Item))
{
throw new DSpaceSWORDException(
"Incorrect ATOMCollectionGenerator instantiated");
}
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
Context context = swordService.getContext();
// get the things we need out of the service
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
Context context = swordService.getContext();
Item item = (Item) dso;
Collection scol = new Collection();
Item item = (Item) dso;
Collection scol = new Collection();
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(item);
scol.setLocation(location);
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(item);
scol.setLocation(location);
// the item title is the sword collection title, or "untitled" otherwise
String title = "Untitled";
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.title");
if (!dcv.isEmpty())
{
String firstValue = dcv.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
title = firstValue;
}
}
scol.setTitle(title);
// the item title is the sword collection title, or "untitled" otherwise
String title = "Untitled";
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.title");
if (!dcv.isEmpty())
{
String firstValue = dcv.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
title = firstValue;
}
}
scol.setTitle(title);
// FIXME: there is no collection policy for items that is obvious to provide.
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// FIXME: there is no collection policy for items that is obvious to provide.
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// abstract is the short description of the item, if it exists
String dcAbstract = "";
List<MetadataValue> dcva = itemService.getMetadataByMetadataString(item, "dc.description.abstract");
if (!dcva.isEmpty())
{
String firstValue = dcva.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
dcAbstract = firstValue;
}
}
if (StringUtils.isNotBlank(dcAbstract))
{
scol.setAbstract(dcAbstract);
}
// abstract is the short description of the item, if it exists
String dcAbstract = "";
List<MetadataValue> dcva = itemService
.getMetadataByMetadataString(item, "dc.description.abstract");
if (!dcva.isEmpty())
{
String firstValue = dcva.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
dcAbstract = firstValue;
}
}
if (StringUtils.isNotBlank(dcAbstract))
{
scol.setAbstract(dcAbstract);
}
// do we suppot mediated deposit
scol.setMediation(swordConfig.isMediated());
// do we suppot mediated deposit
scol.setMediation(swordConfig.isMediated());
// the list of mime types that we accept, which we take from the
// bitstream format registry
List<String> acceptFormats = swordConfig.getAccepts(context, item);
for (String acceptFormat : acceptFormats)
{
scol.addAccepts(acceptFormat);
}
// the list of mime types that we accept, which we take from the
// bitstream format registry
List<String> acceptFormats = swordConfig.getAccepts(context, item);
for (String acceptFormat : acceptFormats)
{
scol.addAccepts(acceptFormat);
}
return scol;
}
return scol;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -29,103 +29,122 @@ import java.util.List;
public class ItemDepositor extends Depositor
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
private Item item;
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
public ItemDepositor(SWORDService swordService, DSpaceObject dso)
throws DSpaceSWORDException
{
super(swordService, dso);
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
if (!(dso instanceof Item))
{
throw new DSpaceSWORDException("You tried to initialise the item depositor with something" +
"other than an item object");
}
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
this.item = (Item) dso;
}
private Item item;
public DepositResult doDeposit(Deposit deposit) throws SWORDErrorException, DSpaceSWORDException
{
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
public ItemDepositor(SWORDService swordService, DSpaceObject dso)
throws DSpaceSWORDException
{
super(swordService, dso);
// FIXME: the spec is unclear what to do in this situation. I'm going
// the throw a 415 (ERROR_CONTENT) until further notice
//
// determine if this is an acceptable file format
if (!swordConfig.isAcceptableContentType(context, deposit.getContentType(), item))
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable content type in deposit request: " + deposit.getContentType());
}
if (!(dso instanceof Item))
{
throw new DSpaceSWORDException(
"You tried to initialise the item depositor with something" +
"other than an item object");
}
// determine if this is an acceptable packaging type for the deposit
// if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
if (!swordConfig.isSupportedMediaType(deposit.getPackaging(), this.item))
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable packaging type in deposit request: " + deposit.getPackaging());
}
this.item = (Item) dso;
}
// Obtain the relevant ingester from the factory
SWORDIngester si = SWORDIngesterFactory.getInstance(context, deposit, item);
swordService.message("Loaded ingester: " + si.getClass().getName());
public DepositResult doDeposit(Deposit deposit)
throws SWORDErrorException, DSpaceSWORDException
{
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
// do the deposit
DepositResult result = si.ingest(swordService, deposit, item);
swordService.message("Archive ingest completed successfully");
// FIXME: the spec is unclear what to do in this situation. I'm going
// the throw a 415 (ERROR_CONTENT) until further notice
//
// determine if this is an acceptable file format
if (!swordConfig
.isAcceptableContentType(context, deposit.getContentType(),
item))
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable content type in deposit request: " +
deposit.getContentType());
}
// if there's an item availalble, and we want to keep the original
// then do that
try
{
if (swordConfig.isKeepOriginal())
{
swordService.message("DSpace will store an original copy of the deposit file, " +
"as well as attaching it to the item");
// determine if this is an acceptable packaging type for the deposit
// if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
if (!swordConfig
.isSupportedMediaType(deposit.getPackaging(), this.item))
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"Unacceptable packaging type in deposit request: " +
deposit.getPackaging());
}
// in order to be allowed to add the file back to the item, we need to ignore authorisations
// for a moment
context.turnOffAuthorisationSystem();
// Obtain the relevant ingester from the factory
SWORDIngester si = SWORDIngesterFactory
.getInstance(context, deposit, item);
swordService.message("Loaded ingester: " + si.getClass().getName());
String bundleName = ConfigurationManager.getProperty("sword-server", "bundle.name");
if (StringUtils.isBlank(bundleName))
{
bundleName = "SWORD";
}
// do the deposit
DepositResult result = si.ingest(swordService, deposit, item);
swordService.message("Archive ingest completed successfully");
List<Bundle> bundles = item.getBundles();
Bundle swordBundle = null;
for (Bundle bundle : bundles)
{
if (bundleName.equals(bundle.getName()))
{
// we found one
swordBundle = bundle;
break;
}
}
if (swordBundle == null)
{
swordBundle = bundleService.create(context, item, bundleName);
}
// if there's an item availalble, and we want to keep the original
// then do that
try
{
if (swordConfig.isKeepOriginal())
{
swordService.message(
"DSpace will store an original copy of the deposit file, " +
"as well as attaching it to the item");
String fn = swordService.getFilename(context, deposit, true);
// in order to be allowed to add the file back to the item, we need to ignore authorisations
// for a moment
context.turnOffAuthorisationSystem();
String bundleName = ConfigurationManager
.getProperty("sword-server", "bundle.name");
if (StringUtils.isBlank(bundleName))
{
bundleName = "SWORD";
}
List<Bundle> bundles = item.getBundles();
Bundle swordBundle = null;
for (Bundle bundle : bundles)
{
if (bundleName.equals(bundle.getName()))
{
// we found one
swordBundle = bundle;
break;
}
}
if (swordBundle == null)
{
swordBundle = bundleService
.create(context, item, bundleName);
}
String fn = swordService.getFilename(context, deposit, true);
Bitstream bitstream;
FileInputStream fis = null;
FileInputStream fis = null;
try
{
fis = new FileInputStream(deposit.getFile());
bitstream = bitstreamService.create(context, swordBundle, fis);
bitstream = bitstreamService
.create(context, swordBundle, fis);
}
finally
{
@@ -134,71 +153,76 @@ public class ItemDepositor extends Depositor
fis.close();
}
}
bitstream.setName(context, fn);
bitstream.setDescription(context, "Original file deposited via SWORD");
bitstream.setName(context, fn);
bitstream.setDescription(context,
"Original file deposited via SWORD");
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getContentType());
if (bf != null)
{
bitstreamService.setFormat(context, bitstream, bf);
}
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getContentType());
if (bf != null)
{
bitstreamService.setFormat(context, bitstream, bf);
}
bitstreamService.update(context, bitstream);
bundleService.update(context, swordBundle);
itemService.update(context, item);
bitstreamService.update(context, bitstream);
bundleService.update(context, swordBundle);
itemService.update(context, item);
swordService.message("Original package stored as " + fn + ", in item bundle " + swordBundle);
swordService.message("Original package stored as " + fn +
", in item bundle " + swordBundle);
// now reset the context ignore authorisation
context.restoreAuthSystemState();
// now reset the context ignore authorisation
context.restoreAuthSystemState();
// set the media link for the created item
result.setMediaLink(urlManager.getMediaLink(bitstream));
}
else
{
// set the media link for the created item using the archived version (since it's just a file)
result.setMediaLink(urlManager.getMediaLink(result.getBitstream()));
}
}
catch (SQLException | AuthorizeException | IOException e)
{
throw new DSpaceSWORDException(e);
}
// set the media link for the created item
result.setMediaLink(urlManager.getMediaLink(bitstream));
}
else
{
// set the media link for the created item using the archived version (since it's just a file)
result.setMediaLink(
urlManager.getMediaLink(result.getBitstream()));
}
}
catch (SQLException | AuthorizeException | IOException e)
{
throw new DSpaceSWORDException(e);
}
return result;
}
return result;
}
public void undoDeposit(DepositResult result) throws DSpaceSWORDException
{
try
{
SWORDContext sc = swordService.getSwordContext();
BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
public void undoDeposit(DepositResult result) throws DSpaceSWORDException
{
try
{
SWORDContext sc = swordService.getSwordContext();
BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
// obtain the bitstream's owning bundles and remove the bitstream
// from them. This will ensure that the bitstream is physically
// removed from the disk.
Bitstream bs = result.getBitstream();
Iterator<BundleBitstream> b2bs = bs.getBundles().iterator();
while (b2bs.hasNext())
{
BundleBitstream bundleBitstream = b2bs.next();
b2bs.remove();
Bundle bundle = bundleBitstream.getBundle();
bundleService.removeBitstream(sc.getContext(), bundle, bs);
bundleService.update(sc.getContext(), bundle);
}
// obtain the bitstream's owning bundles and remove the bitstream
// from them. This will ensure that the bitstream is physically
// removed from the disk.
Bitstream bs = result.getBitstream();
Iterator<BundleBitstream> b2bs = bs.getBundles().iterator();
while (b2bs.hasNext())
{
BundleBitstream bundleBitstream = b2bs.next();
b2bs.remove();
Bundle bundle = bundleBitstream.getBundle();
bundleService.removeBitstream(sc.getContext(), bundle, bs);
bundleService.update(sc.getContext(), bundle);
}
swordService.message("Removing temporary files from disk");
swordService.message("Removing temporary files from disk");
// abort the context, so no database changes are written
sc.abort();
swordService.message("Database changes aborted");
}
catch (IOException | AuthorizeException | SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
// abort the context, so no database changes are written
sc.abort();
swordService.message("Database changes aborted");
}
catch (IOException | AuthorizeException | SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -28,252 +28,275 @@ import java.util.List;
*/
public class ItemEntryGenerator extends DSpaceATOMEntry
{
/** logger */
private static Logger log = Logger.getLogger(ItemEntryGenerator.class);
/** logger */
private static Logger log = Logger.getLogger(ItemEntryGenerator.class);
protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
protected ItemEntryGenerator(SWORDService service)
{
super(service);
}
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories()
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv) {
entry.addCategory(aDcv.getValue());
}
}
}
protected ItemEntryGenerator(SWORDService service)
{
super(service);
}
/**
* Set the content type that DSpace received. This is just
* "application/zip" in this default implementation.
*
*/
protected void addContentElement()
throws DSpaceSWORDException
{
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories()
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
entry.addCategory(aDcv.getValue());
}
}
}
try
{
if (!this.deposit.isNoOp())
{
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
/**
* Set the content type that DSpace received. This is just
* "application/zip" in this default implementation.
*
*/
protected void addContentElement()
throws DSpaceSWORDException
{
// get the things we need out of the service
SWORDUrlManager urlManager = swordService.getUrlManager();
if (StringUtils.isNotBlank(handle))
{
boolean keepOriginal = ConfigurationManager.getBooleanProperty("sword-server", "keep-original-package");
String swordBundle = ConfigurationManager.getProperty("sword-server", "bundle.name");
if (StringUtils.isBlank(swordBundle))
{
swordBundle = "SWORD";
}
try
{
if (!this.deposit.isNoOp())
{
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
// if we keep the original, then expose this as the content element
// otherwise, expose the unpacked version
if (keepOriginal)
{
Content con = new Content();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (swordBundle.equals(bundle.getName())) {
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss) {
BitstreamFormat bf = bs.getBitstream().getFormat(swordService.getContext());
String format = "application/octet-stream";
if (bf != null) {
format = bf.getMIMEType();
}
con.setType(format);
if (StringUtils.isNotBlank(handle))
{
boolean keepOriginal = ConfigurationManager
.getBooleanProperty("sword-server",
"keep-original-package");
String swordBundle = ConfigurationManager
.getProperty("sword-server", "bundle.name");
if (StringUtils.isBlank(swordBundle))
{
swordBundle = "SWORD";
}
// calculate the bitstream link.
String bsLink = urlManager.getBitstreamUrl(bs.getBitstream());
con.setSource(bsLink);
// if we keep the original, then expose this as the content element
// otherwise, expose the unpacked version
if (keepOriginal)
{
Content con = new Content();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (swordBundle.equals(bundle.getName()))
{
List<BundleBitstream> bss = bundle
.getBitstreams();
for (BundleBitstream bs : bss)
{
BitstreamFormat bf = bs.getBitstream()
.getFormat(
swordService.getContext());
String format = "application/octet-stream";
if (bf != null)
{
format = bf.getMIMEType();
}
con.setType(format);
entry.setContent(con);
}
break;
}
}
}
else
{
// return a link to the DSpace entry page
Content content = new Content();
content.setType("text/html");
content.setSource(handleService.getCanonicalForm(handle));
entry.setContent(content);
}
}
}
}
catch (InvalidMediaTypeException e)
{
// do nothing; we'll live without the content type declaration!
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
}
// calculate the bitstream link.
String bsLink = urlManager
.getBitstreamUrl(bs.getBitstream());
con.setSource(bsLink);
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
protected void addIdentifier()
{
// it's possible that the item hasn't been assigned a handle yet
if (!this.deposit.isNoOp())
{
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
entry.setContent(con);
}
break;
}
}
}
else
{
// return a link to the DSpace entry page
Content content = new Content();
content.setType("text/html");
content.setSource(
handleService.getCanonicalForm(handle));
entry.setContent(content);
}
}
}
}
catch (InvalidMediaTypeException e)
{
// do nothing; we'll live without the content type declaration!
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new DSpaceSWORDException(e);
}
}
if (StringUtils.isNotBlank(handle))
{
entry.setId(handleService.getCanonicalForm(handle));
return;
}
}
/**
* Add the identifier for the item. If the item object has
* a handle already assigned, this is used, otherwise, the
* passed handle is used. It is set in the form that
* they can be used to access the resource over http (i.e.
* a real URL).
*/
protected void addIdentifier()
{
// it's possible that the item hasn't been assigned a handle yet
if (!this.deposit.isNoOp())
{
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
// if we get this far, then we just use the dspace url as the
// property
String cfg = ConfigurationManager.getProperty("dspace.url");
entry.setId(cfg);
if (StringUtils.isNotBlank(handle))
{
entry.setId(handleService.getCanonicalForm(handle));
return;
}
}
// FIXME: later on we will maybe have a workflow page supplied
// by the sword interface?
}
// if we get this far, then we just use the dspace url as the
// property
String cfg = ConfigurationManager.getProperty("dspace.url");
entry.setId(cfg);
/**
* Add links associated with this item.
*
*/
protected void addLinks()
throws DSpaceSWORDException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
// FIXME: later on we will maybe have a workflow page supplied
// by the sword interface?
}
try
{
// if there is no handle, we can't generate links
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
else
{
return;
}
/**
* Add links associated with this item.
*
*/
protected void addLinks()
throws DSpaceSWORDException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
// link to all the files in the item
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles) {
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) {
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss) {
Link link = new Link();
String url = urlManager.getBitstreamUrl(bs.getBitstream());
link.setHref(url);
link.setRel("part");
try
{
// if there is no handle, we can't generate links
String handle = "";
if (item.getHandle() != null)
{
handle = item.getHandle();
}
else
{
return;
}
BitstreamFormat bsf = bs.getBitstream().getFormat(swordService.getContext());
if (bsf != null) {
link.setType(bsf.getMIMEType());
}
// link to all the files in the item
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss)
{
Link link = new Link();
String url = urlManager
.getBitstreamUrl(bs.getBitstream());
link.setHref(url);
link.setRel("part");
entry.addLink(link);
}
break;
}
}
BitstreamFormat bsf = bs.getBitstream()
.getFormat(swordService.getContext());
if (bsf != null)
{
link.setType(bsf.getMIMEType());
}
// link to the item splash page
Link splash = new Link();
splash.setHref(handleService.getCanonicalForm(handle));
splash.setRel("alternate");
splash.setType("text/html");
entry.addLink(splash);
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
entry.addLink(link);
}
break;
}
}
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate()
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.date.issued");
if (dcv != null && !dcv.isEmpty())
// link to the item splash page
Link splash = new Link();
splash.setHref(handleService.getCanonicalForm(handle));
splash.setRel("alternate");
splash.setType("text/html");
entry.addLink(splash);
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate()
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.date.issued");
if (dcv != null && !dcv.isEmpty())
{
entry.setPublished(dcv.get(0).getValue());
}
}
}
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
protected void addRights()
throws DSpaceSWORDException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Add rights information. This attaches an href to the URL
* of the item's licence file
*
*/
protected void addRights()
throws DSpaceSWORDException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
String handle = this.item.getHandle();
String handle = this.item.getHandle();
// if there's no handle, we can't give a link
if (StringUtils.isBlank(handle))
// if there's no handle, we can't give a link
if (StringUtils.isBlank(handle))
{
return;
}
String base = ConfigurationManager.getProperty("dspace.url");
String base = ConfigurationManager.getProperty("dspace.url");
// if there's no base URL, we are stuck
if (base == null)
// if there's no base URL, we are stuck
if (base == null)
{
return;
}
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles) {
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName()))
{
{
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss)
{
{
String url = urlManager.getBitstreamUrl(bs.getBitstream());
rightsString.append(url).append(" ");
}
@@ -281,62 +304,66 @@ public class ItemEntryGenerator extends DSpaceATOMEntry
}
}
Rights rights = new Rights();
rights.setContent(rightsString.toString());
rights.setType(ContentType.TEXT);
entry.setRights(rights);
}
Rights rights = new Rights();
rights.setContent(rightsString.toString());
rights.setType(ContentType.TEXT);
entry.setRights(rights);
}
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
protected void addSummary()
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.description.abstract");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
Summary summary = new Summary();
summary.setContent(aDcv.getValue());
summary.setType(ContentType.TEXT);
entry.setSummary(summary);
}
}
}
/**
* Add the summary/abstract from the bibliographic metadata
*
*/
protected void addSummary()
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.description.abstract");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
Summary summary = new Summary();
summary.setContent(aDcv.getValue());
summary.setType(ContentType.TEXT);
entry.setSummary(summary);
}
}
}
/**
* Add the title from the bibliographic metadata
*
*/
protected void addTitle()
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.title");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
Title title = new Title();
title.setContent(aDcv.getValue());
title.setType(ContentType.TEXT);
entry.setTitle(title);
}
}
}
/**
* Add the title from the bibliographic metadata
*
*/
protected void addTitle()
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.title");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
Title title = new Title();
title.setContent(aDcv.getValue());
title.setType(ContentType.TEXT);
entry.setTitle(title);
}
}
}
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate()
{
String config = ConfigurationManager.getProperty("sword-server", "updated.field");
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, config);
if (dcv != null && dcv.size() == 1)
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate()
{
String config = ConfigurationManager
.getProperty("sword-server", "updated.field");
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, config);
if (dcv != null && dcv.size() == 1)
{
DCDate dcd = new DCDate(dcv.get(0).getValue());
entry.setUpdated(dcd.toString());
}
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -32,10 +32,11 @@ public class LoadDSpaceConfig extends HttpServlet
{
public void init()
{
if(!ConfigurationManager.isConfigured())
if (!ConfigurationManager.isConfigured())
{
// Get config parameter
String config = getServletContext().getInitParameter("dspace-config");
String config = getServletContext()
.getInitParameter("dspace-config");
// Load in DSpace config
ConfigurationManager.loadConfig(config);

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -21,53 +21,56 @@ import org.dspace.content.Bitstream;
*/
public class MediaEntryManager
{
/** sword service implementation */
private SWORDService swordService;
/** sword service implementation */
private SWORDService swordService;
public MediaEntryManager(SWORDService swordService)
{
this.swordService = swordService;
}
public MediaEntryManager(SWORDService swordService)
{
this.swordService = swordService;
}
/**
* Get the media entry for the given URL request. If the URL is
* unavailable this method will throw the appropriate SWORD errors,
* with DSpace custom URLs.
*
* @param url
* @throws DSpaceSWORDException
* @throws SWORDErrorException
*/
public AtomDocumentResponse getMediaEntry(String url)
throws DSpaceSWORDException, SWORDErrorException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Get the media entry for the given URL request. If the URL is
* unavailable this method will throw the appropriate SWORD errors,
* with DSpace custom URLs.
*
* @param url
* @throws DSpaceSWORDException
* @throws SWORDErrorException
*/
public AtomDocumentResponse getMediaEntry(String url)
throws DSpaceSWORDException, SWORDErrorException
{
SWORDUrlManager urlManager = swordService.getUrlManager();
AtomDocumentResponse response = new AtomDocumentResponse(200);
AtomDocumentResponse response = new AtomDocumentResponse(200);
if (url == null || urlManager.isBaseMediaLinkUrl(url))
{
// we are dealing with a default media-link, indicating that something
// is wrong
if (url == null || urlManager.isBaseMediaLinkUrl(url))
{
// we are dealing with a default media-link, indicating that something
// is wrong
// FIXME: what do we actually do about this situation?
// throwing an error for the time being
throw new SWORDErrorException(DSpaceSWORDErrorCodes.MEDIA_UNAVAILABLE, "The media link you requested is not available");
}
// FIXME: what do we actually do about this situation?
// throwing an error for the time being
throw new SWORDErrorException(
DSpaceSWORDErrorCodes.MEDIA_UNAVAILABLE,
"The media link you requested is not available");
}
// extract the thing that we are trying to get a media entry on
DSpaceObject dso = urlManager.extractDSpaceObject(url);
// extract the thing that we are trying to get a media entry on
DSpaceObject dso = urlManager.extractDSpaceObject(url);
// now, the media entry should always be to an actual file, so we only care that this is a bitstream
if (!(dso instanceof Bitstream))
{
throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, "The url you provided does not resolve to an appropriate object");
}
// now, the media entry should always be to an actual file, so we only care that this is a bitstream
if (!(dso instanceof Bitstream))
{
throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL,
"The url you provided does not resolve to an appropriate object");
}
// now construct the atom entry for the bitstream
DSpaceATOMEntry dsatom = new BitstreamEntryGenerator(swordService);
SWORDEntry entry = dsatom.getSWORDEntry(dso);
response.setEntry(entry);
return response;
}
// now construct the atom entry for the bitstream
DSpaceATOMEntry dsatom = new BitstreamEntryGenerator(swordService);
SWORDEntry entry = dsatom.getSWORDEntry(dso);
response.setEntry(entry);
return response;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -22,19 +22,20 @@ import org.dspace.authenticate.AuthenticationMethod;
*/
public class SWORDAuthentication
{
/**
* Does the given username and password authenticate for the
* given DSpace Context?
*
* @param context
* @param un
* @param pw
* @return true if yes, false if not
*/
public boolean authenticates(Context context, String un, String pw)
{
AuthenticationService authService = AuthenticateServiceFactory.getInstance().getAuthenticationService();
int auth = authService.authenticate(context, un, pw, null, null);
return auth == AuthenticationMethod.SUCCESS;
}
/**
* Does the given username and password authenticate for the
* given DSpace Context?
*
* @param context
* @param un
* @param pw
* @return true if yes, false if not
*/
public boolean authenticates(Context context, String un, String pw)
{
AuthenticationService authService = AuthenticateServiceFactory
.getInstance().getAuthenticationService();
int auth = authService.authenticate(context, un, pw, null, null);
return auth == AuthenticationMethod.SUCCESS;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -46,71 +46,80 @@ public class SWORDConfiguration
{
/** logger */
public static final Logger log = Logger.getLogger(SWORDConfiguration.class);
public static final Logger log = Logger.getLogger(SWORDConfiguration.class);
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
/** whether we can support noOp */
private boolean noOp = true;
/** whether we can support noOp */
private boolean noOp = true;
/** whether we can be verbose */
private boolean verbose = true;
/** whether we can be verbose */
private boolean verbose = true;
/** what our default max upload size is */
private int maxUploadSize = -1;
/** what our default max upload size is */
private int maxUploadSize = -1;
/** do we support mediation */
private boolean mediated = false;
/** do we support mediation */
private boolean mediated = false;
/** should we keep the original package as bitstream */
private boolean keepOriginal = false;
/** should we keep the original package as bitstream */
private boolean keepOriginal = false;
/** item bundle in which sword deposits are stored */
private String swordBundle = "SWORD";
/** item bundle in which sword deposits are stored */
private String swordBundle = "SWORD";
/** should we keep the original package as a file on ingest error */
private boolean keepPackageOnFailedIngest = false;
/** should we keep the original package as a file on ingest error */
private boolean keepPackageOnFailedIngest = false;
/** location of directory to store packages on ingest error */
private String failedPackageDir = null;
/** location of directory to store packages on ingest error */
private String failedPackageDir = null;
/** Accepted formats */
private List<String> swordaccepts;
/**
* Initialise the sword configuration. It is at this stage that the
* object will interrogate the DSpace Configuration for details
*/
public SWORDConfiguration()
{
// set the max upload size
int mus = ConfigurationManager.getIntProperty("sword-server", "max-upload-size");
if (mus > 0)
{
this.maxUploadSize = mus;
}
/**
* Initialise the sword configuration. It is at this stage that the
* object will interrogate the DSpace Configuration for details
*/
public SWORDConfiguration()
{
// set the max upload size
int mus = ConfigurationManager
.getIntProperty("sword-server", "max-upload-size");
if (mus > 0)
{
this.maxUploadSize = mus;
}
// set the mediation value
this.mediated = ConfigurationManager.getBooleanProperty("sword-server", "on-behalf-of.enable");
// set the mediation value
this.mediated = ConfigurationManager
.getBooleanProperty("sword-server", "on-behalf-of.enable");
// find out if we keep the original as bitstream
this.keepOriginal = ConfigurationManager.getBooleanProperty("sword-server", "keep-original-package");
// find out if we keep the original as bitstream
this.keepOriginal = ConfigurationManager
.getBooleanProperty("sword-server", "keep-original-package");
// get the sword bundle
String bundle = ConfigurationManager.getProperty("sword-server", "bundle.name");
if (bundle != null && "".equals(bundle))
{
this.swordBundle = bundle;
}
// get the sword bundle
String bundle = ConfigurationManager
.getProperty("sword-server", "bundle.name");
if (bundle != null && "".equals(bundle))
{
this.swordBundle = bundle;
}
// find out if we keep the package as a file in specified directory
this.keepPackageOnFailedIngest = ConfigurationManager.getBooleanProperty("sword-server", "keep-package-on-fail", false);
this.keepPackageOnFailedIngest = ConfigurationManager
.getBooleanProperty("sword-server", "keep-package-on-fail",
false);
// get directory path and name
this.failedPackageDir = ConfigurationManager.getProperty("sword-server", "failed-package.dir");
this.failedPackageDir = ConfigurationManager
.getProperty("sword-server", "failed-package.dir");
// Get the accepted formats
String acceptsProperty = ConfigurationManager.getProperty("sword-server", "accepts");
String acceptsProperty = ConfigurationManager
.getProperty("sword-server", "accepts");
swordaccepts = new ArrayList<String>();
if (acceptsProperty == null)
{
@@ -120,229 +129,231 @@ public class SWORDConfiguration
{
swordaccepts.add(element.trim());
}
}
/**
* Get the bundle name that SWORD will store its original deposit
* packages in, when storing them inside an item.
*/
public String getSwordBundle()
{
return swordBundle;
}
/**
* Set the bundle name that sword will store its original deposit
* packages in, when storing them inside an item.
* @param swordBundle
*/
public void setSwordBundle(String swordBundle)
{
this.swordBundle = swordBundle;
}
/**
* Is this a no-op deposit?
*/
public boolean isNoOp()
{
return noOp;
}
/**
* Set whether this is a no-op deposit.
*
* @param noOp
*/
public void setNoOp(boolean noOp)
{
this.noOp = noOp;
}
/**
* Is this a verbose deposit?
*/
public boolean isVerbose()
{
return verbose;
}
/**
* Set whether this is a verbose deposit.
* @param verbose
*/
public void setVerbose(boolean verbose)
{
this.verbose = verbose;
}
/**
* What is the max upload size (in bytes) for the sword interface?
*/
public int getMaxUploadSize()
{
return maxUploadSize;
}
/**
* set the max uplaod size (in bytes) for the sword interface
* @param maxUploadSize
*/
public void setMaxUploadSize(int maxUploadSize)
{
this.maxUploadSize = maxUploadSize;
}
/**
* Does the server support mediated deposit (aka on-behalf-of)?
*/
public boolean isMediated()
{
return mediated;
}
/**
* Set whether the server supports mediated deposit (aka on-behalf-of).
* @param mediated
*/
public void setMediated(boolean mediated)
{
this.mediated = mediated;
}
/**
* Should the repository keep the original package?
*/
public boolean isKeepOriginal()
{
return keepOriginal;
}
/**
* Set whether the repository should keep copies of the original package.
* @param keepOriginal
*/
public void setKeepOriginal(boolean keepOriginal)
{
this.keepOriginal = keepOriginal;
}
/**
* set whether the repository should write file of the original package if ingest fails
* @param keepOriginalOnFail
*/
public void setKeepPackageOnFailedIngest(boolean keepOriginalOnFail)
{
keepPackageOnFailedIngest = keepOriginalOnFail;
}
}
/**
* should the repository write file of the original package if ingest fails
* @return keepPackageOnFailedIngest
*/
public boolean isKeepPackageOnFailedIngest()
{
return keepPackageOnFailedIngest;
}
* Get the bundle name that SWORD will store its original deposit
* packages in, when storing them inside an item.
*/
public String getSwordBundle()
{
return swordBundle;
}
/**
* set the directory to write file of the original package
* @param dir
*/
public void setFailedPackageDir(String dir)
{
failedPackageDir = dir;
}
/**
* Set the bundle name that sword will store its original deposit
* packages in, when storing them inside an item.
* @param swordBundle
*/
public void setSwordBundle(String swordBundle)
{
this.swordBundle = swordBundle;
}
/**
* directory location of the files with original packages
/**
* Is this a no-op deposit?
*/
public boolean isNoOp()
{
return noOp;
}
/**
* Set whether this is a no-op deposit.
*
* @param noOp
*/
public void setNoOp(boolean noOp)
{
this.noOp = noOp;
}
/**
* Is this a verbose deposit?
*/
public boolean isVerbose()
{
return verbose;
}
/**
* Set whether this is a verbose deposit.
* @param verbose
*/
public void setVerbose(boolean verbose)
{
this.verbose = verbose;
}
/**
* What is the max upload size (in bytes) for the sword interface?
*/
public int getMaxUploadSize()
{
return maxUploadSize;
}
/**
* set the max uplaod size (in bytes) for the sword interface
* @param maxUploadSize
*/
public void setMaxUploadSize(int maxUploadSize)
{
this.maxUploadSize = maxUploadSize;
}
/**
* Does the server support mediated deposit (aka on-behalf-of)?
*/
public boolean isMediated()
{
return mediated;
}
/**
* Set whether the server supports mediated deposit (aka on-behalf-of).
* @param mediated
*/
public void setMediated(boolean mediated)
{
this.mediated = mediated;
}
/**
* Should the repository keep the original package?
*/
public boolean isKeepOriginal()
{
return keepOriginal;
}
/**
* Set whether the repository should keep copies of the original package.
* @param keepOriginal
*/
public void setKeepOriginal(boolean keepOriginal)
{
this.keepOriginal = keepOriginal;
}
/**
* set whether the repository should write file of the original package if ingest fails
* @param keepOriginalOnFail
*/
public void setKeepPackageOnFailedIngest(boolean keepOriginalOnFail)
{
keepPackageOnFailedIngest = keepOriginalOnFail;
}
/**
* should the repository write file of the original package if ingest fails
* @return keepPackageOnFailedIngest
*/
public boolean isKeepPackageOnFailedIngest()
{
return keepPackageOnFailedIngest;
}
/**
* set the directory to write file of the original package
* @param dir
*/
public void setFailedPackageDir(String dir)
{
failedPackageDir = dir;
}
/**
* directory location of the files with original packages
* for failed ingests
* @return failedPackageDir
*/
public String getFailedPackageDir()
{
return failedPackageDir;
}
* @return failedPackageDir
*/
public String getFailedPackageDir()
{
return failedPackageDir;
}
/**
* Get the list of mime types that the given dspace object will
* accept as packages.
*
* @param context
* @param dso
* @throws DSpaceSWORDException
*/
public List<String> getAccepts(Context context, DSpaceObject dso)
throws DSpaceSWORDException
{
try
{
List<String> accepts = new ArrayList<String>();
if (dso instanceof Collection)
{
for (String format : swordaccepts)
/**
* Get the list of mime types that the given dspace object will
* accept as packages.
*
* @param context
* @param dso
* @throws DSpaceSWORDException
*/
public List<String> getAccepts(Context context, DSpaceObject dso)
throws DSpaceSWORDException
{
try
{
List<String> accepts = new ArrayList<String>();
if (dso instanceof Collection)
{
for (String format : swordaccepts)
{
accepts.add(format);
}
}
else if (dso instanceof Item)
{
List<BitstreamFormat> bfs = bitstreamFormatService.findNonInternal(context);
for (BitstreamFormat bf : bfs) {
accepts.add(bf.getMIMEType());
}
}
}
else if (dso instanceof Item)
{
List<BitstreamFormat> bfs = bitstreamFormatService
.findNonInternal(context);
for (BitstreamFormat bf : bfs)
{
accepts.add(bf.getMIMEType());
}
}
return accepts;
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
return accepts;
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
/**
* Get the list of mime types that a Collection will accept as packages
*
* @return the list of mime types
* @throws DSpaceSWORDException
*/
public List<String> getCollectionAccepts() throws DSpaceSWORDException
{
* Get the list of mime types that a Collection will accept as packages
*
* @return the list of mime types
* @throws DSpaceSWORDException
*/
public List<String> getCollectionAccepts() throws DSpaceSWORDException
{
List<String> accepts = new ArrayList<String>();
for (String format : swordaccepts)
{
accepts.add(format);
}
return accepts;
}
}
/**
* Get a map of packaging URIs to Q values for the packaging types which
* the given collection will accept.
*
* The URI should be a unique identifier for the packaging type,
* such as:
*
* http://purl.org/net/sword-types/METSDSpaceSIP
*
* and the Q value is a floating point between 0 and 1 which defines
* how much the server "likes" this packaging type
*
* @param col
*/
public Map<String, Float> getAcceptPackaging(Collection col)
/**
* Get a map of packaging URIs to Q values for the packaging types which
* the given collection will accept.
*
* The URI should be a unique identifier for the packaging type,
* such as:
*
* http://purl.org/net/sword-types/METSDSpaceSIP
*
* and the Q value is a floating point between 0 and 1 which defines
* how much the server "likes" this packaging type
*
* @param col
*/
public Map<String, Float> getAcceptPackaging(Collection col)
{
Map<String, String> identifiers = new HashMap<String, String>();
Map<String, String> qs = new HashMap<String, String>();
String handle = col.getHandle();
String handle = col.getHandle();
// build the holding maps of identifiers and q values
// build the holding maps of identifiers and q values
Properties props = ConfigurationManager.getProperties("sword-server");
Set keyset = props.keySet();
for (Object keyObj : keyset)
{
String sw = "accept-packaging.";
String sw = "accept-packaging.";
if (!(keyObj instanceof String))
{
@@ -355,7 +366,7 @@ public class SWORDConfiguration
continue;
}
// extract the configuration into the holding Maps
// extract the configuration into the holding Maps
String suffix = key.substring(sw.length());
String[] bits = suffix.split("\\.");
@@ -389,78 +400,82 @@ public class SWORDConfiguration
}
}
// merge the holding maps into the Accept Packaging settings
Map<String, Float> ap = new HashMap<String, Float>();
for (String ik : identifiers.keySet())
{
String id = identifiers.get(ik);
String qv = qs.get(ik);
Float qf = Float.parseFloat(qv);
ap.put(id, qf);
}
// merge the holding maps into the Accept Packaging settings
Map<String, Float> ap = new HashMap<String, Float>();
for (String ik : identifiers.keySet())
{
String id = identifiers.get(ik);
String qv = qs.get(ik);
Float qf = Float.parseFloat(qv);
ap.put(id, qf);
}
return ap;
return ap;
}
/**
* Is the given packaging/media type supported by the given DSpace
* object?
*
* @param mediaType
* @param dso
* @throws DSpaceSWORDException
* @throws SWORDErrorException
*/
public boolean isSupportedMediaType(String mediaType, DSpaceObject dso)
throws DSpaceSWORDException, SWORDErrorException
{
if (mediaType == null || "".equals(mediaType))
{
return true;
}
/**
* Is the given packaging/media type supported by the given DSpace
* object?
*
* @param mediaType
* @param dso
* @throws DSpaceSWORDException
* @throws SWORDErrorException
*/
public boolean isSupportedMediaType(String mediaType, DSpaceObject dso)
throws DSpaceSWORDException, SWORDErrorException
{
if (mediaType == null || "".equals(mediaType))
{
return true;
}
if (dso instanceof Collection)
{
Map<String, Float> accepts = this.getAcceptPackaging((Collection) dso);
for (String accept : accepts.keySet())
{
if (accept.equals(mediaType))
{
return true;
}
}
}
else if (dso instanceof Item)
{
// items don't unpackage, so they don't care what the media type is
return true;
}
return false;
}
if (dso instanceof Collection)
{
Map<String, Float> accepts = this
.getAcceptPackaging((Collection) dso);
for (String accept : accepts.keySet())
{
if (accept.equals(mediaType))
{
return true;
}
}
}
else if (dso instanceof Item)
{
// items don't unpackage, so they don't care what the media type is
return true;
}
return false;
}
/**
* Is the given content MIME type acceptable to the given DSpace object?
* @param context
* @param type
* @param dso
* @throws DSpaceSWORDException
*/
public boolean isAcceptableContentType(Context context, String type, DSpaceObject dso)
throws DSpaceSWORDException
{
List<String> accepts = this.getAccepts(context, dso);
return accepts.contains(type);
}
/**
* Is the given content MIME type acceptable to the given DSpace object?
* @param context
* @param type
* @param dso
* @throws DSpaceSWORDException
*/
public boolean isAcceptableContentType(Context context, String type,
DSpaceObject dso)
throws DSpaceSWORDException
{
List<String> accepts = this.getAccepts(context, dso);
return accepts.contains(type);
}
/**
* Get the temp directory for storing files during deposit.
*
* @throws DSpaceSWORDException
*/
public String getTempDir()
throws DSpaceSWORDException
{
return (ConfigurationManager.getProperty("upload.temp.dir") != null)
? ConfigurationManager.getProperty("upload.temp.dir") : System.getProperty("java.io.tmpdir");
}
/**
* Get the temp directory for storing files during deposit.
*
* @throws DSpaceSWORDException
*/
public String getTempDir()
throws DSpaceSWORDException
{
return (ConfigurationManager.getProperty("upload.temp.dir") != null)
?
ConfigurationManager.getProperty("upload.temp.dir") :
System.getProperty("java.io.tmpdir");
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -37,151 +37,151 @@ import org.dspace.eperson.EPerson;
*/
public class SWORDContext
{
/** The primary authenticated user for the request */
private EPerson authenticated = null;
/** The primary authenticated user for the request */
private EPerson authenticated = null;
/** The onBehalfOf user for the request */
private EPerson onBehalfOf = null;
/** The onBehalfOf user for the request */
private EPerson onBehalfOf = null;
/** The primary context, representing the on behalf of user if exists, and the authenticated user if not */
private Context context;
/** The primary context, representing the on behalf of user if exists, and the authenticated user if not */
private Context context;
/** the context for the authenticated user, which may not, therefore, be the primary context also */
private Context authenticatorContext;
/** the context for the authenticated user, which may not, therefore, be the primary context also */
private Context authenticatorContext;
/**
* @return the authenticated user
*/
public EPerson getAuthenticated()
{
return authenticated;
}
/**
* @return the authenticated user
*/
public EPerson getAuthenticated()
{
return authenticated;
}
/**
* @param authenticated the eperson to set
*/
public void setAuthenticated(EPerson authenticated)
{
this.authenticated = authenticated;
}
/**
* @param authenticated the eperson to set
*/
public void setAuthenticated(EPerson authenticated)
{
this.authenticated = authenticated;
}
/**
* @return the onBehalfOf user
*/
public EPerson getOnBehalfOf()
{
return onBehalfOf;
}
/**
* @return the onBehalfOf user
*/
public EPerson getOnBehalfOf()
{
return onBehalfOf;
}
/**
* @param onBehalfOf the eperson to set
*/
public void setOnBehalfOf(EPerson onBehalfOf)
{
this.onBehalfOf = onBehalfOf;
}
/**
* @param onBehalfOf the eperson to set
*/
public void setOnBehalfOf(EPerson onBehalfOf)
{
this.onBehalfOf = onBehalfOf;
}
/**
* Returns the most appropriate context for operations on the
* database. This is the on-behalf-of user's context if the
* user exists, or the authenticated user's context otherwise.
*/
public Context getContext()
{
return context;
}
/**
* Returns the most appropriate context for operations on the
* database. This is the on-behalf-of user's context if the
* user exists, or the authenticated user's context otherwise.
*/
public Context getContext()
{
return context;
}
public void setContext(Context context)
{
this.context = context;
}
public void setContext(Context context)
{
this.context = context;
}
/**
* Get the context of the user who authenticated. This should only be
* used for authentication purposes. If there is an on-behalf-of user,
* that context should be used to write database changes. Use:
*
* getContext()
*
* on this class instead.
*/
public Context getAuthenticatorContext()
{
return authenticatorContext;
}
/**
* Get the context of the user who authenticated. This should only be
* used for authentication purposes. If there is an on-behalf-of user,
* that context should be used to write database changes. Use:
*
* getContext()
*
* on this class instead.
*/
public Context getAuthenticatorContext()
{
return authenticatorContext;
}
public void setAuthenticatorContext(Context authenticatorContext)
{
this.authenticatorContext = authenticatorContext;
}
public void setAuthenticatorContext(Context authenticatorContext)
{
this.authenticatorContext = authenticatorContext;
}
/**
* Get the context of the on-behalf-of user. This method should only
* be used for authentication purposes. In all other cases, use:
*
* getContext()
*
* on this class instead. If there is no on-behalf-of user, this
* method will return null.
*/
public Context getOnBehalfOfContext()
{
// return the obo context if this is an obo deposit, else return null
if (this.onBehalfOf != null)
{
return context;
}
return null;
}
/**
* Get the context of the on-behalf-of user. This method should only
* be used for authentication purposes. In all other cases, use:
*
* getContext()
*
* on this class instead. If there is no on-behalf-of user, this
* method will return null.
*/
public Context getOnBehalfOfContext()
{
// return the obo context if this is an obo deposit, else return null
if (this.onBehalfOf != null)
{
return context;
}
return null;
}
/**
* Abort all of the contexts held by this class. No changes will
* be written to the database
*/
public void abort()
{
// abort both contexts
if (context != null && context.isValid())
{
context.abort();
}
/**
* Abort all of the contexts held by this class. No changes will
* be written to the database
*/
public void abort()
{
// abort both contexts
if (context != null && context.isValid())
{
context.abort();
}
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
/**
* Commit the primary context held by this class, and abort the authenticated
* user's context if it is different. This ensures that only changes written
* through the appropriate user's context is persisted, and all other
* operations are flushed. You should, in general, not try to commit the contexts directly
* when using the sword api.
*
* @throws DSpaceSWORDException
*/
public void commit()
throws DSpaceSWORDException
{
try
{
// commit the primary context
if (context != null && context.isValid())
{
context.complete();
}
/**
* Commit the primary context held by this class, and abort the authenticated
* user's context if it is different. This ensures that only changes written
* through the appropriate user's context is persisted, and all other
* operations are flushed. You should, in general, not try to commit the contexts directly
* when using the sword api.
*
* @throws DSpaceSWORDException
*/
public void commit()
throws DSpaceSWORDException
{
try
{
// commit the primary context
if (context != null && context.isValid())
{
context.complete();
}
// the secondary context is for filtering permissions by only, and is
// never committed, so we abort here
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
// the secondary context is for filtering permissions by only, and is
// never committed, so we abort here
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -22,13 +22,15 @@ import org.purl.sword.base.SWORDErrorException;
*/
public interface SWORDIngester
{
/**
* Ingest the package as described in the given Deposit object
* within the given DSpace Context
*
* @param deposit
* @return the result of the deposit
* @throws DSpaceSWORDException
*/
DepositResult ingest(SWORDService service, Deposit deposit, DSpaceObject target) throws DSpaceSWORDException, SWORDErrorException;
/**
* Ingest the package as described in the given Deposit object
* within the given DSpace Context
*
* @param deposit
* @return the result of the deposit
* @throws DSpaceSWORDException
*/
DepositResult ingest(SWORDService service, Deposit deposit,
DSpaceObject target)
throws DSpaceSWORDException, SWORDErrorException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -26,42 +26,50 @@ import org.purl.sword.base.ErrorCodes;
*/
public class SWORDIngesterFactory
{
/**
* Generate an object which conforms to the SWORDIngester interface.
* This Factory method may use the given DSpace context and the given
* SWORD Deposit request to decide on the most appropriate implementation
* of the interface to return.
*
* To configure how this method will respond, configure the package ingester
* for the appropriate media types and defaults. See the sword configuration
* documentation for more details.
*
* @param context
* @param deposit
* @throws DSpaceSWORDException
*/
public static SWORDIngester getInstance(Context context, Deposit deposit, DSpaceObject dso)
/**
* Generate an object which conforms to the SWORDIngester interface.
* This Factory method may use the given DSpace context and the given
* SWORD Deposit request to decide on the most appropriate implementation
* of the interface to return.
*
* To configure how this method will respond, configure the package ingester
* for the appropriate media types and defaults. See the sword configuration
* documentation for more details.
*
* @param context
* @param deposit
* @throws DSpaceSWORDException
*/
public static SWORDIngester getInstance(Context context, Deposit deposit,
DSpaceObject dso)
throws DSpaceSWORDException, SWORDErrorException
{
if (dso instanceof Collection)
{
SWORDIngester ingester = (SWORDIngester) PluginManager.getNamedPlugin("sword-server", SWORDIngester.class, deposit.getPackaging());
if (ingester == null)
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT, "No ingester configured for this package type");
}
return ingester;
}
else if (dso instanceof Item)
{
SWORDIngester ingester = (SWORDIngester) PluginManager.getNamedPlugin("sword-server", SWORDIngester.class, "SimpleFileIngester");
if (ingester == null)
{
throw new DSpaceSWORDException("SimpleFileIngester is not configured in plugin manager");
}
return ingester;
}
if (dso instanceof Collection)
{
SWORDIngester ingester = (SWORDIngester) PluginManager
.getNamedPlugin("sword-server", SWORDIngester.class,
deposit.getPackaging());
if (ingester == null)
{
throw new SWORDErrorException(ErrorCodes.ERROR_CONTENT,
"No ingester configured for this package type");
}
return ingester;
}
else if (dso instanceof Item)
{
SWORDIngester ingester = (SWORDIngester) PluginManager
.getNamedPlugin("sword-server", SWORDIngester.class,
"SimpleFileIngester");
if (ingester == null)
{
throw new DSpaceSWORDException(
"SimpleFileIngester is not configured in plugin manager");
}
return ingester;
}
throw new DSpaceSWORDException("No ingester could be found which works for this DSpace Object");
}
throw new DSpaceSWORDException(
"No ingester could be found which works for this DSpace Object");
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -32,127 +32,148 @@ import org.purl.sword.base.SWORDErrorException;
public class SWORDMETSIngester implements SWORDIngester
{
private SWORDService swordService;
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
private SWORDService swordService;
/** Log4j logger */
public static final Logger log = Logger.getLogger(SWORDMETSIngester.class);
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
/* (non-Javadoc)
* @see org.dspace.sword.SWORDIngester#ingest(org.dspace.core.Context, org.purl.sword.base.Deposit)
*/
public DepositResult ingest(SWORDService service, Deposit deposit, DSpaceObject dso)
throws DSpaceSWORDException, SWORDErrorException
{
try
{
// first, make sure this is the right kind of ingester, and set the collection
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException("Tried to run an ingester on wrong target type");
}
Collection collection = (Collection) dso;
/** Log4j logger */
public static final Logger log = Logger.getLogger(SWORDMETSIngester.class);
// now set the sword service
swordService = service;
/* (non-Javadoc)
* @see org.dspace.sword.SWORDIngester#ingest(org.dspace.core.Context, org.purl.sword.base.Deposit)
*/
public DepositResult ingest(SWORDService service, Deposit deposit,
DSpaceObject dso)
throws DSpaceSWORDException, SWORDErrorException
{
try
{
// first, make sure this is the right kind of ingester, and set the collection
if (!(dso instanceof Collection))
{
throw new DSpaceSWORDException(
"Tried to run an ingester on wrong target type");
}
Collection collection = (Collection) dso;
// get the things out of the service that we need
Context context = swordService.getContext();
// now set the sword service
swordService = service;
// get deposited file as InputStream
File depositFile = deposit.getFile();
// get the things out of the service that we need
Context context = swordService.getContext();
// load the plugin manager for the required configuration
String cfg = ConfigurationManager.getProperty("sword-server", "mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
swordService.message("Using package manifest format: " + cfg);
// get deposited file as InputStream
File depositFile = deposit.getFile();
PackageIngester pi = (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, cfg);
swordService.message("Loaded package ingester: " + pi.getClass().getName());
// load the plugin manager for the required configuration
String cfg = ConfigurationManager.getProperty("sword-server",
"mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
swordService.message("Using package manifest format: " + cfg);
// the licence is either in the zip or the mets manifest. Either way
// it's none of our business here
String licence = null;
PackageIngester pi = (PackageIngester) PluginManager
.getNamedPlugin(PackageIngester.class, cfg);
swordService.message(
"Loaded package ingester: " + pi.getClass().getName());
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// the licence is either in the zip or the mets manifest. Either way
// it's none of our business here
String licence = null;
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// Force package ingester to respect Collection workflows
params.setWorkflowEnabled(true);
// Should restore mode be enabled, i.e. keep existing handle?
if (ConfigurationManager.getBooleanProperty("sword-server", "restore-mode.enable",false))
if (ConfigurationManager
.getBooleanProperty("sword-server", "restore-mode.enable",
false))
{
params.setRestoreModeEnabled(true);
}
// Whether or not to use the collection template
params.setUseCollectionTemplate(ConfigurationManager.getBooleanProperty("mets.default.ingest.useCollectionTemplate", false));
params.setUseCollectionTemplate(ConfigurationManager
.getBooleanProperty(
"mets.default.ingest.useCollectionTemplate",
false));
// ingest the item from the temp file
DSpaceObject ingestedObject = pi.ingest(context, collection, depositFile, params, licence);
if (ingestedObject == null)
{
swordService.message("Failed to ingest the package; throwing exception");
throw new SWORDErrorException(DSpaceSWORDErrorCodes.UNPACKAGE_FAIL, "METS package ingester failed to unpack package");
}
// ingest the item from the temp file
DSpaceObject ingestedObject = pi
.ingest(context, collection, depositFile, params, licence);
if (ingestedObject == null)
{
swordService.message(
"Failed to ingest the package; throwing exception");
throw new SWORDErrorException(
DSpaceSWORDErrorCodes.UNPACKAGE_FAIL,
"METS package ingester failed to unpack package");
}
//Verify we have an Item as a result -- SWORD can only ingest Items
if (!(ingestedObject instanceof Item))
{
throw new DSpaceSWORDException("DSpace Ingester returned wrong object type -- not an Item result.");
}
else
{
//otherwise, we have an item, and a workflow should have already been started for it.
swordService.message("Workflow process started");
}
//Verify we have an Item as a result -- SWORD can only ingest Items
if (!(ingestedObject instanceof Item))
{
throw new DSpaceSWORDException(
"DSpace Ingester returned wrong object type -- not an Item result.");
}
else
{
//otherwise, we have an item, and a workflow should have already been started for it.
swordService.message("Workflow process started");
}
// get reference to item so that we can report on it
Item installedItem = (Item)ingestedObject;
// get reference to item so that we can report on it
Item installedItem = (Item) ingestedObject;
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(installedItem, deposit.getSlug());
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(installedItem, deposit.getSlug());
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
String handle = handleService.findHandle(context, installedItem);
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
String handle = handleService.findHandle(context, installedItem);
swordService.message("Ingest successful");
swordService.message("Item created with internal identifier: " + installedItem.getID());
if (handle != null)
{
swordService.message("Item created with external identifier: " + handle);
}
else
{
swordService.message("No external identifier available at this stage (item in workflow)");
}
swordService.message("Ingest successful");
swordService.message("Item created with internal identifier: " +
installedItem.getID());
if (handle != null)
{
swordService.message(
"Item created with external identifier: " + handle);
}
else
{
swordService.message(
"No external identifier available at this stage (item in workflow)");
}
DepositResult dr = new DepositResult();
dr.setItem(installedItem);
dr.setHandle(handle);
dr.setTreatment(this.getTreatment());
DepositResult dr = new DepositResult();
dr.setItem(installedItem);
dr.setHandle(handle);
dr.setTreatment(this.getTreatment());
return dr;
}
return dr;
}
catch (RuntimeException re)
{
log.error("caught exception: ", re);
@@ -165,123 +186,142 @@ public class SWORDMETSIngester implements SWORDIngester
}
}
/**
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSWORDException
*/
private void setUpdatedDate(Context context, Item item)
throws DSpaceSWORDException
{
String field = ConfigurationManager.getProperty("sword-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSWORDException("No configuration, or configuration is invalid for: sword.updated.field");
}
/**
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSWORDException
*/
private void setUpdatedDate(Context context, Item item)
throws DSpaceSWORDException
{
String field = ConfigurationManager
.getProperty("sword-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSWORDException(
"No configuration, or configuration is invalid for: sword.updated.field");
}
MetadataFieldInfo dc = this.configToDC(field, null);
try {
itemService.clearMetadata(context, item, dc.schema, dc.element, dc.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, dc.schema, dc.element, dc.qualifier, null, date.toString());
} catch (SQLException e) {
log.error("Caught exception: ", e);
throw new DSpaceSWORDException(e);
}
MetadataFieldInfo dc = this.configToDC(field, null);
try
{
itemService.clearMetadata(context, item, dc.schema, dc.element,
dc.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, dc.schema, dc.element,
dc.qualifier, null, date.toString());
}
catch (SQLException e)
{
log.error("Caught exception: ", e);
throw new DSpaceSWORDException(e);
}
swordService.message("Updated date added to response from item metadata where available");
}
swordService.message(
"Updated date added to response from item metadata where available");
}
/**
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
* @param item
* @param slugVal
* @throws DSpaceSWORDException
*/
private void setSlug(Item item, String slugVal)
throws DSpaceSWORDException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
/**
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
* @param item
* @param slugVal
* @throws DSpaceSWORDException
*/
private void setSlug(Item item, String slugVal)
throws DSpaceSWORDException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
String field = ConfigurationManager.getProperty("sword-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSWORDException("No configuration, or configuration is invalid for: sword.slug.field");
}
String field = ConfigurationManager
.getProperty("sword-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSWORDException(
"No configuration, or configuration is invalid for: sword.slug.field");
}
MetadataFieldInfo mfi = this.configToDC(field, null);
try {
itemService.clearMetadata(swordService.getContext(), item, mfi.schema, mfi.element, mfi.qualifier, Item.ANY);
itemService.addMetadata(swordService.getContext(), item, mfi.schema, mfi.element, mfi.qualifier, null, slugVal);
} catch (SQLException e) {
log.error("Caught exception: ", e);
throw new DSpaceSWORDException(e);
}
MetadataFieldInfo mfi = this.configToDC(field, null);
try
{
itemService
.clearMetadata(swordService.getContext(), item, mfi.schema,
mfi.element, mfi.qualifier, Item.ANY);
itemService.addMetadata(swordService.getContext(), item, mfi.schema,
mfi.element, mfi.qualifier, null, slugVal);
}
catch (SQLException e)
{
log.error("Caught exception: ", e);
throw new DSpaceSWORDException(e);
}
swordService.message("Slug value set in response where available");
}
swordService.message("Slug value set in response where available");
}
/**
* utility method to turn given metadata fields of the form
schema.element.qualifier into Metadatum objects which can be
used to access metadata in items.
*
* The def parameter should be null, * or "" depending on how
you intend to use the Metadatum object
*
* @param config
* @param def
* @return
*/
private MetadataFieldInfo configToDC(String config, String def)
{
MetadataFieldInfo mfi = new MetadataFieldInfo();
mfi.schema = def;
mfi.element= def;
mfi.qualifier = def;
/**
* utility method to turn given metadata fields of the form
schema.element.qualifier into Metadatum objects which can be
used to access metadata in items.
*
* The def parameter should be null, * or "" depending on how
you intend to use the Metadatum object
*
* @param config
* @param def
* @return
*/
private MetadataFieldInfo configToDC(String config, String def)
{
MetadataFieldInfo mfi = new MetadataFieldInfo();
mfi.schema = def;
mfi.element = def;
mfi.qualifier = def;
StringTokenizer stz = new StringTokenizer(config, ".");
mfi.schema = stz.nextToken();
mfi.element = stz.nextToken();
if (stz.hasMoreTokens())
{
mfi.qualifier = stz.nextToken();
}
StringTokenizer stz = new StringTokenizer(config, ".");
mfi.schema = stz.nextToken();
mfi.element = stz.nextToken();
if (stz.hasMoreTokens())
{
mfi.qualifier = stz.nextToken();
}
return mfi;
}
return mfi;
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSWORDException
*/
private String getTreatment() throws DSpaceSWORDException
{
return "The package has been deposited into DSpace. Each file has been unpacked " +
"and provided with a unique identifier. The metadata in the manifest has been " +
"extracted and attached to the DSpace item, which has been provided with " +
"an identifier leading to an HTML splash page.";
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSWORDException
*/
private String getTreatment() throws DSpaceSWORDException
{
return "The package has been deposited into DSpace. Each file has been unpacked " +
"and provided with a unique identifier. The metadata in the manifest has been " +
"extracted and attached to the DSpace item, which has been provided with " +
"an identifier leading to an HTML splash page.";
}
private class MetadataFieldInfo {
private String schema;
private String element;
private String qualifier;
}
private class MetadataFieldInfo
{
private String schema;
private String element;
private String qualifier;
}
}

View File

@@ -2,15 +2,15 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
public interface SWORDProperties
{
/** The version of the SWORD service we are offering */
public static final String VERSION = "1.3";
/** The version of the SWORD service we are offering */
public static final String VERSION = "1.3";
public static final String SOFTWARE_URI = "http://www.dspace.org/ns/sword/1.3.1";
public static final String SOFTWARE_URI = "http://www.dspace.org/ns/sword/1.3.1";
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -34,164 +34,168 @@ import org.purl.sword.base.Deposit;
*/
public class SWORDService
{
/** Log4j logging instance */
public static final Logger log = Logger.getLogger(SWORDService.class);
/** Log4j logging instance */
public static final Logger log = Logger.getLogger(SWORDService.class);
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
/** The SWORD context of the request */
private SWORDContext swordContext;
/** The SWORD context of the request */
private SWORDContext swordContext;
/** The configuration of the sword server instance */
private SWORDConfiguration swordConfig;
/** The configuration of the sword server instance */
private SWORDConfiguration swordConfig;
/** The URL Generator */
private SWORDUrlManager urlManager;
/** The URL Generator */
private SWORDUrlManager urlManager;
/** a holder for the messages coming through from the implementation */
private StringBuilder verboseDescription = new StringBuilder();
/** a holder for the messages coming through from the implementation */
private StringBuilder verboseDescription = new StringBuilder();
/** is this a verbose operation */
private boolean verbose = false;
/** is this a verbose operation */
private boolean verbose = false;
/** date formatter */
private SimpleDateFormat dateFormat;
/** date formatter */
private SimpleDateFormat dateFormat;
/**
* Construct a new service instance around the given authenticated
* sword context
*
* @param sc
*/
public SWORDService(SWORDContext sc)
{
this.swordContext = sc;
this.swordConfig = new SWORDConfiguration();
this.urlManager = new SWORDUrlManager(this.swordConfig, this.swordContext.getContext());
dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss.S]");
}
/**
* Construct a new service instance around the given authenticated
* sword context
*
* @param sc
*/
public SWORDService(SWORDContext sc)
{
this.swordContext = sc;
this.swordConfig = new SWORDConfiguration();
this.urlManager = new SWORDUrlManager(this.swordConfig,
this.swordContext.getContext());
dateFormat = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss.S]");
}
public SWORDUrlManager getUrlManager()
{
return urlManager;
}
public SWORDUrlManager getUrlManager()
{
return urlManager;
}
public void setUrlManager(SWORDUrlManager urlManager)
{
this.urlManager = urlManager;
}
public void setUrlManager(SWORDUrlManager urlManager)
{
this.urlManager = urlManager;
}
public SWORDContext getSwordContext()
{
return swordContext;
}
public SWORDContext getSwordContext()
{
return swordContext;
}
public void setSwordContext(SWORDContext swordContext)
{
this.swordContext = swordContext;
}
public void setSwordContext(SWORDContext swordContext)
{
this.swordContext = swordContext;
}
public SWORDConfiguration getSwordConfig()
{
return swordConfig;
}
public SWORDConfiguration getSwordConfig()
{
return swordConfig;
}
public void setSwordConfig(SWORDConfiguration swordConfig)
{
this.swordConfig = swordConfig;
}
public void setSwordConfig(SWORDConfiguration swordConfig)
{
this.swordConfig = swordConfig;
}
public Context getContext()
{
return this.swordContext.getContext();
}
public Context getContext()
{
return this.swordContext.getContext();
}
public boolean isVerbose()
{
return verbose;
}
public boolean isVerbose()
{
return verbose;
}
public void setVerbose(boolean verbose)
{
this.verbose = verbose;
}
public void setVerbose(boolean verbose)
{
this.verbose = verbose;
}
public StringBuilder getVerboseDescription()
{
return verboseDescription;
}
public StringBuilder getVerboseDescription()
{
return verboseDescription;
}
/**
* shortcut to registering a message with the verboseDescription
* member variable. This checks to see if the request is
* verbose, meaning we don't have to do it inline and break nice
* looking code up
*
* @param message
*/
public void message(String message)
{
// build the processing message
String msg = dateFormat.format(new Date()) + " " + message + "; \n\n";
/**
* shortcut to registering a message with the verboseDescription
* member variable. This checks to see if the request is
* verbose, meaning we don't have to do it inline and break nice
* looking code up
*
* @param message
*/
public void message(String message)
{
// build the processing message
String msg = dateFormat.format(new Date()) + " " + message + "; \n\n";
// if this is a verbose deposit, then log it
if (this.verbose)
{
verboseDescription.append(msg);
}
// if this is a verbose deposit, then log it
if (this.verbose)
{
verboseDescription.append(msg);
}
// add to server logs anyway
log.info(msg);
}
// add to server logs anyway
log.info(msg);
}
/**
* Construct the most appropriate filename for the incoming deposit.
*
* @param context
* @param deposit
* @param original
* @throws DSpaceSWORDException
*/
public String getFilename(Context context, Deposit deposit, boolean original)
throws DSpaceSWORDException
{
try
{
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getContentType());
List<String> exts = null;
if (bf != null)
{
exts = bf.getExtensions();
}
/**
* Construct the most appropriate filename for the incoming deposit.
*
* @param context
* @param deposit
* @param original
* @throws DSpaceSWORDException
*/
public String getFilename(Context context, Deposit deposit,
boolean original)
throws DSpaceSWORDException
{
try
{
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getContentType());
List<String> exts = null;
if (bf != null)
{
exts = bf.getExtensions();
}
String fn = deposit.getFilename();
if (fn == null || "".equals(fn))
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
fn = "sword-" + sdf.format(new Date());
if (original)
{
fn = fn + ".original";
}
if (exts != null && !exts.isEmpty())
{
fn = fn + "." + exts.get(0);
}
}
String fn = deposit.getFilename();
if (fn == null || "".equals(fn))
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
fn = "sword-" + sdf.format(new Date());
if (original)
{
fn = fn + ".original";
}
if (exts != null && !exts.isEmpty())
{
fn = fn + "." + exts.get(0);
}
}
return fn;
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
return fn;
}
catch (SQLException e)
{
throw new DSpaceSWORDException(e);
}
}
/**
* Get the name of the temp files that should be used.
*/
public String getTempFilename()
{
return "sword-" + (new Date()).getTime();
}
/**
* Get the name of the temp files that should be used.
*/
public String getTempFilename()
{
return "sword-" + (new Date()).getTime();
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -26,148 +26,170 @@ import java.util.List;
public class ServiceDocumentManager
{
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
private SWORDService swordService;
protected CommunityService communityService = ContentServiceFactory
.getInstance().getCommunityService();
private SWORDAuthenticator swordAuth;
private SWORDService swordService;
public ServiceDocumentManager(SWORDService service)
{
this.swordService = service;
this.swordAuth = new SWORDAuthenticator();
}
private SWORDAuthenticator swordAuth;
/**
* Obtain the service document for the repository based on the
* DSpace context and the SWORD context which must be set for
* this object prior to calling this method.
*
* @return The service document based on the context of the request
* @throws DSpaceSWORDException
*/
public ServiceDocument getServiceDocument()
throws DSpaceSWORDException, SWORDErrorException
{
return this.getServiceDocument(null);
}
public ServiceDocumentManager(SWORDService service)
{
this.swordService = service;
this.swordAuth = new SWORDAuthenticator();
}
public ServiceDocument getServiceDocument(String url)
throws DSpaceSWORDException, SWORDErrorException
{
// extract the things we need from the service
Context context = swordService.getContext();
SWORDContext swordContext = swordService.getSwordContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
/**
* Obtain the service document for the repository based on the
* DSpace context and the SWORD context which must be set for
* this object prior to calling this method.
*
* @return The service document based on the context of the request
* @throws DSpaceSWORDException
*/
public ServiceDocument getServiceDocument()
throws DSpaceSWORDException, SWORDErrorException
{
return this.getServiceDocument(null);
}
// construct the ATOM collection generators that we might use
ATOMCollectionGenerator comGen = new CommunityCollectionGenerator(swordService);
ATOMCollectionGenerator colGen = new CollectionCollectionGenerator(swordService);
ATOMCollectionGenerator itemGen = new ItemCollectionGenerator(swordService);
public ServiceDocument getServiceDocument(String url)
throws DSpaceSWORDException, SWORDErrorException
{
// extract the things we need from the service
Context context = swordService.getContext();
SWORDContext swordContext = swordService.getSwordContext();
SWORDConfiguration swordConfig = swordService.getSwordConfig();
SWORDUrlManager urlManager = swordService.getUrlManager();
// first check that the context and sword context have
// been set
if (context == null)
{
throw new DSpaceSWORDException("The Context is null; please set it before calling getServiceDocument");
}
// construct the ATOM collection generators that we might use
ATOMCollectionGenerator comGen = new CommunityCollectionGenerator(
swordService);
ATOMCollectionGenerator colGen = new CollectionCollectionGenerator(
swordService);
ATOMCollectionGenerator itemGen = new ItemCollectionGenerator(
swordService);
if (swordContext == null)
{
throw new DSpaceSWORDException("The SWORD Context is null; please set it before calling getServiceDocument");
}
// first check that the context and sword context have
// been set
if (context == null)
{
throw new DSpaceSWORDException(
"The Context is null; please set it before calling getServiceDocument");
}
// construct a new service document
Service service = new Service(SWORDProperties.VERSION, swordConfig.isNoOp(), swordConfig.isVerbose());
if (swordContext == null)
{
throw new DSpaceSWORDException(
"The SWORD Context is null; please set it before calling getServiceDocument");
}
// set the max upload size
service.setMaxUploadSize(swordConfig.getMaxUploadSize());
// construct a new service document
Service service = new Service(SWORDProperties.VERSION,
swordConfig.isNoOp(), swordConfig.isVerbose());
// set the max upload size
service.setMaxUploadSize(swordConfig.getMaxUploadSize());
// Set the generator
this.addGenerator(service);
//
if (url == null || urlManager.isBaseServiceDocumentUrl(url))
{
// we are dealing with the default service document
//
if (url == null || urlManager.isBaseServiceDocumentUrl(url))
{
// we are dealing with the default service document
// set the title of the workspace as per the name of the DSpace installation
String ws = ConfigurationManager.getProperty("dspace.name");
Workspace workspace = new Workspace();
workspace.setTitle(ws);
// set the title of the workspace as per the name of the DSpace installation
String ws = ConfigurationManager.getProperty("dspace.name");
Workspace workspace = new Workspace();
workspace.setTitle(ws);
// next thing to do is determine whether the default is communities or collections
boolean swordCommunities = ConfigurationManager.getBooleanProperty("sword-server", "expose-communities");
// next thing to do is determine whether the default is communities or collections
boolean swordCommunities = ConfigurationManager
.getBooleanProperty("sword-server", "expose-communities");
if (swordCommunities)
{
List<Community> comms = swordAuth.getAllowedCommunities(swordContext);
for (Community comm : comms)
{
org.purl.sword.base.Collection scol = comGen.buildCollection(comm);
workspace.addCollection(scol);
}
}
else
{
List<Collection> cols = swordAuth.getAllowedCollections(swordContext);
for (Collection col : cols)
{
org.purl.sword.base.Collection scol = colGen.buildCollection(col);
workspace.addCollection(scol);
}
}
if (swordCommunities)
{
List<Community> comms = swordAuth
.getAllowedCommunities(swordContext);
for (Community comm : comms)
{
org.purl.sword.base.Collection scol = comGen
.buildCollection(comm);
workspace.addCollection(scol);
}
}
else
{
List<Collection> cols = swordAuth
.getAllowedCollections(swordContext);
for (Collection col : cols)
{
org.purl.sword.base.Collection scol = colGen
.buildCollection(col);
workspace.addCollection(scol);
}
}
service.addWorkspace(workspace);
}
else
{
// we are dealing with a partial or sub-service document
DSpaceObject dso = urlManager.extractDSpaceObject(url);
service.addWorkspace(workspace);
}
else
{
// we are dealing with a partial or sub-service document
DSpaceObject dso = urlManager.extractDSpaceObject(url);
if (dso instanceof Collection)
{
Collection collection = (Collection) dso;
Workspace workspace = new Workspace();
workspace.setTitle(collectionService.getMetadata(collection, "name"));
if (dso instanceof Collection)
{
Collection collection = (Collection) dso;
Workspace workspace = new Workspace();
workspace.setTitle(
collectionService.getMetadata(collection, "name"));
List<Item> items = swordAuth.getAllowedItems(swordContext, collection);
for (Item item : items)
{
org.purl.sword.base.Collection scol = itemGen.buildCollection(item);
workspace.addCollection(scol);
}
List<Item> items = swordAuth
.getAllowedItems(swordContext, collection);
for (Item item : items)
{
org.purl.sword.base.Collection scol = itemGen
.buildCollection(item);
workspace.addCollection(scol);
}
service.addWorkspace(workspace);
}
else if (dso instanceof Community)
{
Community community = (Community) dso;
Workspace workspace = new Workspace();
workspace.setTitle(communityService.getMetadata(community, "name"));
service.addWorkspace(workspace);
}
else if (dso instanceof Community)
{
Community community = (Community) dso;
Workspace workspace = new Workspace();
workspace.setTitle(
communityService.getMetadata(community, "name"));
List<Collection> collections = swordAuth.getAllowedCollections(swordContext, community);
for (Collection collection : collections)
{
org.purl.sword.base.Collection scol = colGen.buildCollection(collection);
workspace.addCollection(scol);
}
List<Collection> collections = swordAuth
.getAllowedCollections(swordContext, community);
for (Collection collection : collections)
{
org.purl.sword.base.Collection scol = colGen
.buildCollection(collection);
workspace.addCollection(scol);
}
List<Community> communities = swordAuth.getCommunities(swordContext, community);
for (Community comm : communities)
{
org.purl.sword.base.Collection scol = comGen.buildCollection(comm);
workspace.addCollection(scol);
}
List<Community> communities = swordAuth
.getCommunities(swordContext, community);
for (Community comm : communities)
{
org.purl.sword.base.Collection scol = comGen
.buildCollection(comm);
workspace.addCollection(scol);
}
service.addWorkspace(workspace);
}
}
service.addWorkspace(workspace);
}
}
return new ServiceDocument(service);
}
}
/**
* Add the generator field content
@@ -176,7 +198,8 @@ public class ServiceDocumentManager
*/
private void addGenerator(Service service)
{
boolean identify = ConfigurationManager.getBooleanProperty("sword-server", "identify-version", false);
boolean identify = ConfigurationManager
.getBooleanProperty("sword-server", "identify-version", false);
SWORDUrlManager urlManager = swordService.getUrlManager();
String softwareUri = urlManager.getGeneratorUrl();
if (identify)

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword;
@@ -39,10 +39,17 @@ import java.util.List;
public class SimpleFileIngester implements SWORDIngester
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
/**
* Perform the ingest using the given deposit object onto the specified
@@ -54,46 +61,49 @@ public class SimpleFileIngester implements SWORDIngester
* @throws DSpaceSWORDException
* @throws SWORDErrorException
*/
public DepositResult ingest(SWORDService service, Deposit deposit, DSpaceObject target)
throws DSpaceSWORDException, SWORDErrorException
{
try
{
if (!(target instanceof Item))
{
throw new DSpaceSWORDException("SimpleFileIngester can only be loaded for deposit onto DSpace Items");
}
Item item = (Item) target;
public DepositResult ingest(SWORDService service, Deposit deposit,
DSpaceObject target)
throws DSpaceSWORDException, SWORDErrorException
{
try
{
if (!(target instanceof Item))
{
throw new DSpaceSWORDException(
"SimpleFileIngester can only be loaded for deposit onto DSpace Items");
}
Item item = (Item) target;
// now set the sword service
// now set the sword service
SWORDService swordService = service;
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDUrlManager urlManager = swordService.getUrlManager();
// get the things out of the service that we need
Context context = swordService.getContext();
SWORDUrlManager urlManager = swordService.getUrlManager();
List<Bundle> bundles = item.getBundles();
Bundle original = null;
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
if (original == null)
{
original = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
List<Bundle> bundles = item.getBundles();
Bundle original = null;
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
if (original == null)
{
original = bundleService
.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
Bitstream bs;
FileInputStream fis = null;
FileInputStream fis = null;
try
{
fis = new FileInputStream(deposit.getFile());
bs = bitstreamService.create(context, original, fis);
bs = bitstreamService.create(context, original, fis);
}
finally
{
@@ -103,47 +113,48 @@ public class SimpleFileIngester implements SWORDIngester
}
}
String fn = swordService.getFilename(context, deposit, false);
bs.setName(context, fn);
String fn = swordService.getFilename(context, deposit, false);
bs.setName(context, fn);
swordService.message("File created in item with filename " + fn);
swordService.message("File created in item with filename " + fn);
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getContentType());
if (bf != null)
{
bs.setFormat(context, bf);
}
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getContentType());
if (bf != null)
{
bs.setFormat(context, bf);
}
// to do the updates, we need to ignore authorisation in the context
context.turnOffAuthorisationSystem();
// to do the updates, we need to ignore authorisation in the context
context.turnOffAuthorisationSystem();
bitstreamService.update(context, bs);
bundleService.update(context, original);
itemService.update(context, item);
bitstreamService.update(context, bs);
bundleService.update(context, original);
itemService.update(context, item);
// reset the ignore authorisation
context.restoreAuthSystemState();
// reset the ignore authorisation
context.restoreAuthSystemState();
DepositResult result = new DepositResult();
result.setHandle(urlManager.getBitstreamUrl(bs));
result.setTreatment(this.getTreatment());
result.setBitstream(bs);
DepositResult result = new DepositResult();
result.setHandle(urlManager.getBitstreamUrl(bs));
result.setTreatment(this.getTreatment());
result.setBitstream(bs);
return result;
}
catch (SQLException | AuthorizeException | IOException e)
{
throw new DSpaceSWORDException(e);
}
}
return result;
}
catch (SQLException | AuthorizeException | IOException e)
{
throw new DSpaceSWORDException(e);
}
}
/**
* Get the description of the treatment this class provides to the deposit
*
* @return the description
*/
private String getTreatment()
{
return "The file has been attached to the specified item";
}
/**
* Get the description of the treatment this class provides to the deposit
*
* @return the description
*/
private String getTreatment()
{
return "The file has been attached to the specified item";
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
@@ -22,9 +22,11 @@ import java.util.Properties;
public class AbstractSimpleDC
{
protected HashMap<String, String> dcMap = null;
protected HashMap<String, String> atomMap = null;
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
protected void loadMetadataMaps()
{
@@ -32,7 +34,8 @@ public class AbstractSimpleDC
{
// we should load our DC map from configuration
this.dcMap = new HashMap<>();
Properties props = ConfigurationManager.getProperties("swordv2-server");
Properties props = ConfigurationManager
.getProperties("swordv2-server");
for (Object key : props.keySet())
{
String keyString = (String) key;
@@ -48,17 +51,18 @@ public class AbstractSimpleDC
if (this.atomMap == null)
{
this.atomMap = new HashMap<>();
Properties props = ConfigurationManager.getProperties("swordv2-server");
for (Object key : props.keySet())
Properties props = ConfigurationManager
.getProperties("swordv2-server");
for (Object key : props.keySet())
{
String keyString = (String) key;
if (keyString.startsWith("atom."))
{
String keyString = (String) key;
if (keyString.startsWith("atom."))
{
String k = keyString.substring("atom.".length());
String v = (String) props.get(key);
this.atomMap.put(k, v);
}
String k = keyString.substring("atom.".length());
String v = (String) props.get(key);
this.atomMap.put(k, v);
}
}
}
}
@@ -67,12 +71,14 @@ public class AbstractSimpleDC
this.loadMetadataMaps();
SimpleDCMetadata md = new SimpleDCMetadata();
List<MetadataValue> all = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
List<MetadataValue> all = itemService
.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
for (MetadataValue dcv : all)
{
MetadataField field = dcv.getMetadataField();
String valueMatch = field.getMetadataSchema().getName() + "." + field.getElement();
String valueMatch = field.getMetadataSchema().getName() + "." +
field.getElement();
if (field.getQualifier() != null)
{
valueMatch += "." + field.getQualifier();

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -24,172 +24,210 @@ import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
public abstract class AbstractSwordContentIngester implements SwordContentIngester
public abstract class AbstractSwordContentIngester
implements SwordContentIngester
{
public static final Logger log = Logger.getLogger(AbstractSwordContentIngester.class);
public static final Logger log = Logger
.getLogger(AbstractSwordContentIngester.class);
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
public DepositResult ingest(Context context, Deposit deposit, DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public DepositResult ingest(Context context, Deposit deposit,
DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
return this.ingest(context, deposit, dso, verboseDescription, null);
}
public DepositResult ingest(Context context, Deposit deposit, DSpaceObject dso, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingest(Context context, Deposit deposit,
DSpaceObject dso, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
if (dso instanceof Collection)
{
return this.ingestToCollection(context, deposit, (Collection) dso, verboseDescription, result);
return this.ingestToCollection(context, deposit, (Collection) dso,
verboseDescription, result);
}
else if (dso instanceof Item)
{
return this.ingestToItem(context, deposit, (Item) dso, verboseDescription, result);
return this.ingestToItem(context, deposit, (Item) dso,
verboseDescription, result);
}
return null;
}
public abstract DepositResult ingestToCollection(Context context, Deposit deposit, Collection collection, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
public abstract DepositResult ingestToCollection(Context context,
Deposit deposit, Collection collection,
VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
public abstract DepositResult ingestToItem(Context context, Deposit deposit, Item item, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
public abstract DepositResult ingestToItem(Context context, Deposit deposit,
Item item, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
protected BitstreamFormat getFormat(Context context, String fileName)
throws SQLException
{
String fext = null;
int lastDot = fileName.lastIndexOf(".");
if (lastDot > -1)
{
fext = fileName.substring(lastDot + 1);
}
protected BitstreamFormat getFormat(Context context, String fileName)
throws SQLException
{
String fext = null;
int lastDot = fileName.lastIndexOf(".");
if (lastDot > -1)
{
fext = fileName.substring(lastDot + 1);
}
if (fext == null)
{
return null;
}
if (fext == null)
{
return null;
}
List<BitstreamFormat> formats = bitstreamFormatService.findAll(context);
for (BitstreamFormat format : formats)
{
List<String> extensions = format.getExtensions();
for (String ext : extensions)
{
if (ext.equals(fext))
{
return format;
}
}
}
return null;
}
List<BitstreamFormat> formats = bitstreamFormatService.findAll(context);
for (BitstreamFormat format : formats)
{
List<String> extensions = format.getExtensions();
for (String ext : extensions)
{
if (ext.equals(fext))
{
return format;
}
}
}
return null;
}
/**
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSwordException
*/
protected void setUpdatedDate(Context context, Item item, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
String field = ConfigurationManager.getProperty("swordv2-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException("No configuration, or configuration is invalid for: sword.updated.field");
}
/**
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSwordException
*/
protected void setUpdatedDate(Context context, Item item,
VerboseDescription verboseDescription)
throws DSpaceSwordException
{
String field = ConfigurationManager
.getProperty("swordv2-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException(
"No configuration, or configuration is invalid for: sword.updated.field");
}
MetadataFieldInfo info = this.configToDC(field, null);
try {
itemService.clearMetadata(context, item, info.schema, info.element, info.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, info.schema, info.element, info.qualifier, null, date.toString());
} catch (SQLException e) {
log.error("Caught exception trying to set update date", e);
throw new DSpaceSwordException(e);
}
MetadataFieldInfo info = this.configToDC(field, null);
try
{
itemService.clearMetadata(context, item, info.schema, info.element,
info.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, info.schema, info.element,
info.qualifier, null, date.toString());
}
catch (SQLException e)
{
log.error("Caught exception trying to set update date", e);
throw new DSpaceSwordException(e);
}
verboseDescription.append("Updated date added to response from item metadata where available");
}
verboseDescription
.append("Updated date added to response from item metadata where available");
}
/**
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
*
* @param context
* @param item
* @param slugVal
* @throws DSpaceSwordException
*/
protected void setSlug(Context context, Item item, String slugVal, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
/**
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
*
* @param context
* @param item
* @param slugVal
* @throws DSpaceSwordException
*/
protected void setSlug(Context context, Item item, String slugVal,
VerboseDescription verboseDescription)
throws DSpaceSwordException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
String field = ConfigurationManager.getProperty("swordv2-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException("No configuration, or configuration is invalid for: sword.slug.field");
}
String field = ConfigurationManager
.getProperty("swordv2-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException(
"No configuration, or configuration is invalid for: sword.slug.field");
}
MetadataFieldInfo info = this.configToDC(field, null);
try {
itemService.clearMetadata(context, item, info.schema, info.element, info.qualifier, Item.ANY);
itemService.addMetadata(context, item, info.schema, info.element, info.qualifier, null, slugVal);
} catch (SQLException e) {
log.error("Caught exception trying to set slug", e);
throw new DSpaceSwordException(e);
}
MetadataFieldInfo info = this.configToDC(field, null);
try
{
itemService.clearMetadata(context, item, info.schema, info.element,
info.qualifier, Item.ANY);
itemService.addMetadata(context, item, info.schema, info.element,
info.qualifier, null, slugVal);
}
catch (SQLException e)
{
log.error("Caught exception trying to set slug", e);
throw new DSpaceSwordException(e);
}
verboseDescription.append("Slug value set in response where available");
}
verboseDescription.append("Slug value set in response where available");
}
/**
* Utility method to turn given metadata fields of the form
schema.element.qualifier into Metadatum objects which can be
used to access metadata in items.
*
* The def parameter should be null, * or "" depending on how
you intend to use the Metadatum object.
*
* @param config
* @param def
*/
private MetadataFieldInfo configToDC(String config, String def)
{
MetadataFieldInfo mfi = new MetadataFieldInfo();
mfi.schema = def;
mfi.element= def;
mfi.qualifier = def;
/**
* Utility method to turn given metadata fields of the form
schema.element.qualifier into Metadatum objects which can be
used to access metadata in items.
*
* The def parameter should be null, * or "" depending on how
you intend to use the Metadatum object.
*
* @param config
* @param def
*/
private MetadataFieldInfo configToDC(String config, String def)
{
MetadataFieldInfo mfi = new MetadataFieldInfo();
mfi.schema = def;
mfi.element = def;
mfi.qualifier = def;
StringTokenizer stz = new StringTokenizer(config, ".");
mfi.schema = stz.nextToken();
mfi.element = stz.nextToken();
if (stz.hasMoreTokens())
{
mfi.qualifier = stz.nextToken();
}
StringTokenizer stz = new StringTokenizer(config, ".");
mfi.schema = stz.nextToken();
mfi.element = stz.nextToken();
if (stz.hasMoreTokens())
{
mfi.qualifier = stz.nextToken();
}
return mfi;
}
return mfi;
}
private class MetadataFieldInfo {
private String schema;
private String element;
private String qualifier;
}
private class MetadataFieldInfo
{
private String schema;
private String element;
private String qualifier;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -19,11 +19,12 @@ import org.swordapp.server.SwordCollection;
*/
public interface AtomCollectionGenerator
{
/**
* Build the ATOM Collection which represents the given DSpace Object.
*
* @param dso
* @throws DSpaceSwordException
*/
public SwordCollection buildCollection(Context context, DSpaceObject dso, SwordConfigurationDSpace config) throws DSpaceSwordException;
/**
* Build the ATOM Collection which represents the given DSpace Object.
*
* @param dso
* @throws DSpaceSwordException
*/
public SwordCollection buildCollection(Context context, DSpaceObject dso,
SwordConfigurationDSpace config) throws DSpaceSwordException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -20,50 +20,58 @@ import org.swordapp.server.SwordServerException;
import java.util.List;
public class AtomStatementDisseminator extends GenericStatementDisseminator implements SwordStatementDisseminator
public class AtomStatementDisseminator extends GenericStatementDisseminator
implements SwordStatementDisseminator
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public Statement disseminate(Context context, Item item) throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context);
String feedUri = urlManager.getAtomStatementUri(item);
public Statement disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = new SwordUrlManager(
new SwordConfigurationDSpace(), context);
String feedUri = urlManager.getAtomStatementUri(item);
String authorField = ConfigurationManager.getProperty("swordv2-server", "author.field");
String titleField = ConfigurationManager.getProperty("swordv2-server", "title.field");
String updatedField = ConfigurationManager.getProperty("swordv2-server", "updated.field");
String authorField = ConfigurationManager
.getProperty("swordv2-server", "author.field");
String titleField = ConfigurationManager
.getProperty("swordv2-server", "title.field");
String updatedField = ConfigurationManager
.getProperty("swordv2-server", "updated.field");
String author = this.stringMetadata(item, authorField);
String title = this.stringMetadata(item, titleField);
String updated = this.stringMetadata(item, updatedField);
String author = this.stringMetadata(item, authorField);
String title = this.stringMetadata(item, titleField);
String updated = this.stringMetadata(item, updatedField);
Statement s = new AtomStatement(feedUri, author, title, updated);
this.populateStatement(context, item, s);
return s;
}
Statement s = new AtomStatement(feedUri, author, title, updated);
this.populateStatement(context, item, s);
return s;
}
private String stringMetadata(Item item, String field)
{
if (field == null)
{
return null;
}
private String stringMetadata(Item item, String field)
{
if (field == null)
{
return null;
}
List<MetadataValue> dcvs = itemService.getMetadataByMetadataString(item, field);
if (dcvs == null || dcvs.isEmpty())
{
return null;
}
List<MetadataValue> dcvs = itemService
.getMetadataByMetadataString(item, field);
if (dcvs == null || dcvs.isEmpty())
{
return null;
}
StringBuilder md = new StringBuilder();
for (MetadataValue dcv : dcvs)
{
if (md.length() > 0)
{
md.append(", ");
}
md.append(dcv.getValue());
}
return md.toString();
}
StringBuilder md = new StringBuilder();
for (MetadataValue dcv : dcvs)
{
if (md.length() > 0)
{
md.append(", ");
}
md.append(dcv.getValue());
}
return md.toString();
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -33,154 +33,177 @@ import java.util.List;
public class BinaryContentIngester extends AbstractSwordContentIngester
{
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
public DepositResult ingestToCollection(Context context, Deposit deposit, Collection collection, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
{
try
{
// decide whether we have a new item or an existing one
Item item = null;
WorkspaceItem wsi = null;
if (result != null)
{
item = result.getItem();
}
else
{
result = new DepositResult();
}
if (item == null)
{
// simple zip ingester uses the item template, since there is no native metadata
wsi = workspaceItemService.create(context, collection, true);
item = wsi.getItem();
}
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
Bitstream bs = itemService.createSingleBitstream(context, deposit.getInputStream(), item);
BitstreamFormat format = this.getFormat(context, deposit.getFilename());
bs.setName(context, deposit.getFilename());
bs.setFormat(context, format);
bitstreamService.update(context, bs);
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
// now we have an item in the workspace, and we need to consider adding some metadata to it,
// but since the binary file didn't contain anything, what do we do?
itemService.addMetadata(context, item, "dc", "title", null, null, "Untitled: " + deposit.getFilename());
itemService.addMetadata(context, item, "dc", "description", null, null, "Zip file deposted by SWORD without accompanying metadata");
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
public DepositResult ingestToCollection(Context context, Deposit deposit,
Collection collection, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
try
{
// decide whether we have a new item or an existing one
Item item = null;
WorkspaceItem wsi = null;
if (result != null)
{
item = result.getItem();
}
else
{
result = new DepositResult();
}
if (item == null)
{
// simple zip ingester uses the item template, since there is no native metadata
wsi = workspaceItemService.create(context, collection, true);
item = wsi.getItem();
}
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Ingest successful");
verboseDescription.append("Item created with internal identifier: " + item.getID());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setOriginalDeposit(bs);
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException | IOException e)
{
throw new DSpaceSwordException(e);
}
}
public DepositResult ingestToItem(Context context, Deposit deposit, Item item, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
{
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
// get the original bundle
List<Bundle> originals = item.getBundles();
Bundle original = null;
for (Bundle bundle : originals)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
}
}
if (original == null)
{
original = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
Bitstream bs = bitstreamService.create(context, original, deposit.getInputStream());
BitstreamFormat format = this.getFormat(context, deposit.getFilename());
Bitstream bs = itemService
.createSingleBitstream(context, deposit.getInputStream(),
item);
BitstreamFormat format = this
.getFormat(context, deposit.getFilename());
bs.setName(context, deposit.getFilename());
bs.setFormat(context, format);
bs.setName(context, deposit.getFilename());
bitstreamService.update(context, bs);
bitstreamService.update(context, bs);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// now we have an item in the workspace, and we need to consider adding some metadata to it,
// but since the binary file didn't contain anything, what do we do?
itemService.addMetadata(context, item, "dc", "title", null, null,
"Untitled: " + deposit.getFilename());
itemService
.addMetadata(context, item, "dc", "description", null, null,
"Zip file deposted by SWORD without accompanying metadata");
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
verboseDescription.append("ingest successful");
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
result.setItem(item);
result.setTreatment(this.getTreatment());
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Ingest successful");
verboseDescription
.append("Item created with internal identifier: " +
item.getID());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setOriginalDeposit(bs);
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException | IOException e)
{
throw new DSpaceSwordException(e);
}
}
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException | IOException e)
{
throw new DSpaceSwordException(e);
}
}
public DepositResult ingestToItem(Context context, Deposit deposit,
Item item, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been ingested and unpacked into the item. Template metadata for " +
"the collection has been used, and a default title with the name of the file has " +
"been set";
}
// get the original bundle
List<Bundle> originals = item.getBundles();
Bundle original = null;
for (Bundle bundle : originals)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
}
}
if (original == null)
{
original = bundleService
.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
Bitstream bs = bitstreamService
.create(context, original, deposit.getInputStream());
BitstreamFormat format = this
.getFormat(context, deposit.getFilename());
bs.setFormat(context, format);
bs.setName(context, deposit.getFilename());
bitstreamService.update(context, bs);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("ingest successful");
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setOriginalDeposit(bs);
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException | IOException e)
{
throw new DSpaceSwordException(e);
}
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been ingested and unpacked into the item. Template metadata for " +
"the collection has been used, and a default title with the name of the file has " +
"been set";
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -29,106 +29,114 @@ import java.util.List;
*/
public class CollectionCollectionGenerator implements AtomCollectionGenerator
{
private static Logger log = Logger.getLogger(CommunityCollectionGenerator.class);
private static Logger log = Logger
.getLogger(CommunityCollectionGenerator.class);
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
protected CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
/**
* Build the collection for the given DSpaceObject. In this implementation,
* if the object is not a DSpace COllection, it will throw an exception
* @param dso
* @return
* @throws DSpaceSwordException
*/
public SwordCollection buildCollection(Context context, DSpaceObject dso, SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException
{
if (!(dso instanceof org.dspace.content.Collection))
{
log.error("buildCollection passed argument which is not of type Collection");
throw new DSpaceSwordException("Incorrect ATOMCollectionGenerator instantiated");
}
/**
* Build the collection for the given DSpaceObject. In this implementation,
* if the object is not a DSpace COllection, it will throw an exception
* @param dso
* @return
* @throws DSpaceSwordException
*/
public SwordCollection buildCollection(Context context, DSpaceObject dso,
SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException
{
if (!(dso instanceof org.dspace.content.Collection))
{
log.error(
"buildCollection passed argument which is not of type Collection");
throw new DSpaceSwordException(
"Incorrect ATOMCollectionGenerator instantiated");
}
// get the things we need out of the service
SwordUrlManager urlManager = swordConfig.getUrlManager(context, swordConfig);
// get the things we need out of the service
SwordUrlManager urlManager = swordConfig
.getUrlManager(context, swordConfig);
Collection col = (Collection) dso;
SwordCollection scol = new SwordCollection();
Collection col = (Collection) dso;
SwordCollection scol = new SwordCollection();
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(col);
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(col);
// collection title is just its name
String title = collectionService.getName(col);
// collection title is just its name
String title = collectionService.getName(col);
// the collection policy is the licence to which the collection adheres
String collectionPolicy = collectionService.getLicense(col);
// the collection policy is the licence to which the collection adheres
String collectionPolicy = collectionService.getLicense(col);
// FIXME: what is the treatment? Doesn't seem appropriate for DSpace
// String treatment = " ";
// FIXME: what is the treatment? Doesn't seem appropriate for DSpace
// String treatment = " ";
// abstract is the short description of the collection
List<MetadataValue> dcAbstracts = collectionService.getMetadataByMetadataString(col, "short_description");
// abstract is the short description of the collection
List<MetadataValue> dcAbstracts = collectionService
.getMetadataByMetadataString(col, "short_description");
// we just do support mediation
boolean mediation = swordConfig.isMediated();
// we just do support mediation
boolean mediation = swordConfig.isMediated();
// load up the sword collection
scol.setLocation(location);
// load up the sword collection
scol.setLocation(location);
// add the title if it exists
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// add the title if it exists
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// add the collection policy if it exists
if (StringUtils.isNotBlank(collectionPolicy))
{
scol.setCollectionPolicy(collectionPolicy);
}
// add the collection policy if it exists
if (StringUtils.isNotBlank(collectionPolicy))
{
scol.setCollectionPolicy(collectionPolicy);
}
// FIXME: leave the treatment out for the time being,
// as there is no analogue
// scol.setTreatment(treatment);
// FIXME: leave the treatment out for the time being,
// as there is no analogue
// scol.setTreatment(treatment);
// add the abstract if it exists
if (dcAbstracts != null && !dcAbstracts.isEmpty())
{
String firstValue = dcAbstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
// add the abstract if it exists
if (dcAbstracts != null && !dcAbstracts.isEmpty())
{
String firstValue = dcAbstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
scol.setMediation(mediation);
scol.setMediation(mediation);
List<String> accepts = swordConfig.getCollectionAccepts();
for (String accept : accepts)
{
scol.addAccepts(accept);
scol.addMultipartAccepts(accept);
scol.addMultipartAccepts(accept);
}
// add the accept packaging values
List<String> aps = swordConfig.getAcceptPackaging(col);
for (String ap : aps)
{
scol.addAcceptPackaging(ap);
}
// add the accept packaging values
List<String> aps = swordConfig.getAcceptPackaging(col);
for (String ap : aps)
{
scol.addAcceptPackaging(ap);
}
// should we offer the items in the collection up as deposit
// targets?
boolean itemService = ConfigurationManager.getBooleanProperty("sword.expose-items");
if (itemService)
{
String subService = urlManager.constructSubServiceUrl(col);
scol.addSubService(new IRI(subService));
}
// should we offer the items in the collection up as deposit
// targets?
boolean itemService = ConfigurationManager
.getBooleanProperty("sword.expose-items");
if (itemService)
{
String subService = urlManager.constructSubServiceUrl(col);
scol.addSubService(new IRI(subService));
}
log.debug("Created ATOM Collection for DSpace Collection");
log.debug("Created ATOM Collection for DSpace Collection");
return scol;
}
return scol;
}
}

View File

@@ -2,324 +2,335 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
import org.dspace.content.BitstreamFormat;
import org.dspace.content.Bundle;
import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.core.*;
import org.swordapp.server.AuthCredentials;
import org.swordapp.server.CollectionDepositManager;
import org.swordapp.server.Deposit;
import org.swordapp.server.DepositReceipt;
import org.swordapp.server.SwordAuthException;
import org.swordapp.server.SwordConfiguration;
import org.swordapp.server.SwordError;
import org.swordapp.server.SwordServerException;
import org.swordapp.server.UriRegistry;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.swordapp.server.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CollectionDepositManagerDSpace extends DSpaceSwordAPI implements CollectionDepositManager
public class CollectionDepositManagerDSpace extends DSpaceSwordAPI
implements CollectionDepositManager
{
/** logger */
private static Logger log = Logger.getLogger(CollectionDepositManagerDSpace.class);
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
/**
* logger
*/
private static Logger log = Logger
.getLogger(CollectionDepositManagerDSpace.class);
private VerboseDescription verboseDescription = new VerboseDescription();
protected CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
public DepositReceipt createNew(String collectionUri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordError, SwordServerException, SwordAuthException
{
// start the timer
Date start = new Date();
private VerboseDescription verboseDescription = new VerboseDescription();
// store up the verbose description, which we can then give back at the end if necessary
this.verboseDescription.append("Initialising verbose deposit");
public DepositReceipt createNew(String collectionUri, Deposit deposit,
AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordError, SwordServerException, SwordAuthException
{
// start the timer
Date start = new Date();
SwordContext sc = null;
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
// store up the verbose description, which we can then give back at the end if necessary
this.verboseDescription.append("Initialising verbose deposit");
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
sc = this.doAuth(authCredentials);
Context context = sc.getContext();
SwordContext sc = null;
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_create_new", ""));
}
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
sc = this.doAuth(authCredentials);
Context context = sc.getContext();
// get the deposit target
Collection collection = this.getDepositTarget(context, collectionUri, config);
if (log.isDebugEnabled())
{
log.debug(
LogManager.getHeader(context, "sword_create_new", ""));
}
// get the deposit target
Collection collection = this
.getDepositTarget(context, collectionUri, config);
if (collection == null)
{
throw new SwordError(404);
}
// Ensure that this method is allowed
WorkflowManager wfm = WorkflowManagerFactory.getInstance();
wfm.createResource(context, collection);
// Ensure that this method is allowed
WorkflowManager wfm = WorkflowManagerFactory.getInstance();
wfm.createResource(context, collection);
// find out if the supplied SWORDContext can submit to the given
// dspace object
// find out if the supplied SWORDContext can submit to the given
// dspace object
SwordAuthenticator auth = new SwordAuthenticator();
if (!auth.canSubmit(sc, collection, this.verboseDescription))
{
// throw an exception if the deposit can't be made
String oboEmail = "none";
if (sc.getOnBehalfOf() != null)
{
oboEmail = sc.getOnBehalfOf().getEmail();
}
log.info(LogManager.getHeader(context, "deposit_failed_authorisation", "user=" +
sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail));
throw new SwordAuthException("Cannot submit to the given collection with this context");
}
if (!auth.canSubmit(sc, collection, this.verboseDescription))
{
// throw an exception if the deposit can't be made
String oboEmail = "none";
if (sc.getOnBehalfOf() != null)
{
oboEmail = sc.getOnBehalfOf().getEmail();
}
log.info(LogManager
.getHeader(context, "deposit_failed_authorisation",
"user=" +
sc.getAuthenticated().getEmail() +
",on_behalf_of=" + oboEmail));
throw new SwordAuthException(
"Cannot submit to the given collection with this context");
}
// make a note of the authentication in the verbose string
this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().getEmail());
if (sc.getOnBehalfOf() != null)
{
this.verboseDescription.append("Depositing on behalf of: " + sc.getOnBehalfOf().getEmail());
}
// make a note of the authentication in the verbose string
this.verboseDescription.append("Authenticated user: " +
sc.getAuthenticated().getEmail());
if (sc.getOnBehalfOf() != null)
{
this.verboseDescription.append("Depositing on behalf of: " +
sc.getOnBehalfOf().getEmail());
}
DepositResult result = null;
try
{
if (deposit.isBinaryOnly())
{
result = this.createNewFromBinary(sc, collection, deposit, authCredentials, config);
}
else if (deposit.isEntryOnly())
{
result = this.createNewFromEntry(sc, collection, deposit, authCredentials, config);
}
else if (deposit.isMultipart())
{
result = this.createNewFromMultipart(sc, collection, deposit, authCredentials, config);
}
}
catch(DSpaceSwordException e)
{
if (config.isKeepPackageOnFailedIngest())
{
try
{
if (deposit.isBinaryOnly())
{
this.storePackageAsFile(deposit, authCredentials, config);
}
else if (deposit.isEntryOnly())
{
this.storeEntryAsFile(deposit, authCredentials, config);
}
else if (deposit.isMultipart())
{
this.storePackageAsFile(deposit, authCredentials, config);
this.storeEntryAsFile(deposit, authCredentials, config);
}
}
catch(IOException e2)
{
log.warn("Unable to store SWORD package as file: " + e);
}
}
throw e;
}
catch(SwordError e)
{
if (config.isKeepPackageOnFailedIngest())
{
try
{
if (deposit.isBinaryOnly())
{
this.storePackageAsFile(deposit, authCredentials, config);
}
else if (deposit.isEntryOnly())
{
this.storeEntryAsFile(deposit, authCredentials, config);
}
else if (deposit.isMultipart())
{
this.storePackageAsFile(deposit, authCredentials, config);
this.storeEntryAsFile(deposit, authCredentials, config);
}
}
catch(IOException e2)
{
log.warn("Unable to store SWORD package as file: " + e);
}
}
throw e;
}
DepositResult result = null;
try
{
if (deposit.isBinaryOnly())
{
result = this.createNewFromBinary(sc, collection, deposit,
authCredentials, config);
}
else if (deposit.isEntryOnly())
{
result = this.createNewFromEntry(sc, collection, deposit,
authCredentials, config);
}
else if (deposit.isMultipart())
{
result = this
.createNewFromMultipart(sc, collection, deposit,
authCredentials, config);
}
}
catch (DSpaceSwordException | SwordError e)
{
if (config.isKeepPackageOnFailedIngest())
{
try
{
if (deposit.isBinaryOnly())
{
this.storePackageAsFile(deposit, authCredentials,
config);
}
else if (deposit.isEntryOnly())
{
this.storeEntryAsFile(deposit, authCredentials,
config);
}
else if (deposit.isMultipart())
{
this.storePackageAsFile(deposit, authCredentials,
config);
this.storeEntryAsFile(deposit, authCredentials,
config);
}
}
catch (IOException e2)
{
log.warn("Unable to store SWORD package as file: " + e);
}
}
throw e;
}
// now we've produced a deposit, we need to decide on its workflow state
wfm.resolveState(context, deposit, result, this.verboseDescription);
ReceiptGenerator genny = new ReceiptGenerator();
DepositReceipt receipt = genny.createReceipt(context, result, config);
ReceiptGenerator genny = new ReceiptGenerator();
DepositReceipt receipt = genny
.createReceipt(context, result, config);
Date finish = new Date();
long delta = finish.getTime() - start.getTime();
Date finish = new Date();
long delta = finish.getTime() - start.getTime();
this.verboseDescription.append("Total time for deposit processing: " + delta + " ms");
this.verboseDescription
.append("Total time for deposit processing: " + delta +
" ms");
this.addVerboseDescription(receipt, this.verboseDescription);
// if something hasn't killed it already (allowed), then complete the transaction
sc.commit();
// if something hasn't killed it already (allowed), then complete the transaction
sc.commit();
return receipt;
}
catch (DSpaceSwordException e)
{
log.error("caught exception:", e);
throw new SwordServerException("There was a problem depositing the item", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
{
sc.abort();
}
}
}
return receipt;
}
catch (DSpaceSwordException e)
{
log.error("caught exception:", e);
throw new SwordServerException(
"There was a problem depositing the item", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
{
sc.abort();
}
}
}
protected DepositResult createNewFromBinary(SwordContext swordContext, Collection collection, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig.getUrlManager(swordContext.getContext(), swordConfig);
protected DepositResult createNewFromBinary(SwordContext swordContext,
Collection collection, Deposit deposit,
AuthCredentials authCredentials,
SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig
.getUrlManager(swordContext.getContext(), swordConfig);
// is the content acceptable? If not, this will throw an error
this.isAcceptable(swordConfig, context, deposit, collection);
// Obtain the relevant ingester from the factory
SwordContentIngester si = SwordIngesterFactory.getContentInstance(context, deposit, collection);
this.verboseDescription.append("Loaded ingester: " + si.getClass().getName());
// Obtain the relevant ingester from the factory
SwordContentIngester si = SwordIngesterFactory
.getContentInstance(context, deposit, collection);
this.verboseDescription
.append("Loaded ingester: " + si.getClass().getName());
// do the deposit
DepositResult result = si.ingest(context, deposit, collection, this.verboseDescription);
this.verboseDescription.append("Archive ingest completed successfully");
// do the deposit
DepositResult result = si
.ingest(context, deposit, collection, this.verboseDescription);
this.verboseDescription.append("Archive ingest completed successfully");
// store the originals (this code deals with the possibility that that's not required)
this.storeOriginals(swordConfig, context, this.verboseDescription, deposit, result);
// store the originals (this code deals with the possibility that that's not required)
this.storeOriginals(swordConfig, context, this.verboseDescription,
deposit, result);
return result;
}
return result;
}
protected DepositResult createNewFromEntry(SwordContext swordContext, Collection collection, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig.getUrlManager(swordContext.getContext(), swordConfig);
protected DepositResult createNewFromEntry(SwordContext swordContext,
Collection collection, Deposit deposit,
AuthCredentials authCredentials,
SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig
.getUrlManager(swordContext.getContext(), swordConfig);
// Obtain the relevant ingester from the factory
SwordEntryIngester si = SwordIngesterFactory.getEntryInstance(context, deposit, collection);
this.verboseDescription.append("Loaded ingester: " + si.getClass().getName());
// Obtain the relevant ingester from the factory
SwordEntryIngester si = SwordIngesterFactory
.getEntryInstance(context, deposit, collection);
this.verboseDescription
.append("Loaded ingester: " + si.getClass().getName());
// do the deposit
DepositResult result = si.ingest(context, deposit, collection, this.verboseDescription);
this.verboseDescription.append("Archive ingest completed successfully");
// do the deposit
DepositResult result = si
.ingest(context, deposit, collection, this.verboseDescription);
this.verboseDescription.append("Archive ingest completed successfully");
// store the originals (this code deals with the possibility that that's not required)
this.storeOriginals(swordConfig, context, this.verboseDescription, deposit, result);
// store the originals (this code deals with the possibility that that's not required)
this.storeOriginals(swordConfig, context, this.verboseDescription,
deposit, result);
return result;
}
return result;
}
protected DepositResult createNewFromMultipart(SwordContext swordContext, Collection collection, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig.getUrlManager(swordContext.getContext(), swordConfig);
protected DepositResult createNewFromMultipart(SwordContext swordContext,
Collection collection, Deposit deposit,
AuthCredentials authCredentials,
SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
// get the things out of the service that we need
Context context = swordContext.getContext();
SwordUrlManager urlManager = swordConfig
.getUrlManager(swordContext.getContext(), swordConfig);
// is the content acceptable? If not, this will throw an error
// is the content acceptable? If not, this will throw an error
this.isAcceptable(swordConfig, context, deposit, collection);
// Obtain the relevant content ingester from the factory
SwordContentIngester sci = SwordIngesterFactory.getContentInstance(context, deposit, collection);
this.verboseDescription.append("Loaded content ingester: " + sci.getClass().getName());
// Obtain the relevant content ingester from the factory
SwordContentIngester sci = SwordIngesterFactory
.getContentInstance(context, deposit, collection);
this.verboseDescription
.append("Loaded content ingester: " + sci.getClass().getName());
// obtain the relevant entry intester from the factory
SwordEntryIngester sei = SwordIngesterFactory.getEntryInstance(context, deposit, collection);
this.verboseDescription.append("Loaded entry ingester: " + sei.getClass().getName());
SwordEntryIngester sei = SwordIngesterFactory
.getEntryInstance(context, deposit, collection);
this.verboseDescription
.append("Loaded entry ingester: " + sei.getClass().getName());
DepositResult result;
if (swordConfig.isEntryFirst())
{
// do the entry deposit
result = sei.ingest(context, deposit, collection, this.verboseDescription);
result = sei.ingest(context, deposit, collection,
this.verboseDescription);
// do the content deposit
result = sci.ingest(context, deposit, collection, this.verboseDescription, result);
this.verboseDescription.append("Archive ingest completed successfully");
result = sci.ingest(context, deposit, collection,
this.verboseDescription, result);
this.verboseDescription
.append("Archive ingest completed successfully");
}
else
{
// do the content deposit
result = sci.ingest(context, deposit, collection, this.verboseDescription);
result = sci.ingest(context, deposit, collection,
this.verboseDescription);
// do the entry deposit
result = sei.ingest(context, deposit, collection, this.verboseDescription, result, false);
this.verboseDescription.append("Archive ingest completed successfully");
result = sei.ingest(context, deposit, collection,
this.verboseDescription, result, false);
this.verboseDescription
.append("Archive ingest completed successfully");
}
// store the originals (this code deals with the possibility that that's not required)
this.storeOriginals(swordConfig, context, this.verboseDescription, deposit, result);
this.storeOriginals(swordConfig, context, this.verboseDescription,
deposit, result);
return result;
}
return result;
}
protected Collection getDepositTarget(Context context, String depositUrl, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
protected Collection getDepositTarget(Context context, String depositUrl,
SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
// get the target collection
Collection collection = urlManager.getCollection(context, depositUrl);
// get the target collection
Collection collection = urlManager.getCollection(context, depositUrl);
if (collection == null)
{
throw new SwordError(404);
}
this.verboseDescription.append("Performing deposit using deposit URL: " + depositUrl);
this.verboseDescription
.append("Performing deposit using deposit URL: " + depositUrl);
this.verboseDescription.append("Location resolves to collection with handle: " + collection.getHandle() +
" and name: " + collectionService.getName(collection));
this.verboseDescription
.append("Location resolves to collection with handle: " +
collection.getHandle() +
" and name: " + collectionService.getName(collection));
return collection;
}
return collection;
}
}

View File

@@ -2,12 +2,11 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
import org.apache.abdera.Abdera;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.Entry;
@@ -32,37 +31,45 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CollectionListManagerDSpace extends DSpaceSwordAPI implements CollectionListManager
public class CollectionListManagerDSpace extends DSpaceSwordAPI
implements CollectionListManager
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory.getInstance().getBasicWorkflowItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public Feed listCollectionContents(IRI colIRI, AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordServerException, SwordError, SwordAuthException
{
SwordContext sc = null;
try
{
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
sc = this.doAuth(authCredentials);
Context context = sc.getContext();
SwordUrlManager urlManager = config.getUrlManager(context, config);
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
Collection collection = urlManager.getCollection(context, colIRI.toString());
protected BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory
.getInstance().getBasicWorkflowItemService();
public Feed listCollectionContents(IRI colIRI,
AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordServerException, SwordError, SwordAuthException
{
SwordContext sc = null;
try
{
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
sc = this.doAuth(authCredentials);
Context context = sc.getContext();
SwordUrlManager urlManager = config.getUrlManager(context, config);
Collection collection = urlManager
.getCollection(context, colIRI.toString());
if (collection == null)
{
throw new SwordError(404);
}
List<Item> items = this.listItems(sc, collection, swordConfig);
return this.itemListToFeed(sc, items, swordConfig);
}
catch (DSpaceSwordException e)
{
throw new SwordServerException(e);
}
finally
List<Item> items = this.listItems(sc, collection, swordConfig);
return this.itemListToFeed(sc, items, swordConfig);
}
catch (DSpaceSwordException e)
{
throw new SwordServerException(e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
@@ -70,58 +77,67 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI implements Colle
sc.abort();
}
}
}
}
private Feed itemListToFeed(SwordContext sc, List<Item> items, SwordConfiguration swordConfig)
throws DSpaceSwordException
{
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
SwordUrlManager urlManager = config.getUrlManager(sc.getContext(), config);
private Feed itemListToFeed(SwordContext sc, List<Item> items,
SwordConfiguration swordConfig)
throws DSpaceSwordException
{
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
SwordUrlManager urlManager = config
.getUrlManager(sc.getContext(), config);
Abdera abdera = new Abdera();
Abdera abdera = new Abdera();
Feed feed = abdera.newFeed();
for (Item item : items)
{
Entry entry = feed.addEntry();
entry.setId(urlManager.getEditIRI(item).toString());
String title = this.stringMetadata(item, ConfigurationManager.getProperty("swordv2-server", "title.field"));
title = title == null? "Untitled" : title;
entry.setTitle(title);
entry.addLink(urlManager.getContentUrl(item).toString(), "edit-media");
}
for (Item item : items)
{
Entry entry = feed.addEntry();
entry.setId(urlManager.getEditIRI(item).toString());
String title = this.stringMetadata(item, ConfigurationManager
.getProperty("swordv2-server", "title.field"));
title = title == null ? "Untitled" : title;
entry.setTitle(title);
entry.addLink(urlManager.getContentUrl(item).toString(),
"edit-media");
}
return feed;
}
return feed;
}
private List<Item> listItems(SwordContext sc, Collection collection, SwordConfiguration swordConfig)
throws DSpaceSwordException
{
try
{
EPerson person = sc.getOnBehalfOf() != null ? sc.getOnBehalfOf() : sc.getAuthenticated();
List<Item> collectionItems = new ArrayList<Item>();
private List<Item> listItems(SwordContext sc, Collection collection,
SwordConfiguration swordConfig)
throws DSpaceSwordException
{
try
{
EPerson person = sc.getOnBehalfOf() != null ?
sc.getOnBehalfOf() :
sc.getAuthenticated();
List<Item> collectionItems = new ArrayList<Item>();
// first get the ones out of the archive
Iterator<Item> items = itemService.findBySubmitter(sc.getContext(), person);
while(items.hasNext())
{
Item item = items.next();
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
// first get the ones out of the archive
Iterator<Item> items = itemService
.findBySubmitter(sc.getContext(), person);
while (items.hasNext())
{
Item item = items.next();
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
// now get the ones out of the workspace
List<WorkspaceItem> wsis = workspaceItemService.findByEPerson(sc.getContext(), person);
for (WorkspaceItem wsi : wsis)
{
// now get the ones out of the workspace
List<WorkspaceItem> wsis = workspaceItemService
.findByEPerson(sc.getContext(), person);
for (WorkspaceItem wsi : wsis)
{
Item item = wsi.getItem();
// check for the wsi collection
@@ -132,22 +148,23 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI implements Colle
}
// then see if there are any additional associated collections
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
// finally get the ones out of the workflow
List<BasicWorkflowItem> wfis = basicWorkflowItemService.findByOwner(sc.getContext(), person);
for (BasicWorkflowItem wfi : wfis)
{
Item item = wfi.getItem();
// finally get the ones out of the workflow
List<BasicWorkflowItem> wfis = basicWorkflowItemService
.findByOwner(sc.getContext(), person);
for (BasicWorkflowItem wfi : wfis)
{
Item item = wfi.getItem();
// check for the wfi collection
Collection wfCol = wfi.getCollection();
@@ -157,47 +174,48 @@ public class CollectionListManagerDSpace extends DSpaceSwordAPI implements Colle
}
// then see if there are any additional associated collections
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
List<Collection> cols = item.getCollections();
for (Collection col : cols)
{
if (col.getID().equals(collection.getID()))
{
collectionItems.add(item);
break;
}
}
}
return collectionItems;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
return collectionItems;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
private String stringMetadata(Item item, String field)
{
if (field == null)
{
return null;
}
private String stringMetadata(Item item, String field)
{
if (field == null)
{
return null;
}
List<MetadataValue> dcvs = itemService.getMetadataByMetadataString(item, field);
if (dcvs == null)
{
return null;
}
List<MetadataValue> dcvs = itemService
.getMetadataByMetadataString(item, field);
if (dcvs == null)
{
return null;
}
StringBuilder md = new StringBuilder();
for (MetadataValue dcv : dcvs)
{
if (md.length() > 0)
{
md.append(", ");
}
md.append(dcv.getValue());
}
return md.toString();
}
StringBuilder md = new StringBuilder();
for (MetadataValue dcv : dcvs)
{
if (md.length() > 0)
{
md.append(", ");
}
md.append(dcv.getValue());
}
return md.toString();
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -25,68 +25,77 @@ import java.util.List;
public class CommunityCollectionGenerator implements AtomCollectionGenerator
{
private static Logger log = Logger.getLogger(CommunityCollectionGenerator.class);
private static Logger log = Logger
.getLogger(CommunityCollectionGenerator.class);
protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
public SwordCollection buildCollection(Context context, DSpaceObject dso, SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException
{
if (!(dso instanceof Community))
{
log.error("buildCollection passed something other than a Community object");
throw new DSpaceSwordException("Incorrect ATOMCollectionGenerator instantiated");
}
protected CommunityService communityService = ContentServiceFactory
.getInstance().getCommunityService();
// get the things we need out of the service
SwordUrlManager urlManager = swordConfig.getUrlManager(context, swordConfig);
public SwordCollection buildCollection(Context context, DSpaceObject dso,
SwordConfigurationDSpace swordConfig)
throws DSpaceSwordException
{
if (!(dso instanceof Community))
{
log.error(
"buildCollection passed something other than a Community object");
throw new DSpaceSwordException(
"Incorrect ATOMCollectionGenerator instantiated");
}
Community com = (Community) dso;
SwordCollection scol = new SwordCollection();
// get the things we need out of the service
SwordUrlManager urlManager = swordConfig
.getUrlManager(context, swordConfig);
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(com);
if (location == null)
{
location = handleService.getCanonicalForm(com.getHandle());
}
scol.setLocation(location);
Community com = (Community) dso;
SwordCollection scol = new SwordCollection();
// collection title is just the community name
String title = communityService.getName(com);
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// prepare the parameters to be put in the sword collection
String location = urlManager.getDepositLocation(com);
if (location == null)
{
location = handleService.getCanonicalForm(com.getHandle());
}
scol.setLocation(location);
// FIXME: the community has no obvious licence
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// collection title is just the community name
String title = communityService.getName(com);
if (StringUtils.isNotBlank(title))
{
scol.setTitle(title);
}
// abstract is the short description of the collection
List<MetadataValue> abstracts = communityService.getMetadataByMetadataString(com, "short_description");
if (abstracts != null && !abstracts.isEmpty())
{
String firstValue = abstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
// FIXME: the community has no obvious licence
// the collection policy is the licence to which the collection adheres
// String collectionPolicy = col.getLicense();
// do we support mediated deposit
scol.setMediation(swordConfig.isMediated());
// abstract is the short description of the collection
List<MetadataValue> abstracts = communityService
.getMetadataByMetadataString(com, "short_description");
if (abstracts != null && !abstracts.isEmpty())
{
String firstValue = abstracts.get(0).getValue();
if (StringUtils.isNotBlank(firstValue))
{
scol.setAbstract(firstValue);
}
}
// NOTE: for communities, there are no MIME types that it accepts.
// the list of mime types that we accept
// do we support mediated deposit
scol.setMediation(swordConfig.isMediated());
// offer up the collections from this item as deposit targets
String subService = urlManager.constructSubServiceUrl(com);
scol.addSubService(new IRI(subService));
// NOTE: for communities, there are no MIME types that it accepts.
// the list of mime types that we accept
log.debug("Created ATOM Collection for DSpace Community");
// offer up the collections from this item as deposit targets
String subService = urlManager.constructSubServiceUrl(com);
scol.addSubService(new IRI(subService));
return scol;
}
log.debug("Created ATOM Collection for DSpace Community");
return scol;
}
}

View File

@@ -2,12 +2,11 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
@@ -55,14 +54,21 @@ public class DSpaceSwordAPI
{
private static Logger log = Logger.getLogger(DSpaceSwordAPI.class);
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public SwordContext noAuthContext()
throws DSpaceSwordException
{
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
public SwordContext noAuthContext()
throws DSpaceSwordException
{
SwordContext sc = new SwordContext();
Context context = new Context();
sc.setContext(context);
@@ -84,9 +90,14 @@ public class DSpaceSwordAPI
SwordContext sc = auth.authenticate(authCredentials);
// log the request
String un = authCredentials.getUsername() != null ? authCredentials.getUsername() : "NONE";
String obo = authCredentials.getOnBehalfOf() != null ? authCredentials.getOnBehalfOf() : "NONE";
log.info(LogManager.getHeader(sc.getContext(), "sword_auth_request", "username=" + un + ",on_behalf_of=" + obo));
String un = authCredentials.getUsername() != null ?
authCredentials.getUsername() :
"NONE";
String obo = authCredentials.getOnBehalfOf() != null ?
authCredentials.getOnBehalfOf() :
"NONE";
log.info(LogManager.getHeader(sc.getContext(), "sword_auth_request",
"username=" + un + ",on_behalf_of=" + obo));
return sc;
}
@@ -139,7 +150,8 @@ public class DSpaceSwordAPI
if (components[1].trim().startsWith("q="))
{
// "type;q"
q = Float.parseFloat(components[1].trim().substring(2)); //strip the "q=" from the start of the q value
q = Float.parseFloat(components[1].trim().substring(
2)); //strip the "q=" from the start of the q value
// if the q value is the highest one we've seen so far, record it
if (q > highest_q)
@@ -157,7 +169,8 @@ public class DSpaceSwordAPI
{
// "type;params;q"
params = components[1].trim();
q = Float.parseFloat(components[1].trim().substring(2)); // strip the "q=" from the start of the q value
q = Float.parseFloat(components[1].trim().substring(
2)); // strip the "q=" from the start of the q value
// if the q value is the highest one we've seen so far, record it
if (q > highest_q)
@@ -211,7 +224,7 @@ public class DSpaceSwordAPI
// otherwise, we have to calculate the q value using the following equation which creates a q value "qv"
// within "q_range" of 1.0 [the first part of the eqn] based on the fraction of the way through the total
// accept header list scaled by the q_range [the second part of the eqn]
float nq = (1 - q_range) + (((-1 * qv)/counter) * q_range);
float nq = (1 - q_range) + (((-1 * qv) / counter) * q_range);
if (sorted.containsKey(nq))
{
sorted.get(nq).add(contentType);
@@ -228,28 +241,36 @@ public class DSpaceSwordAPI
return sorted;
}
public void isAcceptable(SwordConfigurationDSpace swordConfig, Context context, Deposit deposit, DSpaceObject dso)
public void isAcceptable(SwordConfigurationDSpace swordConfig,
Context context, Deposit deposit, DSpaceObject dso)
throws SwordError, DSpaceSwordException
{
// determine if this is an acceptable file format
if (!swordConfig.isAcceptableContentType(context, deposit.getMimeType(), dso))
if (!swordConfig
.isAcceptableContentType(context, deposit.getMimeType(), dso))
{
log.error("Unacceptable content type detected: " + deposit.getMimeType() + " for object " + dso.getID());
log.error("Unacceptable content type detected: " +
deposit.getMimeType() + " for object " + dso.getID());
throw new SwordError(UriRegistry.ERROR_CONTENT,
"Unacceptable content type in deposit request: " + deposit.getMimeType());
"Unacceptable content type in deposit request: " +
deposit.getMimeType());
}
// determine if this is an acceptable packaging type for the deposit
// if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
if (!swordConfig.isAcceptedPackaging(deposit.getPackaging(), dso))
{
log.error("Unacceptable packaging type detected: " + deposit.getPackaging() + " for object " + dso.getID());
log.error("Unacceptable packaging type detected: " +
deposit.getPackaging() + " for object " + dso.getID());
throw new SwordError(UriRegistry.ERROR_CONTENT,
"Unacceptable packaging type in deposit request: " + deposit.getPackaging());
"Unacceptable packaging type in deposit request: " +
deposit.getPackaging());
}
}
public void storeOriginals(SwordConfigurationDSpace swordConfig, Context context, VerboseDescription verboseDescription, Deposit deposit, DepositResult result)
public void storeOriginals(SwordConfigurationDSpace swordConfig,
Context context, VerboseDescription verboseDescription,
Deposit deposit, DepositResult result)
throws DSpaceSwordException, SwordServerException
{
// if there's an item availalble, and we want to keep the original
@@ -258,14 +279,16 @@ public class DSpaceSwordAPI
{
if (swordConfig.isKeepOriginal())
{
verboseDescription.append("DSpace will store an original copy of the deposit, " +
"as well as ingesting the item into the archive");
verboseDescription
.append("DSpace will store an original copy of the deposit, " +
"as well as ingesting the item into the archive");
// in order to be allowed to add the file back to the item, we need to ignore authorisations
// for a moment
context.turnOffAuthorisationSystem();
String bundleName = ConfigurationManager.getProperty("swordv2-server", "bundle.name");
String bundleName = ConfigurationManager
.getProperty("swordv2-server", "bundle.name");
if (bundleName == null || "".equals(bundleName))
{
bundleName = "SWORD";
@@ -283,20 +306,26 @@ public class DSpaceSwordAPI
}
if (swordBundle == null)
{
swordBundle = bundleService.create(context, item, bundleName);
swordBundle = bundleService
.create(context, item, bundleName);
}
if (deposit.isMultipart() || deposit.isEntryOnly())
{
String entry = deposit.getSwordEntry().toString();
ByteArrayInputStream bais = new ByteArrayInputStream(entry.getBytes());
Bitstream entryBitstream = bitstreamService.create(context, swordBundle, bais);
ByteArrayInputStream bais = new ByteArrayInputStream(
entry.getBytes());
Bitstream entryBitstream = bitstreamService
.create(context, swordBundle, bais);
String fn = this.createEntryFilename(context, deposit, true);
String fn = this
.createEntryFilename(context, deposit, true);
entryBitstream.setName(context, fn);
entryBitstream.setDescription(context, "Original SWORD entry document");
entryBitstream.setDescription(context,
"Original SWORD entry document");
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, "application/xml");
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, "application/xml");
if (bf != null)
{
entryBitstream.setFormat(context, bf);
@@ -304,7 +333,8 @@ public class DSpaceSwordAPI
bitstreamService.update(context, entryBitstream);
verboseDescription.append("Original entry stored as " + fn + ", in item bundle " + swordBundle);
verboseDescription.append("Original entry stored as " + fn +
", in item bundle " + swordBundle);
}
if (deposit.isMultipart() || deposit.isBinaryOnly())
@@ -316,7 +346,8 @@ public class DSpaceSwordAPI
try
{
fis = deposit.getInputStream();
bitstream = bitstreamService.create(context, swordBundle, fis);
bitstream = bitstreamService
.create(context, swordBundle, fis);
}
finally
{
@@ -334,9 +365,11 @@ public class DSpaceSwordAPI
}
bitstream.setName(context, fn);
bitstream.setDescription(context, "Original SWORD deposit file");
bitstream.setDescription(context,
"Original SWORD deposit file");
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getMimeType());
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getMimeType());
if (bf != null)
{
bitstream.setFormat(context, bf);
@@ -349,7 +382,9 @@ public class DSpaceSwordAPI
// shouldn't mess with it
result.setOriginalDeposit(bitstream);
}
verboseDescription.append("Original deposit stored as " + fn + ", in item bundle " + swordBundle);
verboseDescription
.append("Original deposit stored as " + fn +
", in item bundle " + swordBundle);
}
bundleService.update(context, swordBundle);
@@ -374,12 +409,14 @@ public class DSpaceSwordAPI
* @param original
* @throws DSpaceSwordException
*/
public String createFilename(Context context, Deposit deposit, boolean original)
public String createFilename(Context context, Deposit deposit,
boolean original)
throws DSpaceSwordException
{
try
{
BitstreamFormat bf = bitstreamFormatService.findByMIMEType(context, deposit.getMimeType());
BitstreamFormat bf = bitstreamFormatService
.findByMIMEType(context, deposit.getMimeType());
List<String> exts = null;
if (bf != null)
{
@@ -389,7 +426,8 @@ public class DSpaceSwordAPI
String fn = deposit.getFilename();
if (fn == null || "".equals(fn))
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss");
fn = "sword-" + sdf.format(new Date());
if (original)
{
@@ -409,7 +447,8 @@ public class DSpaceSwordAPI
}
}
public String createEntryFilename(Context context, Deposit deposit, boolean original)
public String createEntryFilename(Context context, Deposit deposit,
boolean original)
throws DSpaceSwordException
{
@@ -423,88 +462,102 @@ public class DSpaceSwordAPI
return fn + ".xml";
}
/**
* Store original package on disk and companion file containing SWORD headers as found in the deposit object
* Also write companion file with header info from the deposit object.
*
* @param deposit
*/
protected void storePackageAsFile(Deposit deposit, AuthCredentials auth, SwordConfigurationDSpace config) throws IOException
{
String path = config.getFailedPackageDir();
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory())
{
throw new IOException("Directory does not exist for writing packages on ingest error.");
}
String filenameBase = "sword-" + auth.getUsername() + "-" + (new Date()).getTime();
File packageFile = new File(path, filenameBase);
File headersFile = new File(path, filenameBase + "-headers");
InputStream is = new BufferedInputStream(new FileInputStream(deposit.getFile()));
OutputStream fos = new BufferedOutputStream(new FileOutputStream(packageFile));
Utils.copy(is, fos);
fos.close();
is.close();
//write companion file with headers
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(headersFile)));
pw.println("Filename=" + deposit.getFilename());
pw.println("Content-Type=" + deposit.getMimeType());
pw.println("Packaging=" + deposit.getPackaging());
pw.println("On Behalf of=" + auth.getOnBehalfOf());
pw.println("Slug=" + deposit.getSlug());
pw.println("User name=" + auth.getUsername());
pw.close();
}
/**
* Store original package on disk and companion file containing SWORD headers as found in the deposit object
* Also write companion file with header info from the deposit object.
*
* @param deposit
*/
protected void storeEntryAsFile(Deposit deposit, AuthCredentials auth, SwordConfigurationDSpace config) throws IOException
{
String path = config.getFailedPackageDir();
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory())
{
throw new IOException("Directory does not exist for writing packages on ingest error.");
}
String filenameBase = "sword-" + auth.getUsername() + "-" + (new Date()).getTime();
File packageFile = new File(path, filenameBase);
File headersFile = new File(path, filenameBase + "-headers");
String entry = deposit.getSwordEntry().toString();
ByteArrayInputStream is = new ByteArrayInputStream(entry.getBytes());
OutputStream fos = new BufferedOutputStream(new FileOutputStream(packageFile));
Utils.copy(is, fos);
fos.close();
is.close();
//write companion file with headers
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(headersFile)));
pw.println("Filename=" + deposit.getFilename());
pw.println("Content-Type=" + deposit.getMimeType());
pw.println("Packaging=" + deposit.getPackaging());
pw.println("On Behalf of=" + auth.getOnBehalfOf());
pw.println("Slug=" + deposit.getSlug());
pw.println("User name=" + auth.getUsername());
pw.close();
}
protected void addVerboseDescription(DepositReceipt receipt, VerboseDescription verboseDescription)
/**
* Store original package on disk and companion file containing SWORD headers as found in the deposit object
* Also write companion file with header info from the deposit object.
*
* @param deposit
*/
protected void storePackageAsFile(Deposit deposit, AuthCredentials auth,
SwordConfigurationDSpace config) throws IOException
{
boolean includeVerbose = ConfigurationManager.getBooleanProperty("swordv2-server", "verbose-description.receipt.enable");
String path = config.getFailedPackageDir();
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory())
{
throw new IOException(
"Directory does not exist for writing packages on ingest error.");
}
String filenameBase =
"sword-" + auth.getUsername() + "-" + (new Date()).getTime();
File packageFile = new File(path, filenameBase);
File headersFile = new File(path, filenameBase + "-headers");
InputStream is = new BufferedInputStream(
new FileInputStream(deposit.getFile()));
OutputStream fos = new BufferedOutputStream(
new FileOutputStream(packageFile));
Utils.copy(is, fos);
fos.close();
is.close();
//write companion file with headers
PrintWriter pw = new PrintWriter(
new BufferedWriter(new FileWriter(headersFile)));
pw.println("Filename=" + deposit.getFilename());
pw.println("Content-Type=" + deposit.getMimeType());
pw.println("Packaging=" + deposit.getPackaging());
pw.println("On Behalf of=" + auth.getOnBehalfOf());
pw.println("Slug=" + deposit.getSlug());
pw.println("User name=" + auth.getUsername());
pw.close();
}
/**
* Store original package on disk and companion file containing SWORD headers as found in the deposit object
* Also write companion file with header info from the deposit object.
*
* @param deposit
*/
protected void storeEntryAsFile(Deposit deposit, AuthCredentials auth,
SwordConfigurationDSpace config) throws IOException
{
String path = config.getFailedPackageDir();
File dir = new File(path);
if (!dir.exists() || !dir.isDirectory())
{
throw new IOException(
"Directory does not exist for writing packages on ingest error.");
}
String filenameBase =
"sword-" + auth.getUsername() + "-" + (new Date()).getTime();
File packageFile = new File(path, filenameBase);
File headersFile = new File(path, filenameBase + "-headers");
String entry = deposit.getSwordEntry().toString();
ByteArrayInputStream is = new ByteArrayInputStream(entry.getBytes());
OutputStream fos = new BufferedOutputStream(
new FileOutputStream(packageFile));
Utils.copy(is, fos);
fos.close();
is.close();
//write companion file with headers
PrintWriter pw = new PrintWriter(
new BufferedWriter(new FileWriter(headersFile)));
pw.println("Filename=" + deposit.getFilename());
pw.println("Content-Type=" + deposit.getMimeType());
pw.println("Packaging=" + deposit.getPackaging());
pw.println("On Behalf of=" + auth.getOnBehalfOf());
pw.println("Slug=" + deposit.getSlug());
pw.println("User name=" + auth.getUsername());
pw.close();
}
protected void addVerboseDescription(DepositReceipt receipt,
VerboseDescription verboseDescription)
{
boolean includeVerbose = ConfigurationManager
.getBooleanProperty("swordv2-server",
"verbose-description.receipt.enable");
if (includeVerbose)
{
receipt.setVerboseDescription(verboseDescription.toString());

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -19,24 +19,24 @@ import org.swordapp.server.SwordServerException;
public class DSpaceSwordException extends Exception
{
public DSpaceSwordException()
{
super();
}
public DSpaceSwordException()
{
super();
}
public DSpaceSwordException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public DSpaceSwordException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public DSpaceSwordException(String arg0)
{
super(arg0);
}
public DSpaceSwordException(String arg0)
{
super(arg0);
}
public DSpaceSwordException(Throwable arg0)
{
super(arg0);
}
public DSpaceSwordException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -2,42 +2,50 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
public class DSpaceUriRegistry
{
public static final String DSPACE_SWORD_NS = "http://www.dspace.org/ns/sword/2.0/";
public static final String DSPACE_SWORD_NS = "http://www.dspace.org/ns/sword/2.0/";
/** if unpackaging the package fails */
public static final String UNPACKAGE_FAIL = DSPACE_SWORD_NS + "errors/UnpackageFail";
/** if unpackaging the package fails */
public static final String UNPACKAGE_FAIL =
DSPACE_SWORD_NS + "errors/UnpackageFail";
/** if the url of the request does not resolve to something meaningful */
public static final String BAD_URL = DSPACE_SWORD_NS + "errors/BadUrl";
/** if the url of the request does not resolve to something meaningful */
public static final String BAD_URL = DSPACE_SWORD_NS + "errors/BadUrl";
/** if the media requested is unavailable */
public static final String MEDIA_UNAVAILABLE = DSPACE_SWORD_NS + "errors/MediaUnavailable";
/** if the media requested is unavailable */
public static final String MEDIA_UNAVAILABLE =
DSPACE_SWORD_NS + "errors/MediaUnavailable";
/* additional codes */
/** Invalid package */
public static final String PACKAGE_ERROR = DSPACE_SWORD_NS + "errors/PackageError";
public static final String PACKAGE_ERROR =
DSPACE_SWORD_NS + "errors/PackageError";
/** Missing resources in package */
public static final String PACKAGE_VALIDATION_ERROR = DSPACE_SWORD_NS + "errors/PackageValidationError";
public static final String PACKAGE_VALIDATION_ERROR =
DSPACE_SWORD_NS + "errors/PackageValidationError";
/** Crosswalk error */
public static final String CROSSWALK_ERROR = DSPACE_SWORD_NS + "errors/CrosswalkError";
public static final String CROSSWALK_ERROR =
DSPACE_SWORD_NS + "errors/CrosswalkError";
/** Invalid collection for linking */
public static final String COLLECTION_LINK_ERROR = DSPACE_SWORD_NS + "errors/CollectionLinkError";
public static final String COLLECTION_LINK_ERROR =
DSPACE_SWORD_NS + "errors/CollectionLinkError";
/** Database or IO Error when installing new item */
public static final String REPOSITORY_ERROR = DSPACE_SWORD_NS + "errors/RepositoryError";
public static final String REPOSITORY_ERROR =
DSPACE_SWORD_NS + "errors/RepositoryError";
// FIXME: this is being withdrawn from all 406 responses for the time being, in preference
// for ErrorContent as per the spec (whether that is right or wrong)
public static final String NOT_ACCEPTABLE = DSPACE_SWORD_NS + "errors/NotAcceptable";
public static final String NOT_ACCEPTABLE =
DSPACE_SWORD_NS + "errors/NotAcceptable";
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -23,55 +23,55 @@ import java.util.Map;
*/
public class DepositResult
{
/** the item created during deposit */
private Item item;
/** the item created during deposit */
private Item item;
/** Bitstream created as a result of the deposit */
private Bitstream originalDeposit;
/** Bitstream created as a result of the deposit */
private Bitstream originalDeposit;
private List<Bitstream> derivedResources;
private List<Bitstream> derivedResources;
/** The treatment of the item during deposit */
private String treatment;
/** The treatment of the item during deposit */
private String treatment;
public Item getItem()
{
return item;
}
public Item getItem()
{
return item;
}
public void setItem(Item item)
{
this.item = item;
}
public void setItem(Item item)
{
this.item = item;
}
public Bitstream getOriginalDeposit()
{
return originalDeposit;
}
public Bitstream getOriginalDeposit()
{
return originalDeposit;
}
public void setOriginalDeposit(Bitstream originalDeposit)
{
this.originalDeposit = originalDeposit;
}
public void setOriginalDeposit(Bitstream originalDeposit)
{
this.originalDeposit = originalDeposit;
}
public List<Bitstream> getDerivedResources()
{
return derivedResources;
}
public List<Bitstream> getDerivedResources()
{
return derivedResources;
}
public void setDerivedResources(List<Bitstream> derivedResources)
{
this.derivedResources = derivedResources;
}
public void setDerivedResources(List<Bitstream> derivedResources)
{
this.derivedResources = derivedResources;
}
public String getTreatment()
{
return treatment;
}
public String getTreatment()
{
return treatment;
}
public void setTreatment(String treatment)
{
this.treatment = treatment;
}
public void setTreatment(String treatment)
{
this.treatment = treatment;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -26,7 +26,8 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
public class FeedContentDisseminator extends AbstractSimpleDC implements SwordContentDisseminator
public class FeedContentDisseminator extends AbstractSimpleDC
implements SwordContentDisseminator
{
public InputStream disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException
@@ -43,10 +44,13 @@ public class FeedContentDisseminator extends AbstractSimpleDC implements SwordCo
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
List<BundleBitstream> bundleBitstreams = bundle.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams) {
List<BundleBitstream> bundleBitstreams = bundle
.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
Entry entry = feed.addEntry();
this.populateEntry(context, entry, bundleBitstream.getBitstream());
this.populateEntry(context, entry,
bundleBitstream.getBitstream());
}
}
}
@@ -90,13 +94,17 @@ public class FeedContentDisseminator extends AbstractSimpleDC implements SwordCo
}
}
private void populateEntry(Context context, Entry entry, Bitstream bitstream)
private void populateEntry(Context context, Entry entry,
Bitstream bitstream)
throws DSpaceSwordException
{
BitstreamFormat format = null;
try {
try
{
format = bitstream.getFormat(context);
} catch (SQLException e) {
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
String contentType = null;
@@ -105,7 +113,8 @@ public class FeedContentDisseminator extends AbstractSimpleDC implements SwordCo
contentType = format.getMIMEType();
}
SwordUrlManager urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context);
SwordUrlManager urlManager = new SwordUrlManager(
new SwordConfigurationDSpace(), context);
String bsUrl = urlManager.getBitstreamUrl(bitstream);
entry.setId(bsUrl);
@@ -133,10 +142,12 @@ public class FeedContentDisseminator extends AbstractSimpleDC implements SwordCo
public boolean disseminatesContentType(String contentType)
throws DSpaceSwordException, SwordError, SwordServerException
{
return "application/atom+xml".equals(contentType) || "application/atom+xml;type=feed".equals(contentType);
return "application/atom+xml".equals(contentType) ||
"application/atom+xml;type=feed".equals(contentType);
}
public boolean disseminatesPackage(String contentType) throws DSpaceSwordException, SwordError, SwordServerException
public boolean disseminatesPackage(String contentType)
throws DSpaceSwordException, SwordError, SwordServerException
{
// we're just going to ignore packaging formats here
return true;

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -24,135 +24,152 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class GenericStatementDisseminator implements SwordStatementDisseminator
public abstract class GenericStatementDisseminator
implements SwordStatementDisseminator
{
protected SwordUrlManager urlManager;
protected SwordUrlManager urlManager;
protected void populateStatement(Context context, Item item, Statement statement)
throws DSpaceSwordException
{
this.urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context);
protected void populateStatement(Context context, Item item,
Statement statement)
throws DSpaceSwordException
{
this.urlManager = new SwordUrlManager(new SwordConfigurationDSpace(),
context);
List<String> includeBundles = this.getIncludeBundles();
String originalDepositBundle = this.getOriginalDepositsBundle();
// we only list the original deposits in full if the sword bundle is in the includeBundles
if (includeBundles.contains(originalDepositBundle))
{
List<OriginalDeposit> originalDeposits = this.getOriginalDeposits(context, item, originalDepositBundle);
List<OriginalDeposit> originalDeposits = this
.getOriginalDeposits(context, item, originalDepositBundle);
statement.setOriginalDeposits(originalDeposits);
}
Map<String, String> states = this.getStates(context, item);
Map<String, String> states = this.getStates(context, item);
statement.setStates(states);
// remove the original deposit bundle from the include bundles
includeBundles.remove(originalDepositBundle);
List<ResourcePart> resources = this.getResourceParts(context, item, includeBundles);
List<ResourcePart> resources = this
.getResourceParts(context, item, includeBundles);
statement.setResources(resources);
Date lastModified = this.getLastModified(context, item);
statement.setLastModified(lastModified);
}
}
protected List<OriginalDeposit> getOriginalDeposits(Context context, Item item, String swordBundle)
throws DSpaceSwordException
{
try
{
protected List<OriginalDeposit> getOriginalDeposits(Context context,
Item item, String swordBundle)
throws DSpaceSwordException
{
try
{
// NOTE: DSpace does not store file metadata, so we can't access the information
// about who deposited what, when, on behalf of whoever.
List<OriginalDeposit> originalDeposits = new ArrayList<OriginalDeposit>();
List<OriginalDeposit> originalDeposits = new ArrayList<OriginalDeposit>();
// an original deposit is everything in the SWORD bundle
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (swordBundle.equals(bundle.getName()))
{
List<BundleBitstream> bundleBitstreams = bundle.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams) {
// note that original deposits don't have actionable urls
OriginalDeposit deposit = new OriginalDeposit(this.urlManager.getBitstreamUrl(bundleBitstream.getBitstream()));
deposit.setMediaType(bundleBitstream.getBitstream().getFormat(context).getMIMEType());
originalDeposits.add(deposit);
}
}
}
return originalDeposits;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (swordBundle.equals(bundle.getName()))
{
List<BundleBitstream> bundleBitstreams = bundle
.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// note that original deposits don't have actionable urls
OriginalDeposit deposit = new OriginalDeposit(
this.urlManager.getBitstreamUrl(
bundleBitstream.getBitstream()));
deposit.setMediaType(bundleBitstream.getBitstream()
.getFormat(context).getMIMEType());
originalDeposits.add(deposit);
}
}
}
return originalDeposits;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
protected Map<String, String> getStates(Context context, Item item)
throws DSpaceSwordException
{
SwordConfigurationDSpace config = new SwordConfigurationDSpace();
WorkflowTools wft = new WorkflowTools();
Map<String, String> states = new HashMap<String, String>();
if (item.isWithdrawn())
{
String uri = config.getStateUri("withdrawn");
String desc = config.getStateDescription("withdrawn");
states.put(uri, desc);
}
else if (item.isArchived())
{
String uri = config.getStateUri("archive");
String desc = config.getStateDescription("archive");
states.put(uri, desc);
}
else if (wft.isItemInWorkflow(context, item))
{
String uri = config.getStateUri("workflow");
String desc = config.getStateDescription("workflow");
states.put(uri, desc);
}
else if (wft.isItemInWorkspace(context, item))
{
String uri = config.getStateUri("workspace");
String desc = config.getStateDescription("workspace");
states.put(uri, desc);
}
return states;
}
protected Map<String, String> getStates(Context context, Item item)
throws DSpaceSwordException
{
SwordConfigurationDSpace config = new SwordConfigurationDSpace();
WorkflowTools wft = new WorkflowTools();
Map<String, String> states = new HashMap<String, String>();
if (item.isWithdrawn())
{
String uri = config.getStateUri("withdrawn");
String desc = config.getStateDescription("withdrawn");
states.put(uri, desc);
}
else if (item.isArchived())
{
String uri = config.getStateUri("archive");
String desc = config.getStateDescription("archive");
states.put(uri, desc);
}
else if (wft.isItemInWorkflow(context, item))
{
String uri = config.getStateUri("workflow");
String desc = config.getStateDescription("workflow");
states.put(uri, desc);
}
else if (wft.isItemInWorkspace(context, item))
{
String uri = config.getStateUri("workspace");
String desc = config.getStateDescription("workspace");
states.put(uri, desc);
}
return states;
}
protected List<ResourcePart> getResourceParts(Context context, Item item, List<String> includeBundles)
throws DSpaceSwordException
{
try
{
// the list of resource parts is everything in the bundles to be included
List<ResourcePart> resources = new ArrayList<ResourcePart>();
protected List<ResourcePart> getResourceParts(Context context, Item item,
List<String> includeBundles)
throws DSpaceSwordException
{
try
{
// the list of resource parts is everything in the bundles to be included
List<ResourcePart> resources = new ArrayList<ResourcePart>();
for (String bundleName : includeBundles)
{
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (bundleName.equals(bundle.getName()))
{
List<BundleBitstream> bundleBitstreams = bundle.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams) {
// note that individual bitstreams have actionable urls
ResourcePart part = new ResourcePart(this.urlManager.getActionableBitstreamUrl(bundleBitstream.getBitstream()));
part.setMediaType(bundleBitstream.getBitstream().getFormat(context).getMIMEType());
resources.add(part);
}
}
if (bundleName.equals(bundle.getName()))
{
List<BundleBitstream> bundleBitstreams = bundle
.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// note that individual bitstreams have actionable urls
ResourcePart part = new ResourcePart(this.urlManager
.getActionableBitstreamUrl(
bundleBitstream.getBitstream()));
part.setMediaType(bundleBitstream.getBitstream()
.getFormat(context).getMIMEType());
resources.add(part);
}
}
}
}
return resources;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
return resources;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
protected Date getLastModified(Context context, Item item)
{
@@ -161,7 +178,8 @@ public abstract class GenericStatementDisseminator implements SwordStatementDiss
private List<String> getIncludeBundles()
{
String cfg = ConfigurationManager.getProperty("swordv2-server", "statement.bundles");
String cfg = ConfigurationManager
.getProperty("swordv2-server", "statement.bundles");
if (cfg == null || "".equals(cfg))
{
cfg = "ORIGINAL, SWORD";
@@ -181,7 +199,8 @@ public abstract class GenericStatementDisseminator implements SwordStatementDiss
private String getOriginalDepositsBundle()
{
String swordBundle = ConfigurationManager.getProperty("swordv2-server", "bundle.name");
String swordBundle = ConfigurationManager
.getProperty("swordv2-server", "bundle.name");
if (swordBundle == null)
{
swordBundle = "SWORD";

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -14,15 +14,18 @@ import org.swordapp.server.Statement;
import org.swordapp.server.SwordError;
import org.swordapp.server.SwordServerException;
public class OreStatementDisseminator extends GenericStatementDisseminator implements SwordStatementDisseminator
public class OreStatementDisseminator extends GenericStatementDisseminator
implements SwordStatementDisseminator
{
public Statement disseminate(Context context, Item item) throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context);
String aggUrl = urlManager.getAggregationUrl(item);
String remUrl = urlManager.getOreStatementUri(item);
Statement s = new OREStatement(remUrl, aggUrl);
this.populateStatement(context, item, s);
return s;
}
public Statement disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = new SwordUrlManager(
new SwordConfigurationDSpace(), context);
String aggUrl = urlManager.getAggregationUrl(item);
String remUrl = urlManager.getOreStatementUri(item);
Statement s = new OREStatement(remUrl, aggUrl);
this.populateStatement(context, item, s);
return s;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -35,24 +35,28 @@ import java.util.Map;
*/
public class ReceiptGenerator
{
/** logger */
private static Logger log = Logger.getLogger(ReceiptGenerator.class);
/** logger */
private static Logger log = Logger.getLogger(ReceiptGenerator.class);
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
protected DepositReceipt createFileReceipt(Context context, DepositResult result, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
protected DepositReceipt createFileReceipt(Context context,
DepositResult result, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
receipt.setLocation(new IRI(urlManager.getActionableBitstreamUrl(result.getOriginalDeposit())));
receipt.setEmpty(true);
receipt.setLocation(new IRI(urlManager
.getActionableBitstreamUrl(result.getOriginalDeposit())));
receipt.setEmpty(true);
return receipt;
}
return receipt;
}
protected DepositReceipt createMediaResourceReceipt(Context context, Item item, SwordConfigurationDSpace config)
protected DepositReceipt createMediaResourceReceipt(Context context,
Item item, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
@@ -61,192 +65,222 @@ public class ReceiptGenerator
return receipt;
}
protected DepositReceipt createReceipt(Context context, DepositResult result, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
return this.createReceipt(context, result, config, false);
}
protected DepositReceipt createReceipt(Context context,
DepositResult result, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
return this.createReceipt(context, result, config, false);
}
/**
* Construct the entry
*
* @throws DSpaceSwordException
*/
protected DepositReceipt createReceipt(Context context, DepositResult result, SwordConfigurationDSpace config, boolean mediaResourceLocation)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
/**
* Construct the entry
*
* @throws DSpaceSwordException
*/
protected DepositReceipt createReceipt(Context context,
DepositResult result, SwordConfigurationDSpace config,
boolean mediaResourceLocation)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
receipt.setAtomStatementURI(urlManager.getAtomStatementUri(result.getItem()));
receipt.setOREStatementURI(urlManager.getOreStatementUri(result.getItem()));
receipt.setEditIRI(urlManager.getEditIRI(result.getItem()));
receipt.setSplashUri(urlManager.getSplashUrl(result.getItem()));
receipt.setSwordEditIRI(urlManager.getEditIRI(result.getItem()));
receipt.setTreatment(result.getTreatment());
receipt.setContent(urlManager.getContentUrl(result.getItem()), "application/zip");
receipt.addEditMediaIRI(urlManager.getContentUrl(result.getItem()), "application/zip");
receipt.setAtomStatementURI(
urlManager.getAtomStatementUri(result.getItem()));
receipt.setOREStatementURI(
urlManager.getOreStatementUri(result.getItem()));
receipt.setEditIRI(urlManager.getEditIRI(result.getItem()));
receipt.setSplashUri(urlManager.getSplashUrl(result.getItem()));
receipt.setSwordEditIRI(urlManager.getEditIRI(result.getItem()));
receipt.setTreatment(result.getTreatment());
receipt.setContent(urlManager.getContentUrl(result.getItem()),
"application/zip");
receipt.addEditMediaIRI(urlManager.getContentUrl(result.getItem()),
"application/zip");
receipt.setMediaFeedIRI(urlManager.getMediaFeedUrl(result.getItem()));
receipt.setLastModified(result.getItem().getLastModified());
if (mediaResourceLocation)
{
receipt.setLocation(urlManager.getContentUrl(result.getItem()));
}
else
{
receipt.setLocation(urlManager.getEditIRI(result.getItem()));
}
if (mediaResourceLocation)
{
receipt.setLocation(urlManager.getContentUrl(result.getItem()));
}
else
{
receipt.setLocation(urlManager.getEditIRI(result.getItem()));
}
try
{
Bitstream od = result.getOriginalDeposit();
if (od != null)
{
// note here that we don't provide an actionable url
receipt.setOriginalDeposit(urlManager.getActionableBitstreamUrl(od), od.getFormat(context).getMIMEType());
}
try
{
Bitstream od = result.getOriginalDeposit();
if (od != null)
{
// note here that we don't provide an actionable url
receipt.setOriginalDeposit(
urlManager.getActionableBitstreamUrl(od),
od.getFormat(context).getMIMEType());
}
Map<String, String> derived = new HashMap<String, String>();
List<Bitstream> drs = result.getDerivedResources();
if (drs != null) {
for (Bitstream bs : result.getDerivedResources()) {
// here we provide actionable urls for the parts of the resource
derived.put(urlManager.getActionableBitstreamUrl(bs), bs.getFormat(context).getMIMEType());
}
}
receipt.setDerivedResources(derived);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
Map<String, String> derived = new HashMap<String, String>();
List<Bitstream> drs = result.getDerivedResources();
if (drs != null)
{
for (Bitstream bs : result.getDerivedResources())
{
// here we provide actionable urls for the parts of the resource
derived.put(urlManager.getActionableBitstreamUrl(bs),
bs.getFormat(context).getMIMEType());
}
}
receipt.setDerivedResources(derived);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
// add the category information to the sword entry
this.addCategories(result, receipt);
// add the category information to the sword entry
this.addCategories(result, receipt);
// add the publish date
this.addPublishDate(result, receipt);
// add the publish date
this.addPublishDate(result, receipt);
// add the item's metadata
SwordEntryDisseminator disseminator = SwordDisseminatorFactory.getEntryInstance();
SwordEntryDisseminator disseminator = SwordDisseminatorFactory
.getEntryInstance();
disseminator.disseminate(context, result.getItem(), receipt);
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = result.getItem().getBundles();
for (Bundle bundle : bundles) {
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = result.getItem().getBundles();
for (Bundle bundle : bundles)
{
if (!Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName()))
{
continue;
}
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss) {
for (BundleBitstream bs : bss)
{
String url = urlManager.getBitstreamUrl(bs.getBitstream());
rightsString.append(url).append(" ");
}
}
receipt.getWrappedEntry().setRights(rightsString.toString());
receipt.getWrappedEntry().setRights(rightsString.toString());
// add the date on which the entry was last updated
this.addLastUpdatedDate(result, receipt);
// add the date on which the entry was last updated
this.addLastUpdatedDate(result, receipt);
// do this from configuration
receipt.setPackaging(config.getDisseminatePackaging());
// do this from configuration
receipt.setPackaging(config.getDisseminatePackaging());
return receipt;
}
return receipt;
}
/**
* Construct the entry
*
* @throws DSpaceSwordException
*/
protected DepositReceipt createReceipt(Context context, Item item, SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
/**
* Construct the entry
*
* @throws DSpaceSwordException
*/
protected DepositReceipt createReceipt(Context context, Item item,
SwordConfigurationDSpace config)
throws DSpaceSwordException, SwordError, SwordServerException
{
SwordUrlManager urlManager = config.getUrlManager(context, config);
DepositReceipt receipt = new DepositReceipt();
receipt.setAtomStatementURI(urlManager.getAtomStatementUri(item));
receipt.setOREStatementURI(urlManager.getOreStatementUri(item));
receipt.setEditIRI(urlManager.getEditIRI(item));
receipt.setLocation(urlManager.getEditIRI(item));
receipt.setSplashUri(urlManager.getSplashUrl(item));
receipt.setSwordEditIRI(urlManager.getEditIRI(item));
receipt.setContent(urlManager.getContentUrl(item), "application/zip");
receipt.addEditMediaIRI(urlManager.getContentUrl(item), "application/zip");
receipt.setAtomStatementURI(urlManager.getAtomStatementUri(item));
receipt.setOREStatementURI(urlManager.getOreStatementUri(item));
receipt.setEditIRI(urlManager.getEditIRI(item));
receipt.setLocation(urlManager.getEditIRI(item));
receipt.setSplashUri(urlManager.getSplashUrl(item));
receipt.setSwordEditIRI(urlManager.getEditIRI(item));
receipt.setContent(urlManager.getContentUrl(item), "application/zip");
receipt.addEditMediaIRI(urlManager.getContentUrl(item),
"application/zip");
receipt.setMediaFeedIRI(urlManager.getMediaFeedUrl(item));
receipt.setLastModified(item.getLastModified());
// add the category information to the sword entry
this.addCategories(item, receipt);
// add the category information to the sword entry
this.addCategories(item, receipt);
// add the publish date
this.addPublishDate(item, receipt);
// add the publish date
this.addPublishDate(item, receipt);
// add the item's metadata
SwordEntryDisseminator disseminator = SwordDisseminatorFactory.getEntryInstance();
SwordEntryDisseminator disseminator = SwordDisseminatorFactory
.getEntryInstance();
disseminator.disseminate(context, item, receipt);
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles) {
StringBuilder rightsString = new StringBuilder();
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (!Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName()))
{
continue;
}
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bs : bss) {
for (BundleBitstream bs : bss)
{
String url = urlManager.getBitstreamUrl(bs.getBitstream());
rightsString.append(url).append(" ");
}
}
receipt.getWrappedEntry().setRights(rightsString.toString());
receipt.getWrappedEntry().setRights(rightsString.toString());
// add the date on which the entry was last updated
this.addLastUpdatedDate(item, receipt);
// add the date on which the entry was last updated
this.addLastUpdatedDate(item, receipt);
// do this from configuration
receipt.setPackaging(config.getDisseminatePackaging());
// do this from configuration
receipt.setPackaging(config.getDisseminatePackaging());
return receipt;
}
return receipt;
}
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories(DepositResult result, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(result.getItem(), "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv) {
receipt.getWrappedEntry().addCategory(UriRegistry.DC_NAMESPACE, aDcv.getValue(), aDcv.getValue());
}
}
}
/**
* Add all the subject classifications from the bibliographic
* metadata.
*
*/
protected void addCategories(DepositResult result, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(result.getItem(), "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
receipt.getWrappedEntry()
.addCategory(UriRegistry.DC_NAMESPACE, aDcv.getValue(),
aDcv.getValue());
}
}
}
protected void addCategories(Item item, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv) {
receipt.getWrappedEntry().addCategory(UriRegistry.DC_NAMESPACE, aDcv.getValue(), aDcv.getValue());
}
}
}
protected void addCategories(Item item, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.subject.*");
if (dcv != null)
{
for (MetadataValue aDcv : dcv)
{
receipt.getWrappedEntry()
.addCategory(UriRegistry.DC_NAMESPACE, aDcv.getValue(),
aDcv.getValue());
}
}
}
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate(DepositResult result, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(result.getItem(), "dc.date.issued");
if (dcv != null && !dcv.isEmpty())
/**
* Add the date of publication from the bibliographic metadata
*
*/
protected void addPublishDate(DepositResult result, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(result.getItem(),
"dc.date.issued");
if (dcv != null && !dcv.isEmpty())
{
try
{
@@ -257,15 +291,16 @@ public class ReceiptGenerator
catch (ParseException e)
{
// we tried, but never mind
log.warn("Couldn't add published date", e);
}
log.warn("Couldn't add published date", e);
}
}
}
}
protected void addPublishDate(Item item, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, "dc.date.issued");
if (dcv != null && dcv.size() == 1)
protected void addPublishDate(Item item, DepositReceipt receipt)
{
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, "dc.date.issued");
if (dcv != null && dcv.size() == 1)
{
try
{
@@ -276,20 +311,23 @@ public class ReceiptGenerator
catch (ParseException e)
{
// we tried, but never mind
log.warn("Couldn't add published date", e);
log.warn("Couldn't add published date", e);
}
}
}
}
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate(DepositResult result, DepositReceipt receipt)
{
String config = ConfigurationManager.getProperty("swordv2-server", "updated.field");
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(result.getItem(), config);
if (dcv != null && dcv.size() == 1)
/**
* Add the date that this item was last updated
*
*/
protected void addLastUpdatedDate(DepositResult result,
DepositReceipt receipt)
{
String config = ConfigurationManager
.getProperty("swordv2-server", "updated.field");
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(result.getItem(), config);
if (dcv != null && dcv.size() == 1)
{
try
{
@@ -300,16 +338,18 @@ public class ReceiptGenerator
catch (ParseException e)
{
// we tried, but never mind
log.warn("Couldn't add last updated date", e);
log.warn("Couldn't add last updated date", e);
}
}
}
}
protected void addLastUpdatedDate(Item item, DepositReceipt receipt)
{
String config = ConfigurationManager.getProperty("swordv2-server", "updated.field");
List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, config);
if (dcv != null && dcv.size() == 1)
protected void addLastUpdatedDate(Item item, DepositReceipt receipt)
{
String config = ConfigurationManager
.getProperty("swordv2-server", "updated.field");
List<MetadataValue> dcv = itemService
.getMetadataByMetadataString(item, config);
if (dcv != null && dcv.size() == 1)
{
try
{
@@ -320,8 +360,8 @@ public class ReceiptGenerator
catch (ParseException e)
{
// we tried, but never mind
log.warn("Couldn't add last updated date", e);
log.warn("Couldn't add last updated date", e);
}
}
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -30,151 +30,179 @@ import java.util.List;
public class ServiceDocumentManagerDSpace implements ServiceDocumentManager
{
/** logger */
private static Logger log = Logger.getLogger(ServiceDocumentManagerDSpace.class);
/** logger */
private static Logger log = Logger
.getLogger(ServiceDocumentManagerDSpace.class);
protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
protected CommunityService communityService = ContentServiceFactory
.getInstance().getCommunityService();
public ServiceDocument getServiceDocument(String sdUri, AuthCredentials authCredentials, SwordConfiguration config)
throws SwordError, SwordServerException, SwordAuthException
{
SwordContext sc = null;
public ServiceDocument getServiceDocument(String sdUri,
AuthCredentials authCredentials, SwordConfiguration config)
throws SwordError, SwordServerException, SwordAuthException
{
SwordContext sc = null;
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SwordAuthenticator auth = new SwordAuthenticator();
sc = auth.authenticate(authCredentials);
Context context = sc.getContext();
try
{
// first authenticate the request
// note: this will build our various DSpace contexts for us
SwordAuthenticator auth = new SwordAuthenticator();
sc = auth.authenticate(authCredentials);
Context context = sc.getContext();
// ensure that this method is allowed
WorkflowManagerFactory.getInstance().retrieveServiceDoc(context);
// ensure that this method is allowed
WorkflowManagerFactory.getInstance().retrieveServiceDoc(context);
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_do_service_document", ""));
}
if (log.isDebugEnabled())
{
log.debug(LogManager
.getHeader(context, "sword_do_service_document", ""));
}
// log the request
String un = authCredentials.getUsername() != null ? authCredentials.getUsername() : "NONE";
String obo = authCredentials.getOnBehalfOf() != null ? authCredentials.getOnBehalfOf() : "NONE";
log.info(LogManager.getHeader(context, "sword_service_document_request", "username=" + un + ",on_behalf_of=" + obo));
// log the request
String un = authCredentials.getUsername() != null ?
authCredentials.getUsername() :
"NONE";
String obo = authCredentials.getOnBehalfOf() != null ?
authCredentials.getOnBehalfOf() :
"NONE";
log.info(LogManager
.getHeader(context, "sword_service_document_request",
"username=" + un + ",on_behalf_of=" + obo));
return this.getServiceDocument(sc, sdUri, (SwordConfigurationDSpace) config);
}
catch (DSpaceSwordException e)
{
log.error("caught exception: ", e);
throw new SwordServerException("The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
return this.getServiceDocument(sc, sdUri,
(SwordConfigurationDSpace) config);
}
catch (DSpaceSwordException e)
{
log.error("caught exception: ", e);
throw new SwordServerException(
"The DSpace SWORD interface experienced an error", e);
}
finally
{
// this is a read operation only, so there's never any need to commit the context
if (sc != null)
{
sc.abort();
}
}
}
}
}
public ServiceDocument getServiceDocument(SwordContext context, String url, SwordConfigurationDSpace swordConfig)
throws SwordError, SwordServerException, DSpaceSwordException
{
// first check that the sword context have
// been set
if (context == null)
{
throw new DSpaceSwordException("The Sword Context is null; please set it before calling getServiceDocument");
}
public ServiceDocument getServiceDocument(SwordContext context, String url,
SwordConfigurationDSpace swordConfig)
throws SwordError, SwordServerException, DSpaceSwordException
{
// first check that the sword context have
// been set
if (context == null)
{
throw new DSpaceSwordException(
"The Sword Context is null; please set it before calling getServiceDocument");
}
// ensure that this method is allowed
WorkflowManagerFactory.getInstance().retrieveServiceDoc(context.getContext());
// ensure that this method is allowed
WorkflowManagerFactory.getInstance()
.retrieveServiceDoc(context.getContext());
// get the URL manager
SwordUrlManager urlManager = swordConfig.getUrlManager(context.getContext(), swordConfig);
// get the URL manager
SwordUrlManager urlManager = swordConfig
.getUrlManager(context.getContext(), swordConfig);
// we'll need the authenticator
SwordAuthenticator swordAuth = new SwordAuthenticator();
// we'll need the authenticator
SwordAuthenticator swordAuth = new SwordAuthenticator();
// construct the ATOM collection generators that we might use
AtomCollectionGenerator comGen = new CommunityCollectionGenerator();
AtomCollectionGenerator colGen = new CollectionCollectionGenerator();
// construct the ATOM collection generators that we might use
AtomCollectionGenerator comGen = new CommunityCollectionGenerator();
AtomCollectionGenerator colGen = new CollectionCollectionGenerator();
// construct a new service document
ServiceDocument service = new ServiceDocument();
// construct a new service document
ServiceDocument service = new ServiceDocument();
// set the max upload size
service.setMaxUploadSize(swordConfig.getMaxUploadSize());
// set the max upload size
service.setMaxUploadSize(swordConfig.getMaxUploadSize());
if (url == null || urlManager.isBaseServiceDocumentUrl(url))
{
// we are dealing with the default service document
if (url == null || urlManager.isBaseServiceDocumentUrl(url))
{
// we are dealing with the default service document
// set the title of the workspace as per the name of the DSpace installation
String ws = ConfigurationManager.getProperty("dspace.name");
SwordWorkspace workspace = new SwordWorkspace();
workspace.setTitle(ws);
// set the title of the workspace as per the name of the DSpace installation
String ws = ConfigurationManager.getProperty("dspace.name");
SwordWorkspace workspace = new SwordWorkspace();
workspace.setTitle(ws);
// next thing to do is determine whether the default is communities or collections
boolean swordCommunities = ConfigurationManager.getBooleanProperty("swordv2-server", "expose-communities");
// next thing to do is determine whether the default is communities or collections
boolean swordCommunities = ConfigurationManager
.getBooleanProperty("swordv2-server", "expose-communities");
if (swordCommunities)
{
List<Community> comms = swordAuth.getAllowedCommunities(context);
for (Community comm : comms)
{
SwordCollection scol = comGen.buildCollection(context.getContext(), comm, swordConfig);
workspace.addCollection(scol);
}
}
else
{
List<Collection> cols = swordAuth.getAllowedCollections(context);
for (Collection col : cols)
{
SwordCollection scol = colGen.buildCollection(context.getContext(), col, swordConfig);
workspace.addCollection(scol);
}
}
if (swordCommunities)
{
List<Community> comms = swordAuth
.getAllowedCommunities(context);
for (Community comm : comms)
{
SwordCollection scol = comGen
.buildCollection(context.getContext(), comm,
swordConfig);
workspace.addCollection(scol);
}
}
else
{
List<Collection> cols = swordAuth
.getAllowedCollections(context);
for (Collection col : cols)
{
SwordCollection scol = colGen
.buildCollection(context.getContext(), col,
swordConfig);
workspace.addCollection(scol);
}
}
service.addWorkspace(workspace);
}
else
{
// we are dealing with a partial or sub-service document
DSpaceObject dso = urlManager.extractDSpaceObject(url);
service.addWorkspace(workspace);
}
else
{
// we are dealing with a partial or sub-service document
DSpaceObject dso = urlManager.extractDSpaceObject(url);
if (dso == null)
{
throw new SwordError(404);
}
if (dso instanceof Community)
{
Community community = (Community) dso;
SwordWorkspace workspace = new SwordWorkspace();
workspace.setTitle(communityService.getName(community));
if (dso instanceof Community)
{
Community community = (Community) dso;
SwordWorkspace workspace = new SwordWorkspace();
workspace.setTitle(communityService.getName(community));
List<Collection> collections = swordAuth.getAllowedCollections(context, community);
for (Collection collection : collections)
{
SwordCollection scol = colGen.buildCollection(context.getContext(), collection, swordConfig);
workspace.addCollection(scol);
}
List<Collection> collections = swordAuth
.getAllowedCollections(context, community);
for (Collection collection : collections)
{
SwordCollection scol = colGen
.buildCollection(context.getContext(), collection,
swordConfig);
workspace.addCollection(scol);
}
List<Community> communities = swordAuth.getCommunities(context, community);
for (Community comm : communities)
{
SwordCollection scol = comGen.buildCollection(context.getContext(), comm, swordConfig);
workspace.addCollection(scol);
}
List<Community> communities = swordAuth
.getCommunities(context, community);
for (Community comm : communities)
{
SwordCollection scol = comGen
.buildCollection(context.getContext(), comm,
swordConfig);
workspace.addCollection(scol);
}
service.addWorkspace(workspace);
}
}
service.addWorkspace(workspace);
}
}
return service;
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -15,11 +15,15 @@ import org.swordapp.server.SwordServerException;
import java.util.Map;
public class SimpleDCEntryDisseminator extends AbstractSimpleDC implements SwordEntryDisseminator
public class SimpleDCEntryDisseminator extends AbstractSimpleDC
implements SwordEntryDisseminator
{
public SimpleDCEntryDisseminator() { }
public SimpleDCEntryDisseminator()
{
}
public DepositReceipt disseminate(Context context, Item item, DepositReceipt receipt)
public DepositReceipt disseminate(Context context, Item item,
DepositReceipt receipt)
throws DSpaceSwordException, SwordError, SwordServerException
{
SimpleDCMetadata md = this.getMetadata(item);
@@ -37,7 +41,7 @@ public class SimpleDCEntryDisseminator extends AbstractSimpleDC implements Sword
String value = atom.get(element);
if ("author".equals(element))
{
receipt.getWrappedEntry().addAuthor(value);
receipt.getWrappedEntry().addAuthor(value);
}
else if ("published".equals(element))
{

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -23,101 +23,126 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
public class SimpleDCEntryIngester extends AbstractSimpleDC implements SwordEntryIngester
public class SimpleDCEntryIngester extends AbstractSimpleDC
implements SwordEntryIngester
{
private static final Logger log = Logger.getLogger(SimpleDCEntryIngester.class);
private static final Logger log = Logger
.getLogger(SimpleDCEntryIngester.class);
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public SimpleDCEntryIngester()
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
public SimpleDCEntryIngester()
{
this.loadMetadataMaps();
}
public DepositResult ingest(Context context, Deposit deposit, DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingest(Context context, Deposit deposit,
DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
return this.ingest(context, deposit, dso, verboseDescription, null, false);
return this
.ingest(context, deposit, dso, verboseDescription, null, false);
}
public DepositResult ingest(Context context, Deposit deposit, DSpaceObject dso, VerboseDescription verboseDescription, DepositResult result, boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingest(Context context, Deposit deposit,
DSpaceObject dso, VerboseDescription verboseDescription,
DepositResult result, boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
if (dso instanceof Collection)
if (dso instanceof Collection)
{
return this.ingestToCollection(context, deposit, (Collection) dso, verboseDescription, result);
return this.ingestToCollection(context, deposit, (Collection) dso,
verboseDescription, result);
}
else if (dso instanceof Item)
else if (dso instanceof Item)
{
return this.ingestToItem(context, deposit, (Item) dso, verboseDescription, result, replace);
return this.ingestToItem(context, deposit, (Item) dso,
verboseDescription, result, replace);
}
return null;
}
return null;
}
public DepositResult ingestToItem(Context context, Deposit deposit, Item item, VerboseDescription verboseDescription, DepositResult result, boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingestToItem(Context context, Deposit deposit,
Item item, VerboseDescription verboseDescription,
DepositResult result, boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
// clean out any existing item metadata which is allowed to be replaced
// clean out any existing item metadata which is allowed to be replaced
if (replace)
{
this.removeMetadata(context, item);
}
// add the metadata to the item
this.addMetadataToItem(context, deposit, item);
// add the metadata to the item
this.addMetadataToItem(context, deposit, item);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Update successful");
verboseDescription.append("Update successful");
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setItem(item);
result.setTreatment(this.getTreatment());
return result;
}
catch (SQLException | AuthorizeException e)
{
throw new DSpaceSwordException(e);
}
}
return result;
}
catch (SQLException | AuthorizeException e)
{
throw new DSpaceSwordException(e);
}
}
private void removeMetadata(Context context, Item item)
throws DSpaceSwordException
{
String raw = ConfigurationManager.getProperty("swordv2-server", "metadata.replaceable");
String raw = ConfigurationManager
.getProperty("swordv2-server", "metadata.replaceable");
String[] parts = raw.split(",");
for (String part : parts)
{
MetadataValueInfo info = this.makeMetadataValueInfo(part.trim(), null);
try {
itemService.clearMetadata(context, item, info.schema, info.element, info.qualifier, Item.ANY);
} catch (SQLException e) {
log.error("Caught exception trying to remove metadata", e);
throw new DSpaceSwordException(e);
}
}
MetadataValueInfo info = this
.makeMetadataValueInfo(part.trim(), null);
try
{
itemService
.clearMetadata(context, item, info.schema, info.element,
info.qualifier, Item.ANY);
}
catch (SQLException e)
{
log.error("Caught exception trying to remove metadata", e);
throw new DSpaceSwordException(e);
}
}
}
private void addUniqueMetadata(Context context, MetadataValueInfo info, Item item) throws SQLException {
private void addUniqueMetadata(Context context, MetadataValueInfo info,
Item item) throws SQLException
{
String qual = info.qualifier;
if (info.qualifier == null)
{
@@ -129,7 +154,8 @@ public class SimpleDCEntryIngester extends AbstractSimpleDC implements SwordEntr
{
lang = Item.ANY;
}
List<MetadataValue> existing = itemService.getMetadata(item, info.schema, info.element, qual, lang);
List<MetadataValue> existing = itemService
.getMetadata(item, info.schema, info.element, qual, lang);
for (MetadataValue dcValue : existing)
{
// FIXME: probably we want to be slightly more careful about qualifiers and languages
@@ -142,78 +168,93 @@ public class SimpleDCEntryIngester extends AbstractSimpleDC implements SwordEntr
}
// if we get to here, go on and add the metadata
itemService.addMetadata(context, item, info.schema, info.element, info.qualifier, info.language, info.value);
itemService.addMetadata(context, item, info.schema, info.element,
info.qualifier, info.language, info.value);
}
private void addMetadataToItem(Context context, Deposit deposit, Item item)
throws DSpaceSwordException
{
// now, go through and get the metadata from the EntryPart and put it in DSpace
SwordEntry se = deposit.getSwordEntry();
private void addMetadataToItem(Context context, Deposit deposit, Item item)
throws DSpaceSwordException
{
// now, go through and get the metadata from the EntryPart and put it in DSpace
SwordEntry se = deposit.getSwordEntry();
// first do the standard atom terms (which may get overridden later)
String title = se.getTitle();
String summary = se.getSummary();
if (title != null)
{
String titleField = this.dcMap.get("title");
if (titleField != null)
{
MetadataValueInfo info = this.makeMetadataValueInfo(titleField, title);
try {
this.addUniqueMetadata(context, info, item);
} catch (SQLException e) {
log.error("Caught exception trying to add title", e);
throw new DSpaceSwordException(e);
}
}
}
if (summary != null)
{
String abstractField = this.dcMap.get("abstract");
if (abstractField != null)
{
MetadataValueInfo info = this.makeMetadataValueInfo(abstractField, summary);
try {
this.addUniqueMetadata(context, info, item);
} catch (SQLException e) {
log.error("Caught exception trying to set abstract", e);
throw new DSpaceSwordException(e);
}
}
}
// first do the standard atom terms (which may get overridden later)
String title = se.getTitle();
String summary = se.getSummary();
if (title != null)
{
String titleField = this.dcMap.get("title");
if (titleField != null)
{
MetadataValueInfo info = this
.makeMetadataValueInfo(titleField, title);
try
{
this.addUniqueMetadata(context, info, item);
}
catch (SQLException e)
{
log.error("Caught exception trying to add title", e);
throw new DSpaceSwordException(e);
}
}
}
if (summary != null)
{
String abstractField = this.dcMap.get("abstract");
if (abstractField != null)
{
MetadataValueInfo info = this
.makeMetadataValueInfo(abstractField, summary);
try
{
this.addUniqueMetadata(context, info, item);
}
catch (SQLException e)
{
log.error("Caught exception trying to set abstract", e);
throw new DSpaceSwordException(e);
}
}
}
Map<String, List<String>> dc = se.getDublinCore();
for (String term : dc.keySet())
{
String dsTerm = this.dcMap.get(term);
if (dsTerm == null)
{
// ignore anything we don't understand
continue;
}
Map<String, List<String>> dc = se.getDublinCore();
for (String term : dc.keySet())
{
String dsTerm = this.dcMap.get(term);
if (dsTerm == null)
{
// ignore anything we don't understand
continue;
}
// now add all the metadata terms
MetadataValueInfo info = this.makeMetadataValueInfo(dsTerm, null);
for (String value : dc.get(term))
{
// now add all the metadata terms
MetadataValueInfo info = this.makeMetadataValueInfo(dsTerm, null);
for (String value : dc.get(term))
{
info.value = value;
try {
this.addUniqueMetadata(context, info, item);
} catch (SQLException e) {
log.error("Caught exception trying to add metadata", e);
throw new DSpaceSwordException(e);
}
}
}
}
try
{
this.addUniqueMetadata(context, info, item);
}
catch (SQLException e)
{
log.error("Caught exception trying to add metadata", e);
throw new DSpaceSwordException(e);
}
}
}
}
public DepositResult ingestToCollection(Context context, Deposit deposit, Collection collection, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingestToCollection(Context context, Deposit deposit,
Collection collection, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
try
{
// decide whether we have a new item or an existing one
{
// decide whether we have a new item or an existing one
Item item = null;
WorkspaceItem wsi = null;
if (result != null)
@@ -232,46 +273,48 @@ public class SimpleDCEntryIngester extends AbstractSimpleDC implements SwordEntr
}
// add the metadata to the item
this.addMetadataToItem(context, deposit, item);
this.addMetadataToItem(context, deposit, item);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Ingest successful");
verboseDescription.append("Item created with internal identifier: " + item.getID());
verboseDescription.append("Ingest successful");
verboseDescription
.append("Item created with internal identifier: " +
item.getID());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setItem(item);
result.setTreatment(this.getTreatment());
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
public MetadataValueInfo makeMetadataValueInfo(String field, String value)
throws DSpaceSwordException
{
MetadataValueInfo dcv = new MetadataValueInfo();
MetadataValueInfo dcv = new MetadataValueInfo();
String[] bits = field.split("\\.");
if (bits.length < 2 || bits.length > 3)
{
@@ -288,93 +331,115 @@ public class SimpleDCEntryIngester extends AbstractSimpleDC implements SwordEntr
}
/**
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSwordException
*/
protected void setUpdatedDate(Context context, Item item, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
String field = ConfigurationManager.getProperty("swordv2-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException("No configuration, or configuration is invalid for: sword.updated.field");
}
* Add the current date to the item metadata. This looks up
* the field in which to store this metadata in the configuration
* sword.updated.field
*
*
* @param context
* @param item
* @throws DSpaceSwordException
*/
protected void setUpdatedDate(Context context, Item item,
VerboseDescription verboseDescription)
throws DSpaceSwordException
{
String field = ConfigurationManager
.getProperty("swordv2-server", "updated.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException(
"No configuration, or configuration is invalid for: sword.updated.field");
}
MetadataValueInfo info = this.makeMetadataValueInfo(field, null);
try {
itemService.clearMetadata(context, item, info.schema, info.element, info.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, info.schema, info.element, info.qualifier, null, date.toString());
} catch (SQLException e) {
log.error("Exception caught trying to set updated date", e);
throw new DSpaceSwordException(e);
}
MetadataValueInfo info = this.makeMetadataValueInfo(field, null);
try
{
itemService.clearMetadata(context, item, info.schema, info.element,
info.qualifier, Item.ANY);
DCDate date = new DCDate(new Date());
itemService.addMetadata(context, item, info.schema, info.element,
info.qualifier, null, date.toString());
}
catch (SQLException e)
{
log.error("Exception caught trying to set updated date", e);
throw new DSpaceSwordException(e);
}
verboseDescription.append("Updated date added to response from item metadata where available");
}
/**
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
*
* @param context
* @param item
* @param slugVal
* @throws DSpaceSwordException
*/
protected void setSlug(Context context, Item item, String slugVal, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
String field = ConfigurationManager.getProperty("swordv2-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException("No configuration, or configuration is invalid for: sword.slug.field");
}
MetadataValueInfo info = this.makeMetadataValueInfo(field, null);
try {
itemService.clearMetadata(context, item, info.schema, info.element, info.qualifier, Item.ANY);
itemService.addMetadata(context, item, info.schema, info.element, info.qualifier, null, slugVal);
} catch (SQLException e) {
log.error("Caught exception trying to set slug", e);
throw new DSpaceSwordException(e);
}
verboseDescription.append("Slug value set in response where available");
}
verboseDescription
.append("Updated date added to response from item metadata where available");
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "A metadata only item has been created";
}
* Store the given slug value (which is used for suggested identifiers,
* and which DSpace ignores) in the item metadata. This looks up the
* field in which to store this metadata in the configuration
* sword.slug.field
*
*
* @param context
* @param item
* @param slugVal
* @throws DSpaceSwordException
*/
protected void setSlug(Context context, Item item, String slugVal,
VerboseDescription verboseDescription)
throws DSpaceSwordException
{
// if there isn't a slug value, don't set it
if (slugVal == null)
{
return;
}
private class MetadataValueInfo {
private String schema;
private String element;
private String qualifier;
private String language;
private String value;
}
String field = ConfigurationManager
.getProperty("swordv2-server", "slug.field");
if (field == null || "".equals(field))
{
throw new DSpaceSwordException(
"No configuration, or configuration is invalid for: sword.slug.field");
}
MetadataValueInfo info = this.makeMetadataValueInfo(field, null);
try
{
itemService.clearMetadata(context, item, info.schema, info.element,
info.qualifier, Item.ANY);
itemService.addMetadata(context, item, info.schema, info.element,
info.qualifier, null, slugVal);
}
catch (SQLException e)
{
log.error("Caught exception trying to set slug", e);
throw new DSpaceSwordException(e);
}
verboseDescription.append("Slug value set in response where available");
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "A metadata only item has been created";
}
private class MetadataValueInfo
{
private String schema;
private String element;
private String qualifier;
private String language;
private String value;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
@@ -14,6 +14,7 @@ import java.util.Map;
public class SimpleDCMetadata
{
private Map<String, String> dublinCore = new HashMap<String, String>();
private Map<String, String> atom = new HashMap<String, String>();
public void addDublinCore(String element, String value)

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -35,7 +35,8 @@ import java.util.zip.ZipOutputStream;
public class SimpleZipContentDisseminator implements SwordContentDisseminator
{
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
public InputStream disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException
@@ -43,8 +44,11 @@ public class SimpleZipContentDisseminator implements SwordContentDisseminator
try
{
// first write everything to a temp file
String tempDir = ConfigurationManager.getProperty("upload.temp.dir");
String fn = tempDir + File.separator + "SWORD." + item.getID() + "." + UUID.randomUUID().toString() + ".zip";
String tempDir = ConfigurationManager
.getProperty("upload.temp.dir");
String fn =
tempDir + File.separator + "SWORD." + item.getID() + "." +
UUID.randomUUID().toString() + ".zip";
OutputStream outStream = new FileOutputStream(new File(fn));
ZipOutputStream zip = new ZipOutputStream(outStream);
@@ -54,11 +58,13 @@ public class SimpleZipContentDisseminator implements SwordContentDisseminator
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
List<BundleBitstream> bss = bundle.getBitstreams();
for (BundleBitstream bundleBitstream : bss) {
for (BundleBitstream bundleBitstream : bss)
{
Bitstream bitstream = bundleBitstream.getBitstream();
ZipEntry ze = new ZipEntry(bitstream.getName());
zip.putNextEntry(ze);
InputStream is = bitstreamService.retrieve(context, bitstream);
InputStream is = bitstreamService
.retrieve(context, bitstream);
Utils.copy(is, zip);
zip.closeEntry();
is.close();

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -36,19 +36,30 @@ import java.util.zip.ZipFile;
public class SimpleZipContentIngester extends AbstractSwordContentIngester
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public DepositResult ingestToCollection(Context context, Deposit deposit, Collection collection, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory
.getInstance().getBitstreamFormatService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
public DepositResult ingestToCollection(Context context, Deposit deposit,
Collection collection, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException
{
try
{
// get deposited file as file object
File depositFile = deposit.getFile();
File depositFile = deposit.getFile();
// decide whether we have a new item or an existing one
Item item = null;
@@ -71,172 +82,188 @@ public class SimpleZipContentIngester extends AbstractSwordContentIngester
// get the original bundle
List<Bundle> bundles = item.getBundles();
Bundle original = null;
for (Bundle bundle : bundles) {
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
if (original == null)
{
original = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME);
original = bundleService
.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
// unzip the file into the bundle
List<Bitstream> derivedResources = this.unzipToBundle(context, depositFile, original);
// unzip the file into the bundle
List<Bitstream> derivedResources = this
.unzipToBundle(context, depositFile, original);
// now we have an item in the workspace, and we need to consider adding some metadata to it,
// but since the zip file didn't contain anything, what do we do?
itemService.addMetadata(context, item, "dc", "title", null, null, "Untitled: " + deposit.getFilename());
itemService.addMetadata(context, item, "dc", "description", null, null, "Zip file deposted by SWORD without accompanying metadata");
// now we have an item in the workspace, and we need to consider adding some metadata to it,
// but since the zip file didn't contain anything, what do we do?
itemService.addMetadata(context, item, "dc", "title", null, null,
"Untitled: " + deposit.getFilename());
itemService
.addMetadata(context, item, "dc", "description", null, null,
"Zip file deposted by SWORD without accompanying metadata");
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, item, deposit.getSlug(), verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Ingest successful");
verboseDescription.append("Item created with internal identifier: " + item.getID());
verboseDescription.append("Ingest successful");
verboseDescription
.append("Item created with internal identifier: " +
item.getID());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setDerivedResources(derivedResources);
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
private List<Bitstream> unzipToBundle(Context context, File depositFile, Bundle target)
throws DSpaceSwordException, SwordError, SwordAuthException
{
try
{
// get the zip file into a usable form
ZipFile zip = new ZipFile(depositFile);
List<Bitstream> derivedResources = new ArrayList<Bitstream>();
Enumeration zenum = zip.entries();
while (zenum.hasMoreElements())
{
ZipEntry entry = (ZipEntry) zenum.nextElement();
InputStream stream = zip.getInputStream(entry);
Bitstream bs = bitstreamService.create(context, target, stream);
BitstreamFormat format = this.getFormat(context, entry.getName());
bs.setFormat(context, format);
bs.setName(context, entry.getName());
bitstreamService.update(context, bs);
derivedResources.add(bs);
}
return derivedResources;
}
catch (ZipException e)
{
throw new SwordError(UriRegistry.ERROR_BAD_REQUEST, "unable to unzip provided package", e);
}
catch (IOException | SQLException e)
{
throw new DSpaceSwordException(e);
} catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
}
public DepositResult ingestToItem(Context context, Deposit deposit, Item item, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException
private List<Bitstream> unzipToBundle(Context context, File depositFile,
Bundle target)
throws DSpaceSwordException, SwordError, SwordAuthException
{
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
// get the zip file into a usable form
ZipFile zip = new ZipFile(depositFile);
List<Bitstream> derivedResources = new ArrayList<Bitstream>();
Enumeration zenum = zip.entries();
while (zenum.hasMoreElements())
{
ZipEntry entry = (ZipEntry) zenum.nextElement();
InputStream stream = zip.getInputStream(entry);
Bitstream bs = bitstreamService.create(context, target, stream);
BitstreamFormat format = this
.getFormat(context, entry.getName());
bs.setFormat(context, format);
bs.setName(context, entry.getName());
bitstreamService.update(context, bs);
derivedResources.add(bs);
}
return derivedResources;
}
catch (ZipException e)
{
throw new SwordError(UriRegistry.ERROR_BAD_REQUEST,
"unable to unzip provided package", e);
}
catch (IOException | SQLException e)
{
throw new DSpaceSwordException(e);
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
}
public DepositResult ingestToItem(Context context, Deposit deposit,
Item item, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException
{
try
{
if (result == null)
{
result = new DepositResult();
}
result.setItem(item);
// get deposited file as file object
File depositFile = deposit.getFile();
File depositFile = deposit.getFile();
// get the original bundle
List<Bundle> bundles = item.getBundles();
Bundle original = null;
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
for (Bundle bundle : bundles)
{
if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName()))
{
original = bundle;
break;
}
}
if (original == null)
{
original = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME);
original = bundleService
.create(context, item, Constants.CONTENT_BUNDLE_NAME);
}
// we are now free to go and unpack the new zip into the original bundle
List<Bitstream> derivedResources = this.unzipToBundle(context, depositFile, original);
// we are now free to go and unpack the new zip into the original bundle
List<Bitstream> derivedResources = this
.unzipToBundle(context, depositFile, original);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, item, verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, item);
context.restoreAuthSystemState();
verboseDescription.append("Replace successful");
verboseDescription.append("Replace successful");
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setItem(item);
result.setTreatment(this.getTreatment());
result.setDerivedResources(derivedResources);
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
return result;
}
catch (AuthorizeException e)
{
throw new SwordAuthException(e);
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been ingested and unpacked into the item. Template metadata for " +
"the collection has been used, and a default title with the name of the file has " +
"been set";
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been ingested and unpacked into the item. Template metadata for " +
"the collection has been used, and a default title with the name of the file has " +
"been set";
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -31,17 +31,20 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class StatementManagerDSpace extends DSpaceSwordAPI implements StatementManager
public class StatementManagerDSpace extends DSpaceSwordAPI
implements StatementManager
{
private static Logger log = Logger.getLogger(StatementManagerDSpace.class);
private static Logger log = Logger.getLogger(StatementManagerDSpace.class);
protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService();
protected AuthorizeService authorizeService = AuthorizeServiceFactory
.getInstance().getAuthorizeService();
public Statement getStatement(String stateIRI, Map<String, String> accept, AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordServerException, SwordError, SwordAuthException
{
public Statement getStatement(String stateIRI, Map<String, String> accept,
AuthCredentials authCredentials, SwordConfiguration swordConfig)
throws SwordServerException, SwordError, SwordAuthException
{
SwordContext sc = null;
try
try
{
SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig;
@@ -51,13 +54,19 @@ public class StatementManagerDSpace extends DSpaceSwordAPI implements StatementM
if (log.isDebugEnabled())
{
log.debug(LogManager.getHeader(context, "sword_get_statement", ""));
log.debug(LogManager
.getHeader(context, "sword_get_statement", ""));
}
// log the request
String un = authCredentials.getUsername() != null ? authCredentials.getUsername() : "NONE";
String obo = authCredentials.getOnBehalfOf() != null ? authCredentials.getOnBehalfOf() : "NONE";
log.info(LogManager.getHeader(context, "sword_get_statement", "username=" + un + ",on_behalf_of=" + obo));
String un = authCredentials.getUsername() != null ?
authCredentials.getUsername() :
"NONE";
String obo = authCredentials.getOnBehalfOf() != null ?
authCredentials.getOnBehalfOf() :
"NONE";
log.info(LogManager.getHeader(context, "sword_get_statement",
"username=" + un + ",on_behalf_of=" + obo));
// first thing is to figure out what we're being asked to work on
SwordUrlManager urlManager = config.getUrlManager(context, config);
@@ -70,31 +79,36 @@ public class StatementManagerDSpace extends DSpaceSwordAPI implements StatementM
// find out if we are allowed to read the item's statement
authorizeService.authorizeAction(context, item, Constants.READ);
// find out, now we know what we're being asked for, whether this is allowed
WorkflowManagerFactory.getInstance().retrieveStatement(context, item);
// find out, now we know what we're being asked for, whether this is allowed
WorkflowManagerFactory.getInstance()
.retrieveStatement(context, item);
String suffix = urlManager.getTypeSuffix(context, stateIRI);
SwordStatementDisseminator disseminator = null;
String suffix = urlManager.getTypeSuffix(context, stateIRI);
SwordStatementDisseminator disseminator = null;
if (suffix != null)
{
if (suffix != null)
{
Map<Float, List<String>> analysed = new HashMap<>();
List<String> list = new ArrayList<>();
list.add(suffix);
analysed.put((float) 1.0, list);
disseminator = SwordDisseminatorFactory.getStatementInstance(analysed);
}
else
{
// we rely on the content negotiation to do the work
String acceptContentType = this.getHeader(accept, "Accept", null);
disseminator = SwordDisseminatorFactory
.getStatementInstance(analysed);
}
else
{
// we rely on the content negotiation to do the work
String acceptContentType = this
.getHeader(accept, "Accept", null);
// we extract from the Accept header the ordered list of content types
TreeMap<Float, List<String>> analysed = this.analyseAccept(acceptContentType);
TreeMap<Float, List<String>> analysed = this
.analyseAccept(acceptContentType);
// the meat of this is done by the package disseminator
disseminator = SwordDisseminatorFactory.getStatementInstance(analysed);
}
disseminator = SwordDisseminatorFactory
.getStatementInstance(analysed);
}
return disseminator.disseminate(context, item);
}
@@ -105,12 +119,13 @@ public class StatementManagerDSpace extends DSpaceSwordAPI implements StatementM
catch (SQLException | DSpaceSwordException e)
{
throw new SwordServerException(e);
} finally
}
finally
{
if (sc != null)
{
sc.abort();
}
}
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -17,13 +17,13 @@ import java.io.InputStream;
public interface SwordContentDisseminator
{
public InputStream disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException;
throws DSpaceSwordException, SwordError, SwordServerException;
public boolean disseminatesContentType(String contentType)
throws DSpaceSwordException, SwordError, SwordServerException;
throws DSpaceSwordException, SwordError, SwordServerException;
public boolean disseminatesPackage(String contentType)
throws DSpaceSwordException, SwordError, SwordServerException;
throws DSpaceSwordException, SwordError, SwordServerException;
public void setContentType(String contentType);

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -24,17 +24,21 @@ import org.swordapp.server.SwordServerException;
*/
public interface SwordContentIngester
{
/**
* Ingest the package as described in the given Deposit object
* within the given DSpace Context
*
* @param deposit
* @return the result of the deposit
* @throws DSpaceSwordException
*/
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
/**
* Ingest the package as described in the given Deposit object
* within the given DSpace Context
*
* @param deposit
* @return the result of the deposit
* @throws DSpaceSwordException
*/
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target,
VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target,
VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -37,151 +37,151 @@ import org.dspace.eperson.EPerson;
*/
public class SwordContext
{
/** The primary authenticated user for the request */
private EPerson authenticated = null;
/** The primary authenticated user for the request */
private EPerson authenticated = null;
/** The onBehalfOf user for the request */
private EPerson onBehalfOf = null;
/** The onBehalfOf user for the request */
private EPerson onBehalfOf = null;
/** The primary context, representing the on behalf of user if exists, and the authenticated user if not */
private Context context;
/** The primary context, representing the on behalf of user if exists, and the authenticated user if not */
private Context context;
/** the context for the authenticated user, which may not, therefore, be the primary context also */
private Context authenticatorContext;
/** the context for the authenticated user, which may not, therefore, be the primary context also */
private Context authenticatorContext;
/**
* @return the authenticated user
*/
public EPerson getAuthenticated()
{
return authenticated;
}
/**
* @return the authenticated user
*/
public EPerson getAuthenticated()
{
return authenticated;
}
/**
* @param authenticated the eperson to set
*/
public void setAuthenticated(EPerson authenticated)
{
this.authenticated = authenticated;
}
/**
* @param authenticated the eperson to set
*/
public void setAuthenticated(EPerson authenticated)
{
this.authenticated = authenticated;
}
/**
* @return the onBehalfOf user
*/
public EPerson getOnBehalfOf()
{
return onBehalfOf;
}
/**
* @return the onBehalfOf user
*/
public EPerson getOnBehalfOf()
{
return onBehalfOf;
}
/**
* @param onBehalfOf the eperson to set
*/
public void setOnBehalfOf(EPerson onBehalfOf)
{
this.onBehalfOf = onBehalfOf;
}
/**
* @param onBehalfOf the eperson to set
*/
public void setOnBehalfOf(EPerson onBehalfOf)
{
this.onBehalfOf = onBehalfOf;
}
/**
* Returns the most appropriate context for operations on the
* database. This is the on-behalf-of user's context if the
* user exists, or the authenticated user's context otherwise.
*/
public Context getContext()
{
return context;
}
/**
* Returns the most appropriate context for operations on the
* database. This is the on-behalf-of user's context if the
* user exists, or the authenticated user's context otherwise.
*/
public Context getContext()
{
return context;
}
public void setContext(Context context)
{
this.context = context;
}
public void setContext(Context context)
{
this.context = context;
}
/**
* Get the context of the user who authenticated. This should only be
* used for authentication purposes. If there is an on-behalf-of user,
* that context should be used to write database changes. Use:
*
* getContext()
*
* on this class instead.
*/
public Context getAuthenticatorContext()
{
return authenticatorContext;
}
/**
* Get the context of the user who authenticated. This should only be
* used for authentication purposes. If there is an on-behalf-of user,
* that context should be used to write database changes. Use:
*
* getContext()
*
* on this class instead.
*/
public Context getAuthenticatorContext()
{
return authenticatorContext;
}
public void setAuthenticatorContext(Context authenticatorContext)
{
this.authenticatorContext = authenticatorContext;
}
public void setAuthenticatorContext(Context authenticatorContext)
{
this.authenticatorContext = authenticatorContext;
}
/**
* Get the context of the on-behalf-of user. This method should only
* be used for authentication purposes. In all other cases, use:
*
* getContext()
*
* on this class instead. If there is no on-behalf-of user, this
* method will return null.
*/
public Context getOnBehalfOfContext()
{
// return the obo context if this is an obo deposit, else return null
if (this.onBehalfOf != null)
{
return context;
}
return null;
}
/**
* Get the context of the on-behalf-of user. This method should only
* be used for authentication purposes. In all other cases, use:
*
* getContext()
*
* on this class instead. If there is no on-behalf-of user, this
* method will return null.
*/
public Context getOnBehalfOfContext()
{
// return the obo context if this is an obo deposit, else return null
if (this.onBehalfOf != null)
{
return context;
}
return null;
}
/**
* Abort all of the contexts held by this class. No changes will
* be written to the database
*/
public void abort()
{
// abort both contexts
if (context != null && context.isValid())
{
context.abort();
}
/**
* Abort all of the contexts held by this class. No changes will
* be written to the database
*/
public void abort()
{
// abort both contexts
if (context != null && context.isValid())
{
context.abort();
}
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
/**
* Commit the primary context held by this class, and abort the authenticated
* user's context if it is different. This ensures that only changes written
* through the appropriate user's context is persisted, and all other
* operations are flushed. You should, in general, not try to commit the contexts directly
* when using the sword api.
*
* @throws DSpaceSwordException
*/
public void commit()
throws DSpaceSwordException
{
try
{
// commit the primary context
if (context != null && context.isValid())
{
context.complete();
}
/**
* Commit the primary context held by this class, and abort the authenticated
* user's context if it is different. This ensures that only changes written
* through the appropriate user's context is persisted, and all other
* operations are flushed. You should, in general, not try to commit the contexts directly
* when using the sword api.
*
* @throws DSpaceSwordException
*/
public void commit()
throws DSpaceSwordException
{
try
{
// commit the primary context
if (context != null && context.isValid())
{
context.complete();
}
// the secondary context is for filtering permissions by only, and is
// never committed, so we abort here
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
// the secondary context is for filtering permissions by only, and is
// never committed, so we abort here
if (authenticatorContext != null && authenticatorContext.isValid())
{
authenticatorContext.abort();
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -17,7 +17,8 @@ import java.util.Map;
public class SwordDisseminatorFactory
{
public static SwordContentDisseminator getContentInstance(Map<Float, List<String>> accept, String acceptPackaging)
public static SwordContentDisseminator getContentInstance(
Map<Float, List<String>> accept, String acceptPackaging)
throws DSpaceSwordException, SwordError
{
try
@@ -31,9 +32,13 @@ public class SwordDisseminatorFactory
{
for (String format : accept.get(q))
{
format = format.replace(";", "_"); // clean up the string for the plugin manager
format = format.replace("=", "_"); // clean up the string for the plugin manager
disseminator = (SwordContentDisseminator) PluginManager.getNamedPlugin("swordv2-server", SwordContentDisseminator.class, format);
format = format.replace(";",
"_"); // clean up the string for the plugin manager
format = format.replace("=",
"_"); // clean up the string for the plugin manager
disseminator = (SwordContentDisseminator) PluginManager
.getNamedPlugin("swordv2-server",
SwordContentDisseminator.class, format);
if (disseminator == null)
{
continue;
@@ -42,7 +47,8 @@ public class SwordDisseminatorFactory
{
// if we find a disseminator which says it does this format, then find out if it
// will do the packaging
if (!disseminator.disseminatesPackage(acceptPackaging))
if (!disseminator
.disseminatesPackage(acceptPackaging))
{
disseminator = null;
continue;
@@ -62,9 +68,14 @@ public class SwordDisseminatorFactory
{
if (acceptPackaging != null)
{
acceptPackaging = acceptPackaging.replace(";", "_"); // clean up the string for the plugin manager
acceptPackaging = acceptPackaging.replace("=", "_"); // clean up the string for the plugin manager
disseminator = (SwordContentDisseminator) PluginManager.getNamedPlugin("swordv2-server", SwordContentDisseminator.class, acceptPackaging);
acceptPackaging = acceptPackaging.replace(";",
"_"); // clean up the string for the plugin manager
acceptPackaging = acceptPackaging.replace("=",
"_"); // clean up the string for the plugin manager
disseminator = (SwordContentDisseminator) PluginManager
.getNamedPlugin("swordv2-server",
SwordContentDisseminator.class,
acceptPackaging);
if (disseminator != null)
{
if (accept != null)
@@ -73,7 +84,8 @@ public class SwordDisseminatorFactory
{
for (String format : accept.get(q))
{
if (!disseminator.disseminatesContentType(format))
if (!disseminator
.disseminatesContentType(format))
{
disseminator = null;
}
@@ -90,7 +102,8 @@ public class SwordDisseminatorFactory
if (disseminator == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT, 406, "No plugin can disseminate the requested formats");
throw new SwordError(UriRegistry.ERROR_CONTENT, 406,
"No plugin can disseminate the requested formats");
}
disseminator.setPackaging(acceptPackaging);
@@ -102,45 +115,54 @@ public class SwordDisseminatorFactory
}
}
public static SwordStatementDisseminator getStatementInstance(Map<Float, List<String>> accept)
public static SwordStatementDisseminator getStatementInstance(
Map<Float, List<String>> accept)
throws DSpaceSwordException, SwordError
{
SwordStatementDisseminator disseminator = null;
SwordStatementDisseminator disseminator = null;
// first try to load disseminators based on content type
if (accept != null)
{
for (Float q : accept.keySet())
{
for (String format : accept.get(q))
{
format = format.replace(";", "_"); // clean up the string for the plugin manager
format = format.replace("=", "_"); // clean up the string for the plugin manager
disseminator = (SwordStatementDisseminator) PluginManager.getNamedPlugin("swordv2-server", SwordStatementDisseminator.class, format);
if (disseminator != null)
{
break;
}
}
}
}
// first try to load disseminators based on content type
if (accept != null)
{
for (Float q : accept.keySet())
{
for (String format : accept.get(q))
{
format = format.replace(";",
"_"); // clean up the string for the plugin manager
format = format.replace("=",
"_"); // clean up the string for the plugin manager
disseminator = (SwordStatementDisseminator) PluginManager
.getNamedPlugin("swordv2-server",
SwordStatementDisseminator.class, format);
if (disseminator != null)
{
break;
}
}
}
}
if (disseminator == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT, 406, "No plugin can disseminate the requested formats");
}
if (disseminator == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT, 406,
"No plugin can disseminate the requested formats");
}
return disseminator;
}
return disseminator;
}
public static SwordEntryDisseminator getEntryInstance()
throws DSpaceSwordException, SwordError
{
SwordEntryDisseminator disseminator = (SwordEntryDisseminator) PluginManager.getSinglePlugin("swordv2-server", SwordEntryDisseminator.class);
SwordEntryDisseminator disseminator = (SwordEntryDisseminator) PluginManager
.getSinglePlugin("swordv2-server",
SwordEntryDisseminator.class);
if (disseminator == null)
{
throw new SwordError(DSpaceUriRegistry.REPOSITORY_ERROR, "No disseminator configured for handling sword entry documents");
throw new SwordError(DSpaceUriRegistry.REPOSITORY_ERROR,
"No disseminator configured for handling sword entry documents");
}
return disseminator;
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -15,6 +15,7 @@ import org.swordapp.server.SwordServerException;
public interface SwordEntryDisseminator
{
public DepositReceipt disseminate(Context context, Item item, DepositReceipt receipt)
throws DSpaceSwordException, SwordError, SwordServerException;
public DepositReceipt disseminate(Context context, Item item,
DepositReceipt receipt)
throws DSpaceSwordException, SwordError, SwordServerException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -16,9 +16,14 @@ import org.swordapp.server.SwordServerException;
public interface SwordEntryIngester
{
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target,
VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target, VerboseDescription verboseDescription, DepositResult result, boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException;
DepositResult ingest(Context context, Deposit deposit, DSpaceObject target,
VerboseDescription verboseDescription, DepositResult result,
boolean replace)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -15,7 +15,6 @@ import org.swordapp.server.Deposit;
import org.swordapp.server.SwordError;
import org.swordapp.server.UriRegistry;
/**
* Factory class which will mint objects conforming to the
* SWORDIngester interface.
@@ -25,27 +24,30 @@ import org.swordapp.server.UriRegistry;
*/
public class SwordIngesterFactory
{
/**
* Generate an object which conforms to the SWORDIngester interface.
* This Factory method may use the given DSpace context and the given
* SWORD Deposit request to decide on the most appropriate implementation
* of the interface to return.
*
* To configure how this method will respond, configure the package ingester
* for the appropriate media types and defaults. See the SWORD configuration
* documentation for more details.
*
* @param context
* @param deposit
* @throws DSpaceSwordException
*/
public static SwordContentIngester getContentInstance(Context context, Deposit deposit, DSpaceObject dso)
/**
* Generate an object which conforms to the SWORDIngester interface.
* This Factory method may use the given DSpace context and the given
* SWORD Deposit request to decide on the most appropriate implementation
* of the interface to return.
*
* To configure how this method will respond, configure the package ingester
* for the appropriate media types and defaults. See the SWORD configuration
* documentation for more details.
*
* @param context
* @param deposit
* @throws DSpaceSwordException
*/
public static SwordContentIngester getContentInstance(Context context,
Deposit deposit, DSpaceObject dso)
throws DSpaceSwordException, SwordError
{
SwordContentIngester ingester = null;
// first look to see if there's an intester for the content type
ingester = (SwordContentIngester) PluginManager.getNamedPlugin("swordv2-server", SwordContentIngester.class, deposit.getMimeType());
ingester = (SwordContentIngester) PluginManager
.getNamedPlugin("swordv2-server", SwordContentIngester.class,
deposit.getMimeType());
if (ingester != null)
{
return ingester;
@@ -53,22 +55,28 @@ public class SwordIngesterFactory
// if no ingester, then
// look to see if there's an ingester for the package format
ingester = (SwordContentIngester) PluginManager.getNamedPlugin("swordv2-server", SwordContentIngester.class, deposit.getPackaging());
ingester = (SwordContentIngester) PluginManager
.getNamedPlugin("swordv2-server", SwordContentIngester.class,
deposit.getPackaging());
if (ingester == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT, "No ingester configured for this package type");
throw new SwordError(UriRegistry.ERROR_CONTENT,
"No ingester configured for this package type");
}
return ingester;
}
}
public static SwordEntryIngester getEntryInstance(Context context, Deposit deposit, DSpaceObject dso)
public static SwordEntryIngester getEntryInstance(Context context,
Deposit deposit, DSpaceObject dso)
throws DSpaceSwordException, SwordError
{
SwordEntryIngester ingester = (SwordEntryIngester) PluginManager.getSinglePlugin("swordv2-server", SwordEntryIngester.class);
if (ingester == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT, "No ingester configured for handling sword entry documents");
}
return ingester;
}
SwordEntryIngester ingester = (SwordEntryIngester) PluginManager
.getSinglePlugin("swordv2-server", SwordEntryIngester.class);
if (ingester == null)
{
throw new SwordError(UriRegistry.ERROR_CONTENT,
"No ingester configured for handling sword entry documents");
}
return ingester;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -36,32 +36,46 @@ import org.swordapp.server.SwordServerException;
public class SwordMETSContentIngester extends AbstractSwordContentIngester
{
/** Log4j logger */
public static final Logger log = Logger.getLogger(SwordMETSContentIngester.class);
/** Log4j logger */
public static final Logger log = Logger
.getLogger(SwordMETSContentIngester.class);
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
public DepositResult ingest(Context context, Deposit deposit, DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
protected CollectionService collectionService = ContentServiceFactory
.getInstance().getCollectionService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
protected HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
public DepositResult ingest(Context context, Deposit deposit,
DSpaceObject dso, VerboseDescription verboseDescription)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
return this.ingest(context, deposit, dso, verboseDescription, null);
}
@Override
public DepositResult ingestToCollection(Context context, Deposit deposit, Collection collection, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingestToCollection(Context context, Deposit deposit,
Collection collection, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
try
{
{
// if we are actuall given an item in the deposit result of a previous operation
// then we do an ingestToItem
if (result != null)
{
Item item = result.getItem();
return this.ingestToItem(context, deposit, item, verboseDescription, result);
return this.ingestToItem(context, deposit, item,
verboseDescription, result);
}
// otherwise, go on and do a create ...
@@ -71,104 +85,124 @@ public class SwordMETSContentIngester extends AbstractSwordContentIngester
// us finer control over the workflow state of the item, whereas asking
// the ingester to /create/ this item causes it to be injected into the workflow,
// irrespective of the In-Progress header provided by the depositor
WorkspaceItem wsi = workspaceItemService.create(context, collection, true);
WorkspaceItem wsi = workspaceItemService
.create(context, collection, true);
Item item = wsi.getItem();
// need to add a licence file, otherwise the METS replace function raises a NullPointerException
String licence = collectionService.getLicense(collection);
if (PackageUtils.findDepositLicense(context, item) == null)
{
PackageUtils.addDepositLicense(context, licence, item, collection);
PackageUtils
.addDepositLicense(context, licence, item, collection);
}
// get deposited file as InputStream
File depositFile = deposit.getFile();
// get deposited file as InputStream
File depositFile = deposit.getFile();
// load the plugin manager for the required configuration
String cfg = ConfigurationManager.getProperty("sword-server", "mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
verboseDescription.append("Using package manifest format: " + cfg);
// load the plugin manager for the required configuration
String cfg = ConfigurationManager.getProperty("sword-server",
"mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
verboseDescription.append("Using package manifest format: " + cfg);
PackageIngester pi = (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, cfg);
verboseDescription.append("Loaded package ingester: " + pi.getClass().getName());
PackageIngester pi = (PackageIngester) PluginManager
.getNamedPlugin(PackageIngester.class, cfg);
verboseDescription.append("Loaded package ingester: " +
pi.getClass().getName());
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// Force package ingester to respect Collection workflows
params.setWorkflowEnabled(true);
// Should restore mode be enabled, i.e. keep existing handle?
if (ConfigurationManager.getBooleanProperty("sword-server", "restore-mode.enable",false))
if (ConfigurationManager
.getBooleanProperty("sword-server", "restore-mode.enable",
false))
{
params.setRestoreModeEnabled(true);
}
// Whether or not to use the collection template
params.setUseCollectionTemplate(ConfigurationManager.getBooleanProperty("mets.default.ingest.useCollectionTemplate", false));
params.setUseCollectionTemplate(ConfigurationManager
.getBooleanProperty(
"mets.default.ingest.useCollectionTemplate",
false));
// ingest the item from the temp file
DSpaceObject ingestedObject = pi.replace(context, item, depositFile, params);
if (ingestedObject == null)
{
verboseDescription.append("Failed to ingest the package; throwing exception");
throw new SwordError(DSpaceUriRegistry.UNPACKAGE_FAIL, "METS package ingester failed to unpack package");
}
// ingest the item from the temp file
DSpaceObject ingestedObject = pi
.replace(context, item, depositFile, params);
if (ingestedObject == null)
{
verboseDescription
.append("Failed to ingest the package; throwing exception");
throw new SwordError(DSpaceUriRegistry.UNPACKAGE_FAIL,
"METS package ingester failed to unpack package");
}
// Verify we have an Item as a result
if (!(ingestedObject instanceof Item))
{
throw new DSpaceSwordException("DSpace Ingester returned wrong object type -- not an Item result.");
}
{
throw new DSpaceSwordException(
"DSpace Ingester returned wrong object type -- not an Item result.");
}
else
{
//otherwise, we have an item, and a workflow should have already been started for it.
verboseDescription.append("Workflow process started");
}
// get reference to item so that we can report on it
Item installedItem = (Item) ingestedObject;
// get reference to item so that we can report on it
Item installedItem = (Item) ingestedObject;
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem, verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, installedItem, deposit.getSlug(), verboseDescription);
// DSpace ignores the slug value as suggested identifier, but
// it does store it in the metadata
this.setSlug(context, installedItem, deposit.getSlug(),
verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
String handle = handleService.findHandle(context, installedItem);
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
String handle = handleService.findHandle(context, installedItem);
verboseDescription.append("Ingest successful");
verboseDescription.append("Item created with internal identifier: " + installedItem.getID());
if (handle != null)
{
verboseDescription.append("Item created with external identifier: " + handle);
}
else
{
verboseDescription.append("No external identifier available at this stage (item in workflow)");
}
verboseDescription.append("Ingest successful");
verboseDescription
.append("Item created with internal identifier: " +
installedItem.getID());
if (handle != null)
{
verboseDescription
.append("Item created with external identifier: " +
handle);
}
else
{
verboseDescription
.append("No external identifier available at this stage (item in workflow)");
}
DepositResult dr = new DepositResult();
dr.setItem(installedItem);
dr.setTreatment(this.getTreatment());
DepositResult dr = new DepositResult();
dr.setItem(installedItem);
dr.setTreatment(this.getTreatment());
return dr;
}
return dr;
}
catch (RuntimeException re)
{
log.error("caught exception: ", re);
@@ -182,8 +216,11 @@ public class SwordMETSContentIngester extends AbstractSwordContentIngester
}
@Override
public DepositResult ingestToItem(Context context, Deposit deposit, Item item, VerboseDescription verboseDescription, DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException
public DepositResult ingestToItem(Context context, Deposit deposit,
Item item, VerboseDescription verboseDescription,
DepositResult result)
throws DSpaceSwordException, SwordError, SwordAuthException,
SwordServerException
{
if (result == null)
{
@@ -191,76 +228,88 @@ public class SwordMETSContentIngester extends AbstractSwordContentIngester
}
try
{
{
// get deposited file as InputStream
File depositFile = deposit.getFile();
// load the plugin manager for the required configuration
String cfg = ConfigurationManager.getProperty("sword-server", "mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
verboseDescription.append("Using package manifest format: " + cfg);
String cfg = ConfigurationManager.getProperty("sword-server",
"mets-ingester.package-ingester");
if (cfg == null || "".equals(cfg))
{
cfg = "METS"; // default to METS
}
verboseDescription.append("Using package manifest format: " + cfg);
PackageIngester pi = (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, cfg);
verboseDescription.append("Loaded package ingester: " + pi.getClass().getName());
PackageIngester pi = (PackageIngester) PluginManager
.getNamedPlugin(PackageIngester.class, cfg);
verboseDescription.append("Loaded package ingester: " +
pi.getClass().getName());
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// Initialize parameters to packager
PackageParameters params = new PackageParameters();
// Force package ingester to respect Collection workflows
params.setWorkflowEnabled(true);
// Should restore mode be enabled, i.e. keep existing handle?
if (ConfigurationManager.getBooleanProperty("sword-server", "restore-mode.enable",false))
if (ConfigurationManager
.getBooleanProperty("sword-server", "restore-mode.enable",
false))
{
params.setRestoreModeEnabled(true);
}
// Whether or not to use the collection template
params.setUseCollectionTemplate(ConfigurationManager.getBooleanProperty("mets.default.ingest.useCollectionTemplate", false));
params.setUseCollectionTemplate(ConfigurationManager
.getBooleanProperty(
"mets.default.ingest.useCollectionTemplate",
false));
// ingest the item from the temp file
DSpaceObject ingestedObject = pi.replace(context, item, depositFile, params);
if (ingestedObject == null)
{
verboseDescription.append("Failed to replace the package; throwing exception");
throw new SwordError(DSpaceUriRegistry.UNPACKAGE_FAIL, "METS package ingester failed to unpack package");
}
// ingest the item from the temp file
DSpaceObject ingestedObject = pi
.replace(context, item, depositFile, params);
if (ingestedObject == null)
{
verboseDescription
.append("Failed to replace the package; throwing exception");
throw new SwordError(DSpaceUriRegistry.UNPACKAGE_FAIL,
"METS package ingester failed to unpack package");
}
// Verify we have an Item as a result
if (!(ingestedObject instanceof Item))
{
throw new DSpaceSwordException("DSpace Ingester returned wrong object type -- not an Item result.");
}
{
throw new DSpaceSwordException(
"DSpace Ingester returned wrong object type -- not an Item result.");
}
// get reference to item so that we can report on it
Item installedItem = (Item) ingestedObject;
// get reference to item so that we can report on it
Item installedItem = (Item) ingestedObject;
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem, verboseDescription);
// update the item metadata to inclue the current time as
// the updated date
this.setUpdatedDate(context, installedItem, verboseDescription);
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// in order to write these changes, we need to bypass the
// authorisation briefly, because although the user may be
// able to add stuff to the repository, they may not have
// WRITE permissions on the archive.
context.turnOffAuthorisationSystem();
itemService.update(context, installedItem);
context.restoreAuthSystemState();
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
String handle = handleService.findHandle(context, installedItem);
// for some reason, DSpace will not give you the handle automatically,
// so we have to look it up
String handle = handleService.findHandle(context, installedItem);
verboseDescription.append("Replace successful");
verboseDescription.append("Replace successful");
result.setItem(installedItem);
result.setTreatment(this.getTreatment());
result.setItem(installedItem);
result.setTreatment(this.getTreatment());
return result;
}
return result;
}
catch (RuntimeException re)
{
log.error("caught exception: ", re);
@@ -274,17 +323,17 @@ public class SwordMETSContentIngester extends AbstractSwordContentIngester
}
/**
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been deposited into DSpace. Each file has been unpacked " +
"and provided with a unique identifier. The metadata in the manifest has been " +
"extracted and attached to the DSpace item, which has been provided with " +
"an identifier leading to an HTML splash page.";
}
* The human readable description of the treatment this ingester has
* put the deposit through
*
* @return
* @throws DSpaceSwordException
*/
private String getTreatment() throws DSpaceSwordException
{
return "The package has been deposited into DSpace. Each file has been unpacked " +
"and provided with a unique identifier. The metadata in the manifest has been " +
"extracted and attached to the DSpace item, which has been provided with " +
"an identifier leading to an HTML splash page.";
}
}

View File

@@ -2,12 +2,11 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Item;
@@ -35,11 +34,12 @@ public class SwordMETSPackageIngester extends DSpaceMETSIngester
*/
@Override
public void addLicense(Context context, Item item, String license,
Collection collection, PackageParameters params)
throws PackageValidationException,
Collection collection, PackageParameters params)
throws PackageValidationException,
AuthorizeException, SQLException, IOException
{
if (PackageUtils.findDepositLicense(context, item) == null && license != null)
if (PackageUtils.findDepositLicense(context, item) == null &&
license != null)
{
PackageUtils.addDepositLicense(context, license, item, collection);
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -15,6 +15,6 @@ import org.swordapp.server.SwordServerException;
public interface SwordStatementDisseminator
{
public Statement disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException;
public Statement disseminate(Context context, Item item)
throws DSpaceSwordException, SwordError, SwordServerException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -32,109 +32,119 @@ import java.util.List;
*/
public class SwordUrlManager
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
/** the sword configuration */
private SwordConfigurationDSpace config;
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
/** the active dspace context */
private Context context;
protected HandleService handleService = HandleServiceFactory.getInstance()
.getHandleService();
public SwordUrlManager(SwordConfigurationDSpace config, Context context)
{
this.config = config;
this.context = context;
}
/** the sword configuration */
private SwordConfigurationDSpace config;
/**
* Obtain the deposit URL for the given collection. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param collection
* @return The Deposit URL
* @throws DSpaceSwordException
*/
public String getDepositLocation(Collection collection)
throws DSpaceSwordException
{
return this.getBaseCollectionUrl() + "/" + collection.getHandle();
}
/** the active dspace context */
private Context context;
/**
* Obtain the deposit URL for the given community. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param community
* @return The Deposit URL
* @throws DSpaceSwordException
*/
public String getDepositLocation(Community community)
throws DSpaceSwordException
{
if (this.config.allowCommunityDeposit())
{
return this.getBaseCollectionUrl() + "/" + community.getHandle();
}
return null;
}
public SwordUrlManager(SwordConfigurationDSpace config, Context context)
{
this.config = config;
this.context = context;
}
public String getSwordBaseUrl()
throws DSpaceSwordException
{
String sUrl = ConfigurationManager.getProperty("swordv2-server", "url");
if (sUrl == null || "".equals(sUrl))
{
String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException("Unable to construct service document urls, due to missing/invalid " +
"config in sword2.url and/or dspace.baseUrl");
}
/**
* Obtain the deposit URL for the given collection. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param collection
* @return The Deposit URL
* @throws DSpaceSwordException
*/
public String getDepositLocation(Collection collection)
throws DSpaceSwordException
{
return this.getBaseCollectionUrl() + "/" + collection.getHandle();
}
/**
* Obtain the deposit URL for the given community. These URLs
* should not be considered persistent, but will remain consistent
* unless configuration changes are made to DSpace
*
* @param community
* @return The Deposit URL
* @throws DSpaceSwordException
*/
public String getDepositLocation(Community community)
throws DSpaceSwordException
{
if (this.config.allowCommunityDeposit())
{
return this.getBaseCollectionUrl() + "/" + community.getHandle();
}
return null;
}
public String getSwordBaseUrl()
throws DSpaceSwordException
{
String sUrl = ConfigurationManager.getProperty("swordv2-server", "url");
if (sUrl == null || "".equals(sUrl))
{
String dspaceUrl = ConfigurationManager
.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException(
"Unable to construct service document urls, due to missing/invalid " +
"config in sword2.url and/or dspace.baseUrl");
}
try
{
URL url = new URL(dspaceUrl);
sUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2").toString();
sUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(),
"/swordv2").toString();
}
catch (MalformedURLException e)
{
throw new DSpaceSwordException("Unable to construct service document urls, due to invalid dspace.baseUrl " +
e.getMessage(),e);
throw new DSpaceSwordException(
"Unable to construct service document urls, due to invalid dspace.baseUrl " +
e.getMessage(), e);
}
}
return sUrl;
}
}
return sUrl;
}
public Item getItem(Context context, String location)
throws DSpaceSwordException, SwordError
{
try
{
String baseUrl = this.getSwordBaseUrl();
{
String baseUrl = this.getSwordBaseUrl();
String emBaseUrl = baseUrl + "/edit-media/";
String eBaseUrl = baseUrl + "/edit/";
String sBaseUrl = baseUrl + "/statement/";
String cBaseUrl = null;
if (location.startsWith(emBaseUrl))
{
cBaseUrl = emBaseUrl;
}
else if (location.startsWith(eBaseUrl))
{
cBaseUrl = eBaseUrl;
}
else if (location.startsWith(sBaseUrl))
{
cBaseUrl = sBaseUrl;
}
String eBaseUrl = baseUrl + "/edit/";
String sBaseUrl = baseUrl + "/statement/";
String cBaseUrl = null;
if (location.startsWith(emBaseUrl))
{
cBaseUrl = emBaseUrl;
}
else if (location.startsWith(eBaseUrl))
{
cBaseUrl = eBaseUrl;
}
else if (location.startsWith(sBaseUrl))
{
cBaseUrl = sBaseUrl;
}
else
{
throw new SwordError(DSpaceUriRegistry.BAD_URL, "The item URL is invalid");
}
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"The item URL is invalid");
}
String iid = location.substring(cBaseUrl.length());
if (iid.endsWith(".atom"))
@@ -142,400 +152,424 @@ public class SwordUrlManager
// this is the atom url, so we need to strip that to ge tthe item id
iid = iid.substring(0, iid.length() - ".atom".length());
}
else if (iid.endsWith(".rdf"))
{
// this is the rdf url so we need to strip that to get the item id
iid = iid.substring(0, iid.length() - ".rdf".length());
}
else if (iid.endsWith(".rdf"))
{
// this is the rdf url so we need to strip that to get the item id
iid = iid.substring(0, iid.length() - ".rdf".length());
}
Item item = itemService.findByIdOrLegacyId(context, iid);
return item;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException("There was a problem resolving the item", e);
}
return item;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException(
"There was a problem resolving the item", e);
}
}
public String getTypeSuffix(Context context, String location)
{
String tail = location.substring(location.lastIndexOf("/"));
int typeSeparator = tail.lastIndexOf(".");
if (typeSeparator == -1)
{
return null;
}
return tail.substring(typeSeparator + 1);
}
public String getTypeSuffix(Context context, String location)
{
String tail = location.substring(location.lastIndexOf("/"));
int typeSeparator = tail.lastIndexOf(".");
if (typeSeparator == -1)
{
return null;
}
return tail.substring(typeSeparator + 1);
}
public boolean isFeedRequest(Context context, String url)
{
return url.endsWith(".atom");
}
/**
* Obtain the collection which is represented by the given
* URL
*
* @param context the DSpace context
* @param location the URL to resolve to a collection
* @return The collection to which the url resolves
* @throws DSpaceSwordException
*/
// FIXME: we need to generalise this to DSpaceObjects, so that we can support
// Communities, Collections and Items separately
public Collection getCollection(Context context, String location)
throws DSpaceSwordException, SwordError
{
try
{
String baseUrl = this.getBaseCollectionUrl();
if (baseUrl.length() == location.length())
{
throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL is incomplete");
}
String handle = location.substring(baseUrl.length());
if (handle.startsWith("/"))
{
handle = handle.substring(1);
}
if ("".equals(handle))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL is incomplete");
}
/**
* Obtain the collection which is represented by the given
* URL
*
* @param context the DSpace context
* @param location the URL to resolve to a collection
* @return The collection to which the url resolves
* @throws DSpaceSwordException
*/
// FIXME: we need to generalise this to DSpaceObjects, so that we can support
// Communities, Collections and Items separately
public Collection getCollection(Context context, String location)
throws DSpaceSwordException, SwordError
{
try
{
String baseUrl = this.getBaseCollectionUrl();
if (baseUrl.length() == location.length())
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"The deposit URL is incomplete");
}
String handle = location.substring(baseUrl.length());
if (handle.startsWith("/"))
{
handle = handle.substring(1);
}
if ("".equals(handle))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"The deposit URL is incomplete");
}
DSpaceObject dso = handleService.resolveToObject(context, handle);
DSpaceObject dso = handleService.resolveToObject(context, handle);
if (dso == null)
{
return null;
}
if (!(dso instanceof Collection))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL does not resolve to a valid collection");
}
if (!(dso instanceof Collection))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"The deposit URL does not resolve to a valid collection");
}
return (Collection) dso;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException("There was a problem resolving the collection", e);
}
}
return (Collection) dso;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException(
"There was a problem resolving the collection", e);
}
}
/**
* Construct the service document URL for the given object, which will
* be supplied in the sword:service element of other service document
* entries.
*
* @param community
* @throws DSpaceSwordException
*/
public String constructSubServiceUrl(Community community)
throws DSpaceSwordException
{
String base = this.getBaseServiceDocumentUrl();
String handle = community.getHandle();
return base + "/" + handle;
}
/**
* Construct the service document URL for the given object, which will
* be supplied in the sword:service element of other service document
* entries.
*
* @param community
* @throws DSpaceSwordException
*/
public String constructSubServiceUrl(Community community)
throws DSpaceSwordException
{
String base = this.getBaseServiceDocumentUrl();
String handle = community.getHandle();
return base + "/" + handle;
}
/**
* Construct the service document URL for the given object, which will
* be supplied in the sword:service element of other service document
* entries.
*
* @param collection
* @throws DSpaceSwordException
*/
public String constructSubServiceUrl(Collection collection)
throws DSpaceSwordException
{
String base = this.getBaseServiceDocumentUrl();
String handle = collection.getHandle();
return base + "/" + handle;
}
/**
* Construct the service document URL for the given object, which will
* be supplied in the sword:service element of other service document
* entries.
*
* @param collection
* @throws DSpaceSwordException
*/
public String constructSubServiceUrl(Collection collection)
throws DSpaceSwordException
{
String base = this.getBaseServiceDocumentUrl();
String handle = collection.getHandle();
return base + "/" + handle;
}
/**
* Extract a DSpaceObject from the given URL. If this method is unable to
* locate a meaningful and appropriate DSpace object it will throw the
* appropriate SWORD error.
* @param url
* @throws DSpaceSwordException
* @throws SwordError
*/
public DSpaceObject extractDSpaceObject(String url)
throws DSpaceSwordException, SwordError
{
try
{
String sdBase = this.getBaseServiceDocumentUrl();
// String mlBase = this.getBaseMediaLinkUrl();
/**
* Extract a DSpaceObject from the given URL. If this method is unable to
* locate a meaningful and appropriate DSpace object it will throw the
* appropriate SWORD error.
* @param url
* @throws DSpaceSwordException
* @throws SwordError
*/
public DSpaceObject extractDSpaceObject(String url)
throws DSpaceSwordException, SwordError
{
try
{
String sdBase = this.getBaseServiceDocumentUrl();
// String mlBase = this.getBaseMediaLinkUrl();
if (url.startsWith(sdBase))
{
// we are dealing with a service document request
if (url.startsWith(sdBase))
{
// we are dealing with a service document request
// first, let's find the beginning of the handle
url = url.substring(sdBase.length());
if (url.startsWith("/"))
{
url = url.substring(1);
}
if (url.endsWith("/"))
{
url = url.substring(0, url.length() - 1);
}
// first, let's find the beginning of the handle
url = url.substring(sdBase.length());
if (url.startsWith("/"))
{
url = url.substring(1);
}
if (url.endsWith("/"))
{
url = url.substring(0, url.length() - 1);
}
DSpaceObject dso = handleService.resolveToObject(context, url);
DSpaceObject dso = handleService.resolveToObject(context, url);
if (dso == null)
{
return null;
}
else if (dso instanceof Collection || dso instanceof Community)
{
return dso;
}
else
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"Service Document request does not refer to a DSpace Collection or Community");
}
}
else
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"Unable to recognise URL as a valid service document: " + url);
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
else if (dso instanceof Collection || dso instanceof Community)
{
return dso;
}
else
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"Service Document request does not refer to a DSpace Collection or Community");
}
}
else
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"Unable to recognise URL as a valid service document: " +
url);
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
/**
* Get the base URL for service document requests.
*
* @throws DSpaceSwordException
*/
public String getBaseServiceDocumentUrl()
throws DSpaceSwordException
{
String sdUrl = ConfigurationManager.getProperty("swordv2-server", "servicedocument.url");
if (sdUrl == null || "".equals(sdUrl))
{
String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException("Unable to construct service document urls, due to missing/invalid " +
"config in swordv2-server.cfg servicedocument.url and/or dspace.baseUrl");
}
/**
* Get the base URL for service document requests.
*
* @throws DSpaceSwordException
*/
public String getBaseServiceDocumentUrl()
throws DSpaceSwordException
{
String sdUrl = ConfigurationManager
.getProperty("swordv2-server", "servicedocument.url");
if (sdUrl == null || "".equals(sdUrl))
{
String dspaceUrl = ConfigurationManager
.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException(
"Unable to construct service document urls, due to missing/invalid " +
"config in swordv2-server.cfg servicedocument.url and/or dspace.baseUrl");
}
try
{
URL url = new URL(dspaceUrl);
sdUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2/servicedocument").toString();
sdUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(),
"/swordv2/servicedocument").toString();
}
catch (MalformedURLException e)
{
throw new DSpaceSwordException("Unable to construct service document urls, due to invalid dspace.baseUrl " +
e.getMessage(),e);
throw new DSpaceSwordException(
"Unable to construct service document urls, due to invalid dspace.baseUrl " +
e.getMessage(), e);
}
}
return sdUrl;
}
}
return sdUrl;
}
/**
* Get the base deposit URL for the DSpace SWORD implementation. This
* is effectively the URL of the servlet which deals with deposit
* requests, and is used as the basis for the individual Collection
* URLs
*
* If the configuration sword.deposit.url is set, this will be returned,
* but if not, it will construct the url as follows:
*
* [dspace.baseUrl]/sword/deposit
*
* where dspace.baseUrl is also in the configuration file.
*
* @return the base URL for sword deposit
* @throws DSpaceSwordException
*/
public String getBaseCollectionUrl()
throws DSpaceSwordException
{
String depositUrl = ConfigurationManager.getProperty("swordv2-server", "collection.url");
if (depositUrl == null || "".equals(depositUrl))
{
String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException("Unable to construct deposit urls, due to missing/invalid config in " +
"swordv2-server.cfg deposit.url and/or dspace.baseUrl");
}
/**
* Get the base deposit URL for the DSpace SWORD implementation. This
* is effectively the URL of the servlet which deals with deposit
* requests, and is used as the basis for the individual Collection
* URLs
*
* If the configuration sword.deposit.url is set, this will be returned,
* but if not, it will construct the url as follows:
*
* [dspace.baseUrl]/sword/deposit
*
* where dspace.baseUrl is also in the configuration file.
*
* @return the base URL for sword deposit
* @throws DSpaceSwordException
*/
public String getBaseCollectionUrl()
throws DSpaceSwordException
{
String depositUrl = ConfigurationManager
.getProperty("swordv2-server", "collection.url");
if (depositUrl == null || "".equals(depositUrl))
{
String dspaceUrl = ConfigurationManager
.getProperty("dspace.baseUrl");
if (dspaceUrl == null || "".equals(dspaceUrl))
{
throw new DSpaceSwordException(
"Unable to construct deposit urls, due to missing/invalid config in " +
"swordv2-server.cfg deposit.url and/or dspace.baseUrl");
}
try
{
URL url = new URL(dspaceUrl);
depositUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2/collection").toString();
depositUrl = new URL(url.getProtocol(), url.getHost(),
url.getPort(), "/swordv2/collection").toString();
}
catch (MalformedURLException e)
{
throw new DSpaceSwordException("Unable to construct deposit urls, due to invalid dspace.baseUrl " +
e.getMessage(),e);
throw new DSpaceSwordException(
"Unable to construct deposit urls, due to invalid dspace.baseUrl " +
e.getMessage(), e);
}
}
return depositUrl;
}
}
return depositUrl;
}
/**
* Is the given URL the base service document URL?
*
* @param url
* @throws DSpaceSwordException
*/
public boolean isBaseServiceDocumentUrl(String url)
throws DSpaceSwordException
{
return this.getBaseServiceDocumentUrl().equals(url);
}
/**
* Is the given URL the base service document URL?
*
* @param url
* @throws DSpaceSwordException
*/
public boolean isBaseServiceDocumentUrl(String url)
throws DSpaceSwordException
{
return this.getBaseServiceDocumentUrl().equals(url);
}
/**
* Central location for constructing usable URLs for DSpace bitstreams.
* There is no place in the main DSpace code base for doing this.
*
* @param bitstream
* @throws DSpaceSwordException
*/
public String getBitstreamUrl(Bitstream bitstream)
throws DSpaceSwordException
{
try
{
List<BundleBitstream> bundles = bitstream.getBundles();
Bundle parent = null;
if (!bundles.isEmpty())
{
parent = bundles.get(0).getBundle();
}
else
{
throw new DSpaceSwordException(
"Encountered orphaned bitstream");
}
/**
* Central location for constructing usable URLs for DSpace bitstreams.
* There is no place in the main DSpace code base for doing this.
*
* @param bitstream
* @throws DSpaceSwordException
*/
public String getBitstreamUrl(Bitstream bitstream)
throws DSpaceSwordException
{
try
{
List<BundleBitstream> bundles = bitstream.getBundles();
Bundle parent = null;
if (!bundles.isEmpty())
{
parent = bundles.get(0).getBundle();
}
else
{
throw new DSpaceSwordException("Encountered orphaned bitstream");
}
List<Item> items = parent.getItems();
Item item;
if (!items.isEmpty())
{
item = items.get(0);
}
else
{
throw new DSpaceSwordException("Encountered orphaned bundle");
}
List<Item> items = parent.getItems();
Item item;
if (!items.isEmpty())
{
item = items.get(0);
}
else
{
throw new DSpaceSwordException("Encountered orphaned bundle");
}
String handle = item.getHandle();
String bsLink = ConfigurationManager.getProperty("dspace.url");
String handle = item.getHandle();
String bsLink = ConfigurationManager.getProperty("dspace.url");
if (handle != null && !"".equals(handle))
{
bsLink = bsLink + "/bitstream/" + handle + "/" +
bitstream.getSequenceID() + "/" + bitstream.getName();
}
else
{
bsLink = bsLink + "/retrieve/" + bitstream.getID() + "/" +
bitstream.getName();
}
if (handle != null && !"".equals(handle))
{
bsLink = bsLink + "/bitstream/" + handle + "/" + bitstream.getSequenceID() + "/" + bitstream.getName();
}
else
{
bsLink = bsLink + "/retrieve/" + bitstream.getID() + "/" + bitstream.getName();
}
return bsLink;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
return bsLink;
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
public String getActionableBitstreamUrl(Bitstream bitstream)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/edit-media/bitstream/" +
bitstream.getID() + "/" + bitstream.getName();
}
public String getActionableBitstreamUrl(Bitstream bitstream)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/edit-media/bitstream/" + bitstream.getID() + "/" + bitstream.getName();
}
public boolean isActionableBitstreamUrl(Context context, String url)
{
return url.contains("/edit-media/bitstream/");
}
public boolean isActionableBitstreamUrl(Context context, String url)
{
return url.contains("/edit-media/bitstream/");
}
public Bitstream getBitstream(Context context, String location)
throws DSpaceSwordException, SwordError
{
try
{
String baseUrl = this.getSwordBaseUrl();
public Bitstream getBitstream(Context context, String location)
throws DSpaceSwordException, SwordError
{
try
{
String baseUrl = this.getSwordBaseUrl();
String emBaseUrl = baseUrl + "/edit-media/bitstream/";
if (!location.startsWith(emBaseUrl))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL, "The bitstream URL is invalid");
}
if (!location.startsWith(emBaseUrl))
{
throw new SwordError(DSpaceUriRegistry.BAD_URL,
"The bitstream URL is invalid");
}
String bitstreamParts = location.substring(emBaseUrl.length());
// the bitstream id is the part up to the first "/"
int firstSlash = bitstreamParts.indexOf("/");
String bid = bitstreamParts.substring(0, firstSlash);
String fn = bitstreamParts.substring(firstSlash + 1);
// the bitstream id is the part up to the first "/"
int firstSlash = bitstreamParts.indexOf("/");
String bid = bitstreamParts.substring(0, firstSlash);
String fn = bitstreamParts.substring(firstSlash + 1);
Bitstream bitstream = bitstreamService.findByIdOrLegacyId(context, bid);
return bitstream;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException("There was a problem resolving the collection", e);
}
}
Bitstream bitstream = bitstreamService
.findByIdOrLegacyId(context, bid);
return bitstream;
}
catch (SQLException e)
{
// log.error("Caught exception:", e);
throw new DSpaceSwordException(
"There was a problem resolving the collection", e);
}
}
// FIXME: we need a totally new kind of URL scheme; perhaps we write the identifier into the item
public String getAtomStatementUri(Item item)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".atom";
}
// FIXME: we need a totally new kind of URL scheme; perhaps we write the identifier into the item
public String getAtomStatementUri(Item item)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".atom";
}
public String getOreStatementUri(Item item)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".rdf";
}
public String getOreStatementUri(Item item)
throws DSpaceSwordException
{
return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".rdf";
}
public String getAggregationUrl(Item item)
throws DSpaceSwordException
{
return this.getOreStatementUri(item) + "#aggregation";
}
public String getAggregationUrl(Item item)
throws DSpaceSwordException
{
return this.getOreStatementUri(item) + "#aggregation";
}
public IRI getEditIRI(Item item)
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit/" + item.getID());
}
public IRI getEditIRI(Item item)
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit/" + item.getID());
}
public String getSplashUrl(Item item)
throws DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
public String getSplashUrl(Item item)
throws DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
// if the item is in the workspace, we need to give it it's own
// special identifier
if (wft.isItemInWorkspace(context, item))
{
String urlTemplate = ConfigurationManager.getProperty("swordv2-server", "workspace.url-template");
String urlTemplate = ConfigurationManager
.getProperty("swordv2-server", "workspace.url-template");
if (urlTemplate != null)
{
return urlTemplate.replace("#wsid#", Integer.toString(wft.getWorkspaceItem(context, item).getID()));
return urlTemplate.replace("#wsid#", Integer.toString(
wft.getWorkspaceItem(context, item).getID()));
}
}
// otherwise, it may be in the workflow, in which case there is
@@ -549,20 +583,21 @@ public class SwordUrlManager
// item
else
{
return handleService.getCanonicalForm(item.getHandle());
return handleService.getCanonicalForm(item.getHandle());
}
return null;
}
}
public IRI getContentUrl(Item item)
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID());
}
public IRI getContentUrl(Item item)
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID());
}
public IRI getMediaFeedUrl(Item item)
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID() + ".atom");
}
throws DSpaceSwordException
{
return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID() +
".atom");
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -28,81 +28,97 @@ import java.util.List;
public class VersionManager
{
protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
protected BundleService bundleService = ContentServiceFactory.getInstance().getBundleService();
protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
protected ItemService itemService = ContentServiceFactory.getInstance()
.getItemService();
public void removeBundle(Context context, Item item, String name)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager.getBooleanProperty("swordv2-server", "versions.keep");
Iterator<Bundle> bundles = item.getBundles().iterator();
while (bundles.hasNext())
{
Bundle b = bundles.next();
if (name.equals(b.getName()))
{
bundles.remove();
this.removeBundle(context, item, b, keep);
}
}
}
protected BundleService bundleService = ContentServiceFactory.getInstance()
.getBundleService();
public void removeBundle(Context context, Item item, Bundle source)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager.getBooleanProperty("swordv2-server", "versions.keep");
this.removeBundle(context, item, source, keep);
}
protected BitstreamService bitstreamService = ContentServiceFactory
.getInstance().getBitstreamService();
public void removeBundle(Context context, Item item, Bundle source, boolean archive)
throws SQLException, AuthorizeException, IOException
{
public void removeBundle(Context context, Item item, String name)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager
.getBooleanProperty("swordv2-server", "versions.keep");
Iterator<Bundle> bundles = item.getBundles().iterator();
while (bundles.hasNext())
{
Bundle b = bundles.next();
if (name.equals(b.getName()))
{
bundles.remove();
this.removeBundle(context, item, b, keep);
}
}
}
public void removeBundle(Context context, Item item, Bundle source)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager
.getBooleanProperty("swordv2-server", "versions.keep");
this.removeBundle(context, item, source, keep);
}
public void removeBundle(Context context, Item item, Bundle source,
boolean archive)
throws SQLException, AuthorizeException, IOException
{
// archive the bundle contents if desired
if (archive)
{
this.archiveBundle(context, item, source);
}
if (archive)
{
this.archiveBundle(context, item, source);
}
// remove all the bitstreams from the bundle
Iterator<BundleBitstream> bundleBitstreams = source.getBitstreams().iterator();
while (bundleBitstreams.hasNext())
{
BundleBitstream bundleBitstream = bundleBitstreams.next();
bundleBitstreams.remove();
bundleService.removeBitstream(context, source, bundleBitstream.getBitstream());
}
Iterator<BundleBitstream> bundleBitstreams = source.getBitstreams()
.iterator();
while (bundleBitstreams.hasNext())
{
BundleBitstream bundleBitstream = bundleBitstreams.next();
bundleBitstreams.remove();
bundleService.removeBitstream(context, source,
bundleBitstream.getBitstream());
}
// delete the bundle itself
itemService.removeBundle(context, item, source);
}
itemService.removeBundle(context, item, source);
}
public void removeBitstream(Context context, Item item, Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager.getBooleanProperty("swordv2-server", "versions.keep");
this.removeBitstream(context, item, bitstream, keep);
}
public void removeBitstream(Context context, Item item, Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
boolean keep = ConfigurationManager
.getBooleanProperty("swordv2-server", "versions.keep");
this.removeBitstream(context, item, bitstream, keep);
}
public void removeBitstream(Context context, Item item, Bitstream bitstream, boolean keep)
throws SQLException, AuthorizeException, IOException
{
Bundle exempt = null;
if (keep)
{
exempt = this.archiveBitstream(context, item, bitstream);
}
public void removeBitstream(Context context, Item item, Bitstream bitstream,
boolean keep)
throws SQLException, AuthorizeException, IOException
{
Bundle exempt = null;
if (keep)
{
exempt = this.archiveBitstream(context, item, bitstream);
}
Iterator<BundleBitstream> bundleBitstreams = bitstream.getBundles().iterator();
while (bundleBitstreams.hasNext())
{
BundleBitstream bundleBitstream = bundleBitstreams.next();
if (exempt != null && bundleBitstream.getBundle().getID() != exempt.getID())
{
bundleBitstreams.remove();
bundleService.removeBitstream(context, bundleBitstream.getBundle(), bitstream);
}
}
Iterator<BundleBitstream> bundleBitstreams = bitstream.getBundles()
.iterator();
while (bundleBitstreams.hasNext())
{
BundleBitstream bundleBitstream = bundleBitstreams.next();
if (exempt != null &&
bundleBitstream.getBundle().getID() != exempt.getID())
{
bundleBitstreams.remove();
bundleService
.removeBitstream(context, bundleBitstream.getBundle(),
bitstream);
}
}
// there is nowhere in the metadata to say when this file was moved, so we
// are going to drop it into the description
@@ -114,66 +130,74 @@ public class VersionManager
newDesc += desc;
}
bitstream.setDescription(context, newDesc);
bitstreamService.update(context, bitstream);
}
bitstreamService.update(context, bitstream);
}
private Bundle archiveBitstream(Context context, Item item, Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
String swordBundle = ConfigurationManager.getProperty("swordv2-server", "bundle.deleted");
if (swordBundle == null)
{
swordBundle = "DELETED";
}
private Bundle archiveBitstream(Context context, Item item,
Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
String swordBundle = ConfigurationManager
.getProperty("swordv2-server", "bundle.deleted");
if (swordBundle == null)
{
swordBundle = "DELETED";
}
List<Bundle> bundles = item.getBundles();
Bundle archive = null;
for (Bundle bundle : bundles) {
if (swordBundle.equals(bundle.getName())) {
archive = bundle;
break;
}
}
if (archive == null)
{
archive = bundleService.create(context, item, swordBundle);
}
this.archiveBitstream(context, archive, bitstream);
return archive;
}
List<Bundle> bundles = item.getBundles();
Bundle archive = null;
for (Bundle bundle : bundles)
{
if (swordBundle.equals(bundle.getName()))
{
archive = bundle;
break;
}
}
if (archive == null)
{
archive = bundleService.create(context, item, swordBundle);
}
this.archiveBitstream(context, archive, bitstream);
return archive;
}
private void archiveBitstream(Context context, Bundle target, Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
bundleService.addBitstream(context, target, bitstream);
}
private void archiveBitstream(Context context, Bundle target,
Bitstream bitstream)
throws SQLException, AuthorizeException, IOException
{
bundleService.addBitstream(context, target, bitstream);
}
private void archiveBundle(Context context, Item item, Bundle source)
throws SQLException, AuthorizeException, IOException
{
// get the datestamped root bundle name
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String oldName = "VER" + sdf.format(new Date());
oldName = this.getNumberedName(item, oldName, 0);
private void archiveBundle(Context context, Item item, Bundle source)
throws SQLException, AuthorizeException, IOException
{
// get the datestamped root bundle name
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String oldName = "VER" + sdf.format(new Date());
oldName = this.getNumberedName(item, oldName, 0);
Bundle old = bundleService.create(context, item, oldName);
List<BundleBitstream> bundleBitstreams = source.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
bundleService.addBitstream(context, old, bundleBitstream.getBitstream());
}
}
Bundle old = bundleService.create(context, item, oldName);
List<BundleBitstream> bundleBitstreams = source.getBitstreams();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
bundleService
.addBitstream(context, old, bundleBitstream.getBitstream());
}
}
private String getNumberedName(Item item, String name, int number)
throws SQLException
{
String nName = name + "." + Integer.toString(number);
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles) {
if (nName.equals(bundle.getName())) {
return this.getNumberedName(item, name, number + 1);
}
}
return nName;
}
private String getNumberedName(Item item, String name, int number)
throws SQLException
{
String nName = name + "." + Integer.toString(number);
List<Bundle> bundles = item.getBundles();
for (Bundle bundle : bundles)
{
if (nName.equals(bundle.getName()))
{
return this.getNumberedName(item, name, number + 1);
}
}
return nName;
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -16,43 +16,61 @@ import org.swordapp.server.SwordError;
public interface WorkflowManager
{
public void retrieveServiceDoc(Context context) throws SwordError, DSpaceSwordException;
public void retrieveServiceDoc(Context context)
throws SwordError, DSpaceSwordException;
public void listCollectionContents(Context context, Collection collection) throws SwordError, DSpaceSwordException;
public void listCollectionContents(Context context, Collection collection)
throws SwordError, DSpaceSwordException;
public void createResource(Context context, Collection collection) throws SwordError, DSpaceSwordException;
public void createResource(Context context, Collection collection)
throws SwordError, DSpaceSwordException;
public void retrieveContent(Context context, Item item) throws SwordError, DSpaceSwordException;
public void retrieveContent(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void retrieveBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException;
public void retrieveBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException;
public void replaceResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException;
public void replaceResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void replaceBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException;
public void replaceBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException;
public void replaceMetadata(Context context, Item item) throws SwordError, DSpaceSwordException;
public void replaceMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void replaceMetadataAndMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException;
public void replaceMetadataAndMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void deleteMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException;
public void deleteMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void deleteBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException;
public void deleteBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException;
public void addResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException;
public void addResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void addMetadata(Context context, Item item) throws SwordError, DSpaceSwordException;
public void addMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void deleteItem(Context context, Item item) throws SwordError, DSpaceSwordException;
public void deleteItem(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void retrieveStatement(Context context, Item item) throws SwordError, DSpaceSwordException;
public void retrieveStatement(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void modifyState(Context context, Item item) throws SwordError, DSpaceSwordException;
public void modifyState(Context context, Item item)
throws SwordError, DSpaceSwordException;
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription)
throws DSpaceSwordException;
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription, boolean containerOperation)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription,
boolean containerOperation)
throws DSpaceSwordException;
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -25,47 +25,56 @@ import java.util.List;
*/
public class WorkflowManagerDefault implements WorkflowManager
{
public void retrieveServiceDoc(Context context) throws SwordError
{
// do nothing - operation allowed
}
public void retrieveServiceDoc(Context context) throws SwordError
{
// do nothing - operation allowed
}
public void listCollectionContents(Context context, Collection collection) throws SwordError
{
// do nothing - operation allowed
}
public void listCollectionContents(Context context, Collection collection)
throws SwordError
{
// do nothing - operation allowed
}
public void createResource(Context context, Collection collection) throws SwordError
{
// do nothing - operation allowed
}
public void createResource(Context context, Collection collection)
throws SwordError
{
// do nothing - operation allowed
}
public void retrieveContent(Context context, Item item) throws SwordError
{
// do nothing - operation allowed
}
public void retrieveContent(Context context, Item item) throws SwordError
{
// do nothing - operation allowed
}
public void retrieveBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void retrieveBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void replaceResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void replaceResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void replaceMetadata(Context context, Item item) throws SwordError, DSpaceSwordException
{
boolean allowUpdate = ConfigurationManager.getBooleanProperty("swordv2-server", "workflowmanagerdefault.always-update-metadata");
public void replaceMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException
{
boolean allowUpdate = ConfigurationManager
.getBooleanProperty("swordv2-server",
"workflowmanagerdefault.always-update-metadata");
if (allowUpdate)
{
// all updates are allowed
@@ -73,62 +82,71 @@ public class WorkflowManagerDefault implements WorkflowManager
}
// otherwise, go ahead and figure out the state
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void replaceMetadataAndMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException
{
this.replaceResourceContent(context, item);
this.replaceMetadata(context, item);
}
public void replaceMetadataAndMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException
{
this.replaceResourceContent(context, item);
this.replaceMetadata(context, item);
}
public void deleteMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void deleteMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void deleteBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException
{
// this is equivalent to asking whether the media resource in the item can be deleted
try
{
List<BundleBitstream> bundleBitstreams = bitstream.getBundles();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
public void deleteBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException
{
// this is equivalent to asking whether the media resource in the item can be deleted
try
{
List<BundleBitstream> bundleBitstreams = bitstream.getBundles();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// is the bitstream in the ORIGINAL bundle? If not, it can't be worked on
if (!Constants.CONTENT_BUNDLE_NAME.equals(bundleBitstream.getBundle().getName()))
if (!Constants.CONTENT_BUNDLE_NAME
.equals(bundleBitstream.getBundle().getName()))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The file is not in a bundle which can be modified");
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The file is not in a bundle which can be modified");
}
List<Item> items = bundleBitstream.getBundle().getItems();
for (Item item : items)
{
this.deleteMediaResource(context, item);
}
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
List<Item> items = bundleBitstream.getBundle().getItems();
for (Item item : items)
{
this.deleteMediaResource(context, item);
}
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
public void replaceBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException
@@ -136,52 +154,63 @@ public class WorkflowManagerDefault implements WorkflowManager
// File replace with DSpace actually violates the RESTful environment, so it is
// turned off by default, and strongly advised against. Nonetheless, it is used
// by some DepositMO aware extensions, so must be supported (as shown below)
boolean fileReplace = ConfigurationManager.getBooleanProperty("swordv2-server", "workflowmanagerdefault.file-replace.enable");
boolean fileReplace = ConfigurationManager
.getBooleanProperty("swordv2-server",
"workflowmanagerdefault.file-replace.enable");
if (!fileReplace)
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "DSpace does not support file replace; you should DELETE the original file and PUT the new one");
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"DSpace does not support file replace; you should DELETE the original file and PUT the new one");
}
// this is equivalent to asking whether the media resource in the item can be deleted
try
{
List<BundleBitstream> bundleBitstreams = bitstream.getBundles();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
try
{
List<BundleBitstream> bundleBitstreams = bitstream.getBundles();
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// is the bitstream in the ORIGINAL bundle? If not, it can't be worked on
if (!Constants.CONTENT_BUNDLE_NAME.equals(bundleBitstream.getBundle().getName()))
if (!Constants.CONTENT_BUNDLE_NAME
.equals(bundleBitstream.getBundle().getName()))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The file is not in a bundle which can be modified");
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The file is not in a bundle which can be modified");
}
for (Item item : bundleBitstream.getBundle().getItems())
{
this.replaceResourceContent(context, item);
}
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
for (Item item : bundleBitstream.getBundle().getItems())
{
this.replaceResourceContent(context, item);
}
}
}
catch (SQLException e)
{
throw new DSpaceSwordException(e);
}
}
public void addResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void addResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void addMetadata(Context context, Item item) throws SwordError, DSpaceSwordException
{
boolean allowUpdate = ConfigurationManager.getBooleanProperty("swordv2-server", "workflowmanagerdefault.always-update-metadata");
public void addMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException
{
boolean allowUpdate = ConfigurationManager
.getBooleanProperty("swordv2-server",
"workflowmanagerdefault.always-update-metadata");
if (allowUpdate)
{
// all updates are allowed
@@ -189,66 +218,78 @@ public class WorkflowManagerDefault implements WorkflowManager
}
// otherwise, lookup the state of the item
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void deleteItem(Context context, Item item) throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void deleteItem(Context context, Item item)
throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void retrieveStatement(Context context, Item item) throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void retrieveStatement(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void modifyState(Context context, Item item) throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void modifyState(Context context, Item item)
throws SwordError, DSpaceSwordException
{
WorkflowTools wft = new WorkflowTools();
if (item.isArchived() || item.isWithdrawn())
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been archived, and can no longer be modified");
}
if (wft.isItemInWorkflow(context, item))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The item has already been injected into the review workflow, and can no longer be modified");
}
}
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
this.resolveState(context, deposit, result, verboseDescription, true);
}
this.resolveState(context, deposit, result, verboseDescription, true);
}
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription, boolean containerOperation)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription,
boolean containerOperation)
throws DSpaceSwordException
{
// the containerOperation flag tells us whether this method was called by an operation which happened on the
// container. This workflow implementation only changes workflow states on contaner operations, not media
// resource operations, so we just bounce this right back.
if (!containerOperation)
{
return;
}
// the containerOperation flag tells us whether this method was called by an operation which happened on the
// container. This workflow implementation only changes workflow states on contaner operations, not media
// resource operations, so we just bounce this right back.
if (!containerOperation)
{
return;
}
// if we get to here this is a container operation, and we can decide how best to process
// if we get to here this is a container operation, and we can decide how best to process
Item item = result.getItem();
// find out where the item is in the workflow
@@ -269,25 +310,29 @@ public class WorkflowManagerDefault implements WorkflowManager
if (!deposit.isInProgress() && inarch)
{
verboseDescription.append("The deposit is finished, and the item is already in the archive");
verboseDescription
.append("The deposit is finished, and the item is already in the archive");
// throw new DSpaceSwordException("Invalid workflow state");
}
if (!deposit.isInProgress() && inws)
{
verboseDescription.append("The deposit is finished: moving it from the workspace to the workflow");
verboseDescription
.append("The deposit is finished: moving it from the workspace to the workflow");
wft.startWorkflow(context, item);
}
if (deposit.isInProgress() && inarch)
{
verboseDescription.append("The deposit is not finished, and the item is already in the archive");
verboseDescription
.append("The deposit is not finished, and the item is already in the archive");
// throw new DSpaceSwordException("Invalid workflow state");
}
if (deposit.isInProgress() && inwf)
{
verboseDescription.append("The deposit is in progress, but is in the workflow; returning to the workspace");
verboseDescription
.append("The deposit is in progress, but is in the workflow; returning to the workspace");
wft.stopWorkflow(context, item);
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -12,14 +12,16 @@ import org.swordapp.server.SwordError;
public class WorkflowManagerFactory
{
public static WorkflowManager getInstance()
public static WorkflowManager getInstance()
throws DSpaceSwordException, SwordError
{
WorkflowManager manager = (WorkflowManager) PluginManager.getSinglePlugin("swordv2-server", WorkflowManager.class);
WorkflowManager manager = (WorkflowManager) PluginManager
.getSinglePlugin("swordv2-server", WorkflowManager.class);
if (manager == null)
{
throw new SwordError(DSpaceUriRegistry.REPOSITORY_ERROR, "No workflow manager configured");
throw new SwordError(DSpaceUriRegistry.REPOSITORY_ERROR,
"No workflow manager configured");
}
return manager;
}
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -29,12 +29,14 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
// do nothing - operation allowed
}
public void listCollectionContents(Context context, Collection collection) throws SwordError
public void listCollectionContents(Context context, Collection collection)
throws SwordError
{
// do nothing - operation allowed
}
public void createResource(Context context, Collection collection) throws SwordError
public void createResource(Context context, Collection collection)
throws SwordError
{
// do nothing - operation allowed
}
@@ -44,32 +46,38 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
// do nothing - operation allowed
}
public void retrieveBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException
public void retrieveBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void replaceResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException
public void replaceResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void replaceMetadata(Context context, Item item) throws SwordError, DSpaceSwordException
public void replaceMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void replaceMetadataAndMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException
public void replaceMetadataAndMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void deleteMediaResource(Context context, Item item) throws SwordError, DSpaceSwordException
public void deleteMediaResource(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void deleteBitstream(Context context, Bitstream bitstream) throws SwordError, DSpaceSwordException
public void deleteBitstream(Context context, Bitstream bitstream)
throws SwordError, DSpaceSwordException
{
// this is equivalent to asking whether the media resource in the item can be deleted
try
@@ -78,9 +86,11 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// is the bitstream in the ORIGINAL bundle? If not, it can't be worked on
if (!Constants.CONTENT_BUNDLE_NAME.equals(bundleBitstream.getBundle().getName()))
if (!Constants.CONTENT_BUNDLE_NAME
.equals(bundleBitstream.getBundle().getName()))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The file is not in a bundle which can be modified");
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The file is not in a bundle which can be modified");
}
List<Item> items = bundleBitstream.getBundle().getItems();
@@ -106,9 +116,11 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
for (BundleBitstream bundleBitstream : bundleBitstreams)
{
// is the bitstream in the ORIGINAL bundle? If not, it can't be worked on
if (!Constants.CONTENT_BUNDLE_NAME.equals(bundleBitstream.getBundle().getName()))
if (!Constants.CONTENT_BUNDLE_NAME
.equals(bundleBitstream.getBundle().getName()))
{
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED, "The file is not in a bundle which can be modified");
throw new SwordError(UriRegistry.ERROR_METHOD_NOT_ALLOWED,
"The file is not in a bundle which can be modified");
}
List<Item> items = bundleBitstream.getBundle().getItems();
@@ -124,38 +136,46 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
}
}
public void addResourceContent(Context context, Item item) throws SwordError, DSpaceSwordException
public void addResourceContent(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void addMetadata(Context context, Item item) throws SwordError, DSpaceSwordException
public void addMetadata(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void deleteItem(Context context, Item item) throws SwordError, DSpaceSwordException
public void deleteItem(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void retrieveStatement(Context context, Item item) throws SwordError, DSpaceSwordException
public void retrieveStatement(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void modifyState(Context context, Item item) throws SwordError, DSpaceSwordException
public void modifyState(Context context, Item item)
throws SwordError, DSpaceSwordException
{
// do nothing - operation allowed
}
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription)
throws DSpaceSwordException
{
this.resolveState(context, deposit, result, verboseDescription, true);
}
public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription, boolean containerOperation)
public void resolveState(Context context, Deposit deposit,
DepositResult result, VerboseDescription verboseDescription,
boolean containerOperation)
throws DSpaceSwordException
{
// the containerOperation flag tells us whether this method was called by an operation which happened on the
@@ -187,25 +207,29 @@ public class WorkflowManagerUnrestricted implements WorkflowManager
if (!deposit.isInProgress() && inarch)
{
verboseDescription.append("The deposit is finished, and the item is already in the archive");
verboseDescription
.append("The deposit is finished, and the item is already in the archive");
// throw new DSpaceSwordException("Invalid workflow state");
}
if (!deposit.isInProgress() && inws)
{
verboseDescription.append("The deposit is finished: moving it from the workspace to the workflow");
verboseDescription
.append("The deposit is finished: moving it from the workspace to the workflow");
wft.startWorkflow(context, item);
}
if (deposit.isInProgress() && inarch)
{
verboseDescription.append("The deposit is not finished, and the item is already in the archive");
verboseDescription
.append("The deposit is not finished, and the item is already in the archive");
// throw new DSpaceSwordException("Invalid workflow state");
}
if (deposit.isInProgress() && inwf)
{
verboseDescription.append("The deposit is in progress, but is in the workflow; returning to the workspace");
verboseDescription
.append("The deposit is in progress, but is in the workflow; returning to the workspace");
wft.stopWorkflow(context, item);
}
}

View File

@@ -2,7 +2,7 @@
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* <p>
* http://www.dspace.org/license/
*/
package org.dspace.sword2;
@@ -30,13 +30,20 @@ import java.sql.SQLException;
public class WorkflowTools
{
protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();
protected WorkspaceItemService workspaceItemService = ContentServiceFactory
.getInstance().getWorkspaceItemService();
protected BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory.getInstance().getBasicWorkflowItemService();
protected BasicWorkflowService basicWorkflowService = BasicWorkflowServiceFactory.getInstance().getBasicWorkflowService();
protected BasicWorkflowItemService basicWorkflowItemService = BasicWorkflowServiceFactory
.getInstance().getBasicWorkflowItemService();
protected XmlWorkflowItemService xmlWorkflowItemService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowItemService();
protected XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService();
protected BasicWorkflowService basicWorkflowService = BasicWorkflowServiceFactory
.getInstance().getBasicWorkflowService();
protected XmlWorkflowItemService xmlWorkflowItemService = XmlWorkflowServiceFactory
.getInstance().getXmlWorkflowItemService();
protected XmlWorkflowService xmlWorkflowService = XmlWorkflowServiceFactory
.getInstance().getXmlWorkflowService();
/**
* Is the given item in the DSpace workflow?
@@ -53,10 +60,16 @@ public class WorkflowTools
{
try
{
if(ConfigurationManager.getProperty("workflow","workflow.framework").equals("xmlworkflow")){
if (ConfigurationManager
.getProperty("workflow", "workflow.framework")
.equals("xmlworkflow"))
{
return xmlWorkflowItemService.findByItem(context, item) != null;
}else{
return basicWorkflowItemService.findByItem(context, item) != null;
}
else
{
return basicWorkflowItemService.findByItem(context, item) !=
null;
}
}
catch (SQLException e)
@@ -103,9 +116,14 @@ public class WorkflowTools
{
try
{
if(ConfigurationManager.getProperty("workflow","workflow.framework").equals("xmlworkflow")){
if (ConfigurationManager
.getProperty("workflow", "workflow.framework")
.equals("xmlworkflow"))
{
return xmlWorkflowItemService.findByItem(context, item);
}else{
}
else
{
return basicWorkflowItemService.findByItem(context, item);
}
}
@@ -153,17 +171,29 @@ public class WorkflowTools
WorkspaceItem wsi = this.getWorkspaceItem(context, item);
// kick off the workflow
boolean notify = ConfigurationManager.getBooleanProperty("swordv2-server", "workflow.notify");
if (ConfigurationManager.getProperty("workflow", "workflow.framework").equals("xmlworkflow")) {
if (notify) {
boolean notify = ConfigurationManager
.getBooleanProperty("swordv2-server", "workflow.notify");
if (ConfigurationManager
.getProperty("workflow", "workflow.framework")
.equals("xmlworkflow"))
{
if (notify)
{
xmlWorkflowService.start(context, wsi);
} else {
}
else
{
xmlWorkflowService.startWithoutNotify(context, wsi);
}
} else {
if (notify) {
}
else
{
if (notify)
{
basicWorkflowService.start(context, wsi);
} else {
}
else
{
basicWorkflowService.startWithoutNotify(context, wsi);
}
}
@@ -191,11 +221,15 @@ public class WorkflowTools
// abort the workflow
if (wfi != null)
{
if(wfi instanceof BasicWorkflowItem)
if (wfi instanceof BasicWorkflowItem)
{
basicWorkflowService.abort(context, (BasicWorkflowItem) wfi, context.getCurrentUser());
}else{
xmlWorkflowService.abort(context, (XmlWorkflowItem) wfi, context.getCurrentUser());
basicWorkflowService.abort(context, (BasicWorkflowItem) wfi,
context.getCurrentUser());
}
else
{
xmlWorkflowService.abort(context, (XmlWorkflowItem) wfi,
context.getCurrentUser());
}
}
}