Package org.dspace.sword

Source Code of org.dspace.sword.DepositManager

/**
* 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 java.io.*;
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.dspace.core.Utils;

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 final 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 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 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 = null;

        try
        {
            result = dep.doDeposit(deposit);
        }
        catch(DSpaceSWORDException e)
        {
            if (swordService.getSwordConfig().isKeepPackageOnFailedIngest())
            {
                try
                {
                    storePackageAsFile(deposit);
                }
                catch(IOException e2)
                {
                    log.warn("Unable to store SWORD package as file: " + e);
                }
            }
            throw e;
        }
        catch(SWORDErrorException e)
        {
            if (swordService.getSwordConfig().isKeepPackageOnFailedIngest())
            {
                try
                {
                    storePackageAsFile(deposit);
                }
                catch(IOException e2)
                {
                    log.warn("Unable to store SWORD package as file: " + e);
                }
            }
            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 (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;
  }

    /**
     *   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
     */
    private void storePackageAsFile(Deposit deposit) throws IOException
    {
        String path = swordService.getSwordConfig().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-" + 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));
        Utils.copy(is, fos);
        fos.close();
        is.close();

        //write companion file with headers
        PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(headersFile)));

        pw.println("Content-Disposition=" + deposit.getContentDisposition());
        pw.println("Content-Type=" + deposit.getContentType());
        pw.println("Packaging=" + deposit.getPackaging());
        pw.println("Location=" + deposit.getLocation());
        pw.println("On Behalf of=" + deposit.getOnBehalfOf());
        pw.println("Slug=" + deposit.getSlug());
        pw.println("User name=" + deposit.getUsername());
        pw.close();
    }
}
TOP

Related Classes of org.dspace.sword.DepositManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.