/* DepositManager.java
*
* Copyright (c) 2007, Aberystwyth University
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* - Neither the name of the Centre for Advanced Software and
* Intelligent Systems (CASIS) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package org.dspace.sword;
import java.util.Date;
import org.apache.log4j.Logger;
import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.purl.sword.base.Deposit;
import org.purl.sword.base.DepositResponse;
import org.purl.sword.base.SWORDAuthenticationException;
import org.purl.sword.base.SWORDEntry;
import org.purl.sword.base.SWORDErrorException;
/**
* This class is responsible for initiating the process of
* deposit of SWORD Deposit objects into the DSpace repository
*
* @author Richard Jones
*
*/
public class DepositManager
{
/** Log4j logger */
public static Logger log = Logger.getLogger(DepositManager.class);
/** 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");
}
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);
swordService.message("Performing deposit using location: " + loc);
if (dso instanceof Collection)
{
swordService.message("Location resolves to collection with handle: " + dso.getHandle() +
" and name: " + ((Collection) dso).getMetadata("name"));
}
else if (dso instanceof Item)
{
swordService.message("Location resolves to item with handle: " + dso.getHandle());
}
return dso;
}
/**
* Once this object is fully prepared, this method will execute
* the deposit process. The returned DepositRequest can be
* used then to assembel 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 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");
}
// 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);
}
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 = dep.doDeposit(deposit);
// 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 (handle == null || "".equals(handle))
{
state = Deposit.ACCEPTED;
}
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);
// 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());
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);
return response;
}
}