/**
* 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
*
* http://www.dspace.org/license/
*/
package org.dspace.sword;
import org.apache.commons.lang.StringUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.*;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.BitstreamFormatService;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.BundleService;
import org.dspace.content.service.ItemService;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.purl.sword.base.Deposit;
import org.purl.sword.base.ErrorCodes;
import org.purl.sword.base.SWORDErrorException;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
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();
private Item item;
public ItemDepositor(SWORDService swordService, DSpaceObject dso)
throws DSpaceSWORDException
{
super(swordService, dso);
if (!(dso instanceof Item))
{
throw new DSpaceSWORDException(
"You tried to initialise the item depositor with something" +
"other than an item object");
}
this.item = (Item) dso;
}
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();
// 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());
}
// 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());
}
// Obtain the relevant ingester from the factory
SWORDIngester si = SWORDIngesterFactory
.getInstance(context, deposit, item);
swordService.message("Loaded ingester: " + si.getClass().getName());
// do the deposit
DepositResult result = si.ingest(swordService, deposit, item);
swordService.message("Archive ingest completed successfully");
// 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");
// 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;
try
{
fis = new FileInputStream(deposit.getFile());
bitstream = bitstreamService
.create(context, swordBundle, fis);
}
finally
{
if (fis != null)
{
fis.close();
}
}
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);
}
bitstreamService.update(context, bitstream);
bundleService.update(context, swordBundle);
itemService.update(context, item);
swordService.message("Original package stored as " + fn +
", in item bundle " + swordBundle);
// 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);
}
return result;
}
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<Bundle> bundles = bs.getBundles().iterator();
while (bundles.hasNext())
{
Bundle bundle = bundles.next();
bundles.remove();
bundleService.removeBitstream(sc.getContext(), bundle, bs);
bundleService.update(sc.getContext(), bundle);
}
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);
}
}
}