From eb63f024f044a6415a35265eef19a421fba69ece Mon Sep 17 00:00:00 2001 From: Andrea Schweer Date: Mon, 24 Aug 2015 09:50:39 +1200 Subject: [PATCH] DS-2701 Reformat code according to DSpace code conventions --- .../dspace/sword/ATOMCollectionGenerator.java | 41 +- .../dspace/sword/BitstreamEntryGenerator.java | 447 ++-- .../sword/CollectionCollectionGenerator.java | 173 +- .../org/dspace/sword/CollectionDepositor.java | 310 +-- .../org/dspace/sword/CollectionLocation.java | 204 +- .../sword/CommunityCollectionGenerator.java | 111 +- .../org/dspace/sword/DSpaceATOMEntry.java | 499 ++-- .../dspace/sword/DSpaceSWORDErrorCodes.java | 42 +- .../dspace/sword/DSpaceSWORDException.java | 36 +- .../org/dspace/sword/DSpaceSWORDServer.java | 283 +-- .../java/org/dspace/sword/DepositManager.java | 325 +-- .../java/org/dspace/sword/DepositResult.java | 131 +- .../main/java/org/dspace/sword/Depositor.java | 66 +- .../dspace/sword/ItemCollectionGenerator.java | 145 +- .../java/org/dspace/sword/ItemDepositor.java | 296 +-- .../org/dspace/sword/ItemEntryGenerator.java | 547 ++--- .../org/dspace/sword/LoadDSpaceConfig.java | 17 +- .../org/dspace/sword/MediaEntryManager.java | 87 +- .../org/dspace/sword/SWORDAuthentication.java | 35 +- .../org/dspace/sword/SWORDAuthenticator.java | 2025 +++++++++-------- .../org/dspace/sword/SWORDConfiguration.java | 645 +++--- .../java/org/dspace/sword/SWORDContext.java | 270 +-- .../java/org/dspace/sword/SWORDIngester.java | 24 +- .../dspace/sword/SWORDIngesterFactory.java | 82 +- .../org/dspace/sword/SWORDMETSIngester.java | 478 ++-- .../org/dspace/sword/SWORDProperties.java | 8 +- .../java/org/dspace/sword/SWORDService.java | 276 +-- .../org/dspace/sword/SWORDUrlManager.java | 955 ++++---- .../dspace/sword/ServiceDocumentManager.java | 259 ++- .../org/dspace/sword/SimpleFileIngester.java | 151 +- .../org/dspace/sword2/AbstractSimpleDC.java | 34 +- .../sword2/AbstractSwordContentIngester.java | 314 +-- .../sword2/AtomCollectionGenerator.java | 19 +- .../sword2/AtomStatementDisseminator.java | 88 +- .../dspace/sword2/BinaryContentIngester.java | 297 +-- .../sword2/CollectionCollectionGenerator.java | 162 +- .../CollectionDepositManagerDSpace.java | 485 ++-- .../sword2/CollectionListManagerDSpace.java | 264 ++- .../sword2/CommunityCollectionGenerator.java | 113 +- .../dspace/sword2/ContainerManagerDSpace.java | 904 ++++---- .../org/dspace/sword2/DSpaceSwordAPI.java | 295 ++- .../dspace/sword2/DSpaceSwordException.java | 36 +- .../org/dspace/sword2/DSpaceUriRegistry.java | 36 +- .../java/org/dspace/sword2/DepositResult.java | 82 +- .../sword2/FeedContentDisseminator.java | 33 +- .../sword2/GenericStatementDisseminator.java | 211 +- .../sword2/MediaResourceManagerDSpace.java | 748 +++--- .../sword2/OreStatementDisseminator.java | 25 +- .../org/dspace/sword2/ReceiptGenerator.java | 394 ++-- .../sword2/ServiceDocumentManagerDSpace.java | 256 ++- .../sword2/SimpleDCEntryDisseminator.java | 14 +- .../dspace/sword2/SimpleDCEntryIngester.java | 539 +++-- .../org/dspace/sword2/SimpleDCMetadata.java | 3 +- .../sword2/SimpleZipContentDisseminator.java | 18 +- .../sword2/SimpleZipContentIngester.java | 313 +-- .../dspace/sword2/StatementManagerDSpace.java | 73 +- .../org/dspace/sword2/SwordAuthenticator.java | 1668 +++++++------- .../sword2/SwordConfigurationDSpace.java | 945 ++++---- .../sword2/SwordContentDisseminator.java | 8 +- .../dspace/sword2/SwordContentIngester.java | 32 +- .../java/org/dspace/sword2/SwordContext.java | 268 +-- .../sword2/SwordDisseminatorFactory.java | 100 +- .../dspace/sword2/SwordEntryDisseminator.java | 7 +- .../org/dspace/sword2/SwordEntryIngester.java | 15 +- .../dspace/sword2/SwordIngesterFactory.java | 68 +- .../sword2/SwordMETSContentIngester.java | 311 +-- .../sword2/SwordMETSPackageIngester.java | 10 +- .../sword2/SwordStatementDisseminator.java | 6 +- .../org/dspace/sword2/SwordUrlManager.java | 867 +++---- .../dspace/sword2/TempFileInputStream.java | 2 +- .../org/dspace/sword2/VerboseDescription.java | 2 +- .../org/dspace/sword2/VersionManager.java | 266 ++- .../org/dspace/sword2/WorkflowManager.java | 58 +- .../dspace/sword2/WorkflowManagerDefault.java | 395 ++-- .../dspace/sword2/WorkflowManagerFactory.java | 12 +- .../sword2/WorkflowManagerUnrestricted.java | 72 +- .../java/org/dspace/sword2/WorkflowTools.java | 78 +- 77 files changed, 10667 insertions(+), 9247 deletions(-) diff --git a/dspace-sword/src/main/java/org/dspace/sword/ATOMCollectionGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/ATOMCollectionGenerator.java index 7078ec9487..bb2f357e30 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ATOMCollectionGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ATOMCollectionGenerator.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -12,30 +12,31 @@ import org.dspace.content.DSpaceObject; /** * @author Richard Jones - * + * * Define an abstract interface for classes wishing to generate ATOM Collections * for SWORD service documents */ 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; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/BitstreamEntryGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/BitstreamEntryGenerator.java index 337deeabaf..21b3c6a6db 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/BitstreamEntryGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/BitstreamEntryGenerator.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -23,251 +23,258 @@ import java.util.List; /** * @author Richard Jones - * + * * Class to generate ATOM Entry documents for DSpace Bitstreams */ 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 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 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 lbundles = item.getBundles(); + for (Bundle lbundle : lbundles) + { + if (!Constants.LICENSE_BUNDLE_NAME.equals(lbundle.getName())) + { + // skip non-license bundles + continue; + } + List 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 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 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 lbundles = item.getBundles(); - for (Bundle lbundle : lbundles) { - if (!Constants.LICENSE_BUNDLE_NAME.equals(lbundle.getName())) - { - // skip non-license bundles - continue; - } - List 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 + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/CollectionCollectionGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/CollectionCollectionGenerator.java index 8575507476..b1eb852637 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/CollectionCollectionGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/CollectionCollectionGenerator.java @@ -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 - * + *

* 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 accepts = swordService.getSwordConfig().getCollectionAccepts(); + scol.setMediation(mediation); + + List accepts = swordService.getSwordConfig() + .getCollectionAccepts(); for (String accept : accepts) { scol.addAccepts(accept); } - // add the accept packaging values - Map aps = swordConfig.getAcceptPackaging(col); - for (Map.Entry ap : aps.entrySet()) - { - scol.addAcceptPackaging(ap.getKey(), ap.getValue()); - } + // add the accept packaging values + Map aps = swordConfig.getAcceptPackaging(col); + for (Map.Entry 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; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/CollectionDepositor.java b/dspace-sword/src/main/java/org/dspace/sword/CollectionDepositor.java index 728d3a055d..68107a457d 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/CollectionDepositor.java +++ b/dspace-sword/src/main/java/org/dspace/sword/CollectionDepositor.java @@ -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 - * + *

* 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 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 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"); - } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/CollectionLocation.java b/dspace-sword/src/main/java/org/dspace/sword/CollectionLocation.java index a1509deb3f..f7863ac6fb 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/CollectionLocation.java +++ b/dspace-sword/src/main/java/org/dspace/sword/CollectionLocation.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -25,117 +25,125 @@ import org.dspace.handle.service.HandleService; * This class provides a single point of contact for * resolving Collections from SWORD Deposit URLs and for * generating SWORD Deposit URLs from Collections - * + * * @author Richard Jones * */ 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 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 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(); + } - DSpaceObject dso = handleService.resolveToObject(context, handle); - - 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); - } - } - - /** - * 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"); - } + /** + * 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); + + 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); + } + } + + /** + * 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; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/CommunityCollectionGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/CommunityCollectionGenerator.java index 8358ef897a..a7aebfc989 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/CommunityCollectionGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/CommunityCollectionGenerator.java @@ -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 - * + *

* 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 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 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; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/DSpaceATOMEntry.java b/dspace-sword/src/main/java/org/dspace/sword/DSpaceATOMEntry.java index 4f0165049b..c6aa4a0f17 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DSpaceATOMEntry.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DSpaceATOMEntry.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -24,296 +24,297 @@ import org.purl.sword.atom.Generator; * handles the objects in a default way, but the intention is * for you to be able to extend the class with your own * representation if necessary. - * + * * @author Richard Jones * */ public abstract class DSpaceATOMEntry { - /** the SWORD ATOM entry which this class effectively decorates */ - protected SWORDEntry entry; - - /** the item this ATOM entry represents */ - protected Item item = null; + /** the SWORD ATOM entry which this class effectively decorates */ + protected SWORDEntry entry; - /** The bitstream this ATOM entry represents */ - protected Bitstream bitstream = null; + /** the item this ATOM entry represents */ + protected Item item = null; - /** the deposit result */ - protected DepositResult result = null; + /** The bitstream this ATOM entry represents */ + protected Bitstream bitstream = null; - /** sword service implementation */ - protected SWORDService swordService; + /** the deposit result */ + protected DepositResult result = null; - /** the original deposit */ - protected Deposit deposit = null; + /** sword service implementation */ + protected SWORDService swordService; - /** - * Create a new atom entry object around the given service - * - * @param service - */ - protected DSpaceATOMEntry(SWORDService service) - { - this.swordService = service; - } + /** the original deposit */ + protected Deposit 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; - } + /** + * Create a new atom entry object around the given service + * + * @param service + */ + protected DSpaceATOMEntry(SWORDService service) + { + this.swordService = service; + } - /** - * 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(); + /** + * 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; + } - // 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"); - } + /** + * 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(); - this.constructEntry(); + // 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"); + } - return entry; - } + this.constructEntry(); - /** - * 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(); + return entry; + } - this.entry = new SWORDEntry(); - this.item = result.getItem(); - this.bitstream = result.getBitstream(); - this.result = result; - this.deposit = deposit; + /** + * 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.constructEntry(); + this.entry = new SWORDEntry(); + this.item = result.getItem(); + this.bitstream = result.getBitstream(); + this.result = result; + this.deposit = deposit; - return entry; - } + this.constructEntry(); - /** - * Construct the entry - * - * @throws DSpaceSWORDException - */ - protected void constructEntry() - throws DSpaceSWORDException - { - // set the generator - this.addGenerator(); + return entry; + } - // add the authors to the sword entry - this.addAuthors(); + /** + * Construct the entry + * + * @throws DSpaceSWORDException + */ + protected void constructEntry() + throws DSpaceSWORDException + { + // set the generator + this.addGenerator(); - // add the category information to the sword entry - this.addCategories(); + // add the authors to the sword entry + this.addAuthors(); - // add a content element to the sword entry - this.addContentElement(); + // add the category information to the sword entry + this.addCategories(); - // add a packaging element to the sword entry - this.addPackagingElement(); + // add a content element to the sword entry + this.addContentElement(); - // add contributors (authors plus any other bits) to the sword entry - this.addContributors(); + // add a packaging element to the sword entry + this.addPackagingElement(); - // add the identifier for the item, if the id is going - // to be valid by the end of the request - this.addIdentifier(); + // add contributors (authors plus any other bits) to the sword entry + this.addContributors(); - // add any appropriate links - this.addLinks(); + // add the identifier for the item, if the id is going + // to be valid by the end of the request + this.addIdentifier(); - // add the publish date - this.addPublishDate(); + // add any appropriate links + this.addLinks(); - // add the rights information - this.addRights(); + // add the publish date + this.addPublishDate(); - // add the summary of the item - this.addSummary(); + // add the rights information + this.addRights(); - // add the title of the item - this.addTitle(); + // add the summary of the item + this.addSummary(); - // add the date on which the entry was last updated - this.addLastUpdatedDate(); + // add the title of the item + this.addTitle(); - // set the treatment - this.addTreatment(); - } + // add the date on which the entry was last updated + this.addLastUpdatedDate(); - /** - * Add deposit treatment text - */ - protected void addTreatment() - { - if (result != null) - { - entry.setTreatment(result.getTreatment()); - } - } + // set the treatment + this.addTreatment(); + } - /** - * 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 deposit treatment text + */ + protected void addTreatment() + { + if (result != null) + { + entry.setTreatment(result.getTreatment()); + } + } - /** - * set the packaging format of the deposit - */ - protected void addPackagingElement() - { - if (deposit != null) - { - entry.setPackaging(deposit.getPackaging()); - } - } + /** + * 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 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); - } - } + /** + * set the packaging format of the deposit + */ + protected void addPackagingElement() + { + if (deposit != null) + { + entry.setPackaging(deposit.getPackaging()); + } + } - /** - * 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 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 all the subject classifications from the bibliographic - * metadata. - * - */ - abstract void addCategories() throws DSpaceSWORDException; + /** + * 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); + } + } + } - /** - * Set the content type that DSpace received. This is just - * "application/zip" in this default implementation. - * - */ - abstract void addContentElement() 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; - /** - * 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 the date of publication from the bibliographic metadata - * - */ - abstract void addPublishDate() 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 rights information. This attaches an href to the URL - * of the item's licence file - * - */ - abstract void addRights() throws DSpaceSWORDException; + /** + * Add links associated with this item. + * + */ + abstract void addLinks() 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 date that this item was last updated - * - */ - abstract void addLastUpdatedDate() 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 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 date that this item was last updated + * + */ + abstract void addLastUpdatedDate() throws DSpaceSWORDException; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDErrorCodes.java b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDErrorCodes.java index f1905f3294..531ca173b3 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDErrorCodes.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDErrorCodes.java @@ -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 - * + *

* 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"; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDException.java b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDException.java index f3ca1e80d0..01e4ed63c4 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDException.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDException.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -10,31 +10,31 @@ package org.dspace.sword; /** * This Exception class can be thrown by the internals of the * DSpace SWORD implementation - * + * * @author Richard Jones * */ 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); + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDServer.java b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDServer.java index 8eccf1d534..57b52c71f8 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDServer.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DSpaceSWORDServer.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -26,164 +26,183 @@ import org.purl.sword.base.ServiceDocumentRequest; /** * An implementation of the SWORDServer interface to allow SWORD deposit * operations on DSpace. See: - * + * * http://www.ukoln.ac.uk/repositories/digirep/index/SWORD_APP_Profile_0.5 - * + * * @author Richard Jones */ 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())); - - // 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 + // 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()); + + 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; + } + } - 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(); + /* (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(); if (log.isDebugEnabled()) - { - 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())); - - // 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(); - - 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) + { + 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())); + + // 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(); + + 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(); } - } - } + } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/DepositManager.java b/dspace-sword/src/main/java/org/dspace/sword/DepositManager.java index be5e401ea5..5635bf2e29 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DepositManager.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DepositManager.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -32,119 +32,135 @@ 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); + /** 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; - } - - DepositResponse response = new DepositResponse(state); - response.setLocation(result.getMediaLink()); + // 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; + } - 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); + DepositResponse response = new DepositResponse(state); + response.setLocation(result.getMediaLink()); - // 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()); + 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); - Date finish = new Date(); - long delta = finish.getTime() - start.getTime(); - swordService.message("Total time for deposit processing: " + delta + " ms"); - entry.setVerboseDescription(swordService.getVerboseDescription().toString()); + // 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"); + } - response.setEntry(entry); - - return response; - } + 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 @@ -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()); diff --git a/dspace-sword/src/main/java/org/dspace/sword/DepositResult.java b/dspace-sword/src/main/java/org/dspace/sword/DepositResult.java index 54037cf46f..0a8a4cd95e 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/DepositResult.java +++ b/dspace-sword/src/main/java/org/dspace/sword/DepositResult.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -14,87 +14,86 @@ import org.dspace.content.Bitstream; * The DSpace class for representing the results of a deposit * request. This class can be used to hold all of the relevant * components required to later build the SWORD response - * + * * @author Richard Jones * */ public class DepositResult { - /** the handle assigned to the item, if available */ - private String handle; - - /** the item created during deposit */ - private Item item; + /** the handle assigned to the item, if available */ + private String handle; - /** Bitstream created as a result of the deposit */ - private Bitstream bitstream; + /** the item created during deposit */ + private Item item; - /** The treatment of the item during deposit */ - private String treatment; + /** Bitstream created as a result of the deposit */ + private Bitstream bitstream; - /** The media linkto the created object */ - private String mediaLink; + /** The treatment of the item during deposit */ + private String treatment; + /** 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; - } - - /** - * @param item the item to set - */ - public void setItem(Item item) - { - this.item = item; - } + /** + * @return the item + */ + public Item getItem() + { + return item; + } - /** - * @return the handle - */ - public String getHandle() - { - return handle; - } + /** + * @param item the item to set + */ + public void setItem(Item item) + { + this.item = item; + } - /** - * @param handle the item handle - */ - public void setHandle(String handle) - { - this.handle = handle; - } + /** + * @return the handle + */ + public String getHandle() + { + return handle; + } - public String getMediaLink() - { - return mediaLink; - } + /** + * @param handle the item handle + */ + public void setHandle(String handle) + { + this.handle = handle; + } - public void setMediaLink(String mediaLink) - { - this.mediaLink = mediaLink; - } + public String getMediaLink() + { + return mediaLink; + } + + public void setMediaLink(String mediaLink) + { + this.mediaLink = mediaLink; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/Depositor.java b/dspace-sword/src/main/java/org/dspace/sword/Depositor.java index 8eb5291171..b63c8d27cb 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/Depositor.java +++ b/dspace-sword/src/main/java/org/dspace/sword/Depositor.java @@ -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 - * + *

* 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; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java index 85dd99bfda..5e8b01fdfa 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ItemCollectionGenerator.java @@ -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 - * + *

* 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 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 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 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 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 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 acceptFormats = swordConfig.getAccepts(context, item); + for (String acceptFormat : acceptFormats) + { + scol.addAccepts(acceptFormat); + } - return scol; - } + return scol; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/ItemDepositor.java b/dspace-sword/src/main/java/org/dspace/sword/ItemDepositor.java index 2861bc2c7d..9a56312ca9 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ItemDepositor.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ItemDepositor.java @@ -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 - * + *

* 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 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 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 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 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); + } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java b/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java index 6d8b5831e5..1e8958f847 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ItemEntryGenerator.java @@ -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 - * + *

* 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 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 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 bundles = item.getBundles(); - for (Bundle bundle : bundles) - { - if (swordBundle.equals(bundle.getName())) { - List 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 bundles = item.getBundles(); + for (Bundle bundle : bundles) + { + if (swordBundle.equals(bundle.getName())) + { + List 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 bundles = item.getBundles(); - for (Bundle bundle : bundles) { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) { - List 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 bundles = item.getBundles(); + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) + { + List 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 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 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 bundles = item.getBundles(); - for (Bundle bundle : bundles) { + StringBuilder rightsString = new StringBuilder(); + List bundles = item.getBundles(); + for (Bundle bundle : bundles) + { if (Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName())) - { + { List 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 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 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 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 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 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 dcv = itemService + .getMetadataByMetadataString(item, config); + if (dcv != null && dcv.size() == 1) { DCDate dcd = new DCDate(dcv.get(0).getValue()); entry.setUpdated(dcd.toString()); } - } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/LoadDSpaceConfig.java b/dspace-sword/src/main/java/org/dspace/sword/LoadDSpaceConfig.java index 327dbac4ce..734476b108 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/LoadDSpaceConfig.java +++ b/dspace-sword/src/main/java/org/dspace/sword/LoadDSpaceConfig.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -14,28 +14,29 @@ import org.dspace.core.ConfigurationManager; /** * Simple servlet to load in DSpace and log4j configurations. Should always be * started up before other servlets (use ) - * + * * This class holds code to be removed in the next version of the DSpace XMLUI, * it is now managed by a Shared Context Listener inthe dspace-api project. - * + * * It is deprecated, rather than removed to maintain backward compatibility for * local DSpace 1.5.x customized overlays. - * + * * TODO: Remove in trunk * * @deprecated Use Servlet Context Listener provided in dspace-api (remove in > * 1.5.x) - * + * * @author Robert Tansley */ 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); diff --git a/dspace-sword/src/main/java/org/dspace/sword/MediaEntryManager.java b/dspace-sword/src/main/java/org/dspace/sword/MediaEntryManager.java index a456aae2e1..22953d8023 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/MediaEntryManager.java +++ b/dspace-sword/src/main/java/org/dspace/sword/MediaEntryManager.java @@ -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 - * + *

* 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; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthentication.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthentication.java index 05b141af64..995e832986 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthentication.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthentication.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -16,25 +16,26 @@ import org.dspace.authenticate.AuthenticationMethod; /** * This class offers a thin wrapper for the default DSpace * authentication module for the SWORD implementation - * + * * @author Richard Jones * */ 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; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthenticator.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthenticator.java index 2bb71705e4..d6e10d38ed 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthenticator.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDAuthenticator.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -41,71 +41,84 @@ import java.util.ArrayList; /** * This class offers a thin wrapper for the default DSpace * authentication module for the SWORD implementation - * + * * @author Richard Jones * */ public class SWORDAuthenticator { - /** logger */ - private static Logger log = Logger.getLogger(SWORDAuthenticator.class); + /** logger */ + private static Logger log = Logger.getLogger(SWORDAuthenticator.class); - protected AuthenticationService authenticationService = AuthenticateServiceFactory.getInstance().getAuthenticationService(); - protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); - protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); - protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + protected AuthenticationService authenticationService = AuthenticateServiceFactory + .getInstance().getAuthenticationService(); - /** - * 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) - { - int auth = authenticationService.authenticate(context, un, pw, null, null); - return auth == AuthenticationMethod.SUCCESS; - } + protected AuthorizeService authorizeService = AuthorizeServiceFactory + .getInstance().getAuthorizeService(); - /** - * Construct the context object member variable of this class - * using the passed IP address as part of the loggable - * information - * - * @param ip the ip address of the incoming request - * @throws org.purl.sword.base.SWORDException - */ - private Context constructContext(String ip) - throws SWORDException - { - Context context = new Context(); - // Set the session ID and IP address - context.setExtraLogInfo("session_id=0:ip_addr=" + ip); + protected EPersonService ePersonService = EPersonServiceFactory + .getInstance().getEPersonService(); - return context; - } + protected CommunityService communityService = ContentServiceFactory + .getInstance().getCommunityService(); - /** - * Authenticate the given service document request. This extracts - * the appropriate information from the request and forwards to the - * appropriate authentication method. - * - * @param request - * @throws SWORDException - * @throws SWORDErrorException - * @throws SWORDAuthenticationException - */ - public SWORDContext authenticate(ServiceDocumentRequest request) - throws SWORDException, SWORDErrorException, SWORDAuthenticationException - { - Context context = this.constructContext(request.getIPAddress()); - SWORDContext sc; - try + protected CollectionService collectionService = ContentServiceFactory + .getInstance().getCollectionService(); + + protected ItemService itemService = ContentServiceFactory.getInstance() + .getItemService(); + + /** + * 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) + { + int auth = authenticationService + .authenticate(context, un, pw, null, null); + return auth == AuthenticationMethod.SUCCESS; + } + + /** + * Construct the context object member variable of this class + * using the passed IP address as part of the loggable + * information + * + * @param ip the ip address of the incoming request + * @throws org.purl.sword.base.SWORDException + */ + private Context constructContext(String ip) + throws SWORDException + { + Context context = new Context(); + // Set the session ID and IP address + context.setExtraLogInfo("session_id=0:ip_addr=" + ip); + + return context; + } + + /** + * Authenticate the given service document request. This extracts + * the appropriate information from the request and forwards to the + * appropriate authentication method. + * + * @param request + * @throws SWORDException + * @throws SWORDErrorException + * @throws SWORDAuthenticationException + */ + public SWORDContext authenticate(ServiceDocumentRequest request) + throws SWORDException, SWORDErrorException, + SWORDAuthenticationException + { + Context context = this.constructContext(request.getIPAddress()); + SWORDContext sc; + try { sc = this.authenticate(context, request); } @@ -117,25 +130,26 @@ public class SWORDAuthenticator } throw e; } - return sc; - } + return sc; + } - /** - * Authenticate the given ATOM document request. This extracts the - * appropriate information from the request, and forwards to the - * appropriate authentication method. - * - * @param request - * @throws SWORDException - * @throws SWORDErrorException - * @throws SWORDAuthenticationException - */ - public SWORDContext authenticate(AtomDocumentRequest request) - throws SWORDException, SWORDErrorException, SWORDAuthenticationException - { - Context context = this.constructContext(request.getIPAddress()); - SWORDContext sc = null; - try + /** + * Authenticate the given ATOM document request. This extracts the + * appropriate information from the request, and forwards to the + * appropriate authentication method. + * + * @param request + * @throws SWORDException + * @throws SWORDErrorException + * @throws SWORDAuthenticationException + */ + public SWORDContext authenticate(AtomDocumentRequest request) + throws SWORDException, SWORDErrorException, + SWORDAuthenticationException + { + Context context = this.constructContext(request.getIPAddress()); + SWORDContext sc = null; + try { sc = this.authenticate(context, request); } @@ -147,58 +161,66 @@ public class SWORDAuthenticator } throw e; } - return sc; + return sc; } - /** - * Authenticate the incoming service document request. Calls: - * - * authenticatate(username, password, onBehalfOf) - * - * @param request - * @return a SWORDContext object containing the relevant users - * @throws org.purl.sword.base.SWORDAuthenticationException - * @throws SWORDException - */ - private SWORDContext authenticate(Context context, AtomDocumentRequest request) - throws SWORDAuthenticationException, SWORDException, SWORDErrorException - { - return this.authenticate(context, request.getUsername(), request.getPassword(), null, request.getIPAddress()); - } + /** + * Authenticate the incoming service document request. Calls: + * + * authenticatate(username, password, onBehalfOf) + * + * @param request + * @return a SWORDContext object containing the relevant users + * @throws org.purl.sword.base.SWORDAuthenticationException + * @throws SWORDException + */ + private SWORDContext authenticate(Context context, + AtomDocumentRequest request) + throws SWORDAuthenticationException, SWORDException, + SWORDErrorException + { + return this.authenticate(context, request.getUsername(), + request.getPassword(), null, request.getIPAddress()); + } - /** - * Authenticate the incoming service document request. Calls: - * - * authenticatate(username, password, onBehalfOf) - * - * @param request - * @return a SWORDContext object containing the relevant users - * @throws org.purl.sword.base.SWORDAuthenticationException - * @throws SWORDException - */ - private SWORDContext authenticate(Context context, ServiceDocumentRequest request) - throws SWORDAuthenticationException, SWORDException, SWORDErrorException - { - return this.authenticate(context, request.getUsername(), request.getPassword(), request.getOnBehalfOf(), request.getIPAddress()); - } + /** + * Authenticate the incoming service document request. Calls: + * + * authenticatate(username, password, onBehalfOf) + * + * @param request + * @return a SWORDContext object containing the relevant users + * @throws org.purl.sword.base.SWORDAuthenticationException + * @throws SWORDException + */ + private SWORDContext authenticate(Context context, + ServiceDocumentRequest request) + throws SWORDAuthenticationException, SWORDException, + SWORDErrorException + { + return this.authenticate(context, request.getUsername(), + request.getPassword(), request.getOnBehalfOf(), + request.getIPAddress()); + } - /** - * Authenticate the deposit request. - * - * @param deposit - * @throws SWORDException - * @throws SWORDErrorException - * @throws SWORDAuthenticationException - */ - public SWORDContext authenticate(Deposit deposit) - throws SWORDException, SWORDErrorException, SWORDAuthenticationException - { - Context context = this.constructContext(deposit.getIPAddress()); - SWORDContext sc = null; - try - { - sc = this.authenticate(context, deposit); - } + /** + * Authenticate the deposit request. + * + * @param deposit + * @throws SWORDException + * @throws SWORDErrorException + * @throws SWORDAuthenticationException + */ + public SWORDContext authenticate(Deposit deposit) + throws SWORDException, SWORDErrorException, + SWORDAuthenticationException + { + Context context = this.constructContext(deposit.getIPAddress()); + SWORDContext sc = null; + try + { + sc = this.authenticate(context, deposit); + } catch (SWORDException | SWORDErrorException | RuntimeException | SWORDAuthenticationException e) { if (context != null && context.isValid()) @@ -207,849 +229,918 @@ public class SWORDAuthenticator } throw e; } - return sc; - } - - /** - * Authenticate the incoming deposit request. Calls: - * - * authenticate(username, password, onBehalfOf) - * - * @param deposit - * @return a SWORDContext object containing the relevant users - * @throws SWORDAuthenticationException - * @throws SWORDException - */ - private SWORDContext authenticate(Context context, Deposit deposit) - throws SWORDAuthenticationException, SWORDException, SWORDErrorException - { - return this.authenticate(context, deposit.getUsername(), deposit.getPassword(), deposit.getOnBehalfOf(), deposit.getIPAddress()); - } - - /** - * Authenticate the given username/password pair, in conjunction with - * the onBehalfOf user. The rules are that the username/password pair - * must successfully authenticate the user, and the onBehalfOf user - * must exist in the user database. - * - * @param un - * @param pw - * @param obo - * @return a SWORD context holding the various user information - * @throws SWORDAuthenticationException - * @throws SWORDException - */ - private SWORDContext authenticate(Context context, String un, String pw, String obo, String ip) - throws SWORDAuthenticationException, SWORDException, SWORDErrorException - { - // smooth out the OnBehalfOf request, so that empty strings are - // treated as null - if ("".equals(obo)) - { - obo = null; - } - - // first find out if we support on-behalf-of deposit - boolean mediated = ConfigurationManager.getBooleanProperty("sword-server", "on-behalf-of.enable"); - if (!mediated && obo != null) - { - // user is trying to do a mediated deposit on a repository which does not support it - log.error("Attempted mediated deposit on service not configured to do so"); - throw new SWORDErrorException(ErrorCodes.MEDIATION_NOT_ALLOWED, "Mediated deposit to this service is not permitted"); - } - - log.info(LogManager.getHeader(context, "sword_authenticate", "username=" + un + ",on_behalf_of=" + obo)); - - try - { - // attempt to authenticate the primary user - SWORDContext sc = new SWORDContext(); - EPerson ep = null; - boolean authenticated = false; - if (this.authenticates(context, un, pw)) - { - // if authenticated, obtain the eperson object - ep = context.getCurrentUser(); - - if (ep != null) - { - authenticated = true; - sc.setAuthenticated(ep); - // Set any special groups - invoke the authentication mgr. - List groups = authenticationService.getSpecialGroups(context, null); - - for (Group group : groups) - { - context.setSpecialGroup(group.getID()); - log.debug("Adding Special Group id=" + group.getID()); - } - - sc.setAuthenticatorContext(context); - sc.setContext(context); - } - - // if there is an onBehalfOfuser, then find their eperson - // record, and if it exists set it. If not, then the - // authentication process fails - EPerson epObo = null; - if (obo != null) - { - epObo = ePersonService.findByEmail(context, obo); - if (epObo == null) - { - epObo = ePersonService.findByNetid(context, obo); - } - - if (epObo != null) - { - sc.setOnBehalfOf(epObo); - Context oboContext = this.constructContext(ip); - oboContext.setCurrentUser(epObo); - // Set any special groups - invoke the authentication mgr. - List groups = authenticationService.getSpecialGroups(oboContext, null); - - for (Group group : groups) - { - oboContext.setSpecialGroup(group.getID()); - log.debug("Adding Special Group id=" + group.getID()); - } - sc.setContext(oboContext); - } - else - { - authenticated = false; - throw new SWORDErrorException(ErrorCodes.TARGET_OWNER_UKNOWN, "unable to identify on-behalf-of user: " + obo); - } - } - } - - if (!authenticated) - { - // decide what kind of error to throw - if (ep != null) - { - log.info(LogManager.getHeader(context, "sword_unable_to_set_user", "username=" + un)); - throw new SWORDAuthenticationException("Unable to authenticate the supplied used"); - } - else - { - // FIXME: this shouldn't ever happen now, but may as well leave it in just in case - // there's a bug elsewhere - log.info(LogManager.getHeader(context, "sword_unable_to_set_on_behalf_of", "username=" + un + ",on_behalf_of=" + obo)); - throw new SWORDAuthenticationException("Unable to authenticate the onBehalfOf account"); - } - } - - return sc; - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new SWORDException("There was a problem accessing the repository user database", e); - } - } - - /** - * Can the users contained in this object's member SWORDContext - * make a successful submission to the selected collection. - * - * See javadocs for individual canSubmitTo methods to see the conditions - * which are applied in each situation - * - * @return true if yes, false if not - * @throws DSpaceSWORDException - */ - public boolean canSubmit(SWORDService swordService, Deposit deposit, DSpaceObject dso) - throws DSpaceSWORDException, SWORDErrorException - { - // get the things we need out of the service - SWORDContext swordContext = swordService.getSwordContext(); - - // determine if we can submit - boolean submit = this.canSubmitTo(swordContext, dso); - - if (submit) - { - swordService.message("User is authorised to submit to collection"); - } - else - { - swordService.message("User is not authorised to submit to collection"); - } - - return submit; - } - - /** - * Is the authenticated user a DSpace administrator? This translates - * as asking the question of whether the given eperson is a member - * of the special DSpace group Administrator, with id 1 - * - * @param swordContext - * @return true if administrator, false if not - * @throws SQLException - */ - public boolean isUserAdmin(SWORDContext swordContext) - throws DSpaceSWORDException - { - try - { - EPerson authenticated = swordContext.getAuthenticated(); - return authenticated != null && authorizeService.isAdmin(swordContext.getAuthenticatorContext()); - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Is the given onBehalfOf user DSpace administrator? This translates - * as asking the question of whether the given eperson is a member - * of the special DSpace group Administrator, with id 1 - * - * @param swordContext - * @return true if administrator, false if not - * @throws SQLException - */ - public boolean isOnBehalfOfAdmin(SWORDContext swordContext) - throws DSpaceSWORDException - { - EPerson onBehalfOf = swordContext.getOnBehalfOf(); - try - { - return onBehalfOf != null && authorizeService.isAdmin(swordContext.getOnBehalfOfContext()); - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Is the authenticated user a member of the given group - * or one of its sub groups? - * - * @param group - */ - public boolean isUserInGroup(SWORDContext swordContext, Group group) { - EPerson authenticated = swordContext.getAuthenticated(); - return authenticated != null && isInGroup(group, authenticated); - } - - /** - * Is the onBehalfOf user a member of the given group or - * one of its sub groups? - * - * @param group - */ - public boolean isOnBehalfOfInGroup(SWORDContext swordContext, Group group) { - EPerson onBehalfOf = swordContext.getOnBehalfOf(); - return onBehalfOf != null && isInGroup(group, onBehalfOf); - } - - /** - * Is the given eperson in the given group, or any of the groups - * that are also members of that group. This method recurses - * until it has exhausted the tree of groups or finds the given - * eperson - * - * @param group - * @param eperson - * @return true if in group, false if not - */ - public boolean isInGroup(Group group, EPerson eperson) - { - List eps = group.getMembers(); - List groups = group.getMemberGroups(); - - // is the user in the current group - for (EPerson ep : eps) - { - if (eperson.getID().equals(ep.getID())) - { - return true; - } - } - - // is the eperson in the sub-groups (recurse) - if (groups != null && !groups.isEmpty()) - { - for (Group group1 : groups) - { - if (isInGroup(group1, eperson)) - { - return true; - } - } - } - - // ok, we didn't find you - return false; - } - - /** - * Get an array of all the communities that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * The user may submit to a community if the following conditions - * are met: - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to READ - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public List getAllowedCommunities(SWORDContext swordContext) - throws DSpaceSWORDException - { - // a community is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - // - the authenticated user is authorised to READ - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - try - { - // locate all the top level communities - Context context = swordContext.getContext(); - List allowed = new ArrayList<>(); - List comms = communityService.findAllTop(context); - for (Community comm : comms) - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) { - oboAllowed = true; - } - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), comm, Constants.READ); - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), comm, Constants.READ); - } - - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(comm); - } - } - return allowed; - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * The user may submit to a community if the following conditions - * are met: - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to READ - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * - * @param community - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public List getCommunities(SWORDContext swordContext, Community community) - throws DSpaceSWORDException - { - // a community is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - // - the authenticated user is authorised to READ - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - try - { - List comms = community.getSubcommunities(); - List allowed = new ArrayList<>(); - - for (Community comm : comms) - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), comm, Constants.READ); - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), comm, Constants.READ); - } - - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(comm); - } - } - return allowed; - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * Forwards to: - * - * getAllowedCollections(swordContext, null) - * - * See that method for details of the conditions applied - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public List getAllowedCollections(SWORDContext swordContext) - throws DSpaceSWORDException - { - return this.getAllowedCollections(swordContext, null); - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to ADD - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public List getAllowedCollections(SWORDContext swordContext, Community community) - throws DSpaceSWORDException - { - // a collection is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD - // -- the on-behalf-of user is null - // - the authenticated user is authorised to ADD - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD - // -- the on-behalf-of user is null - - try - { - // get the context of the authenticated user - Context authContext = swordContext.getAuthenticatorContext(); - - // short cut by obtaining the collections to which the authenticated user can submit - List cols = collectionService.findAuthorized(authContext, community, Constants.ADD); - List allowed = new ArrayList<>(); - - // now find out if the obo user is allowed to submit to any of these collections - for (Collection col : cols) - { - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), col, Constants.ADD); - } - - // final check to see if we are allowed to READ - if (oboAllowed) - { - allowed.add(col); - } - } - return allowed; - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Get a list of all the items that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public List getAllowedItems(SWORDContext swordContext, org.dspace.content.Collection collection) - throws DSpaceSWORDException - { - // an item is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - - try - { - List allowed = new ArrayList<>(); - Iterator ii = itemService.findByCollection(swordContext.getContext(), collection); - - while (ii.hasNext()) - { - Item item = ii.next(); - - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // get the "ORIGINAL" bundle(s) - List bundles = item.getBundles(); - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), item, Constants.WRITE); - - boolean add = false; - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - } - - authAllowed = write && add; - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), item, Constants.WRITE); - - boolean add = false; - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - add = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - - oboAllowed = write && add; - } - - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(item); - } - } - - return allowed; - } - catch (SQLException e) - { - throw new DSpaceSWORDException(e); - } - } - - /** - * Can the current SWORD Context permit deposit into the given - * collection in the given DSpace Context? - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to ADD - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * - * @param swordContext - * @param collection - * @throws DSpaceSWORDException - */ - public boolean canSubmitTo(SWORDContext swordContext, org.dspace.content.Collection collection) - throws DSpaceSWORDException - { - // a user can submit to a collection in the following conditions: - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD/in the submission group - // -- the on-behalf-of user is null - // - the authenticated user is authorised to ADD/in the submission group - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD/in the submission group - // -- the on-behalf-of user is null - - try - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // look up the READ policy on the collection. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), collection, Constants.ADD); - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), collection, Constants.ADD); - } - - // final check to see if we are allowed to READ - return (authAllowed && oboAllowed); - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Does the given context have the authority to submit to the given item. - * - * The context has permission of the following conditions are met: - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSWORDException - */ - public boolean canSubmitTo(SWORDContext swordContext, Item item) - throws DSpaceSWORDException - { - // a user can submit to a collection in the following conditions: - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - - try - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // get the "ORIGINAL" bundle(s) - List bundles = item.getBundles(); - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), item, Constants.WRITE); - - boolean add = false; - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - } - - authAllowed = write && add; - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), item, Constants.WRITE); - - boolean add = false; - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - } - - oboAllowed = write && add; - } - - // final check to see if we are allowed to READ - return (authAllowed && oboAllowed); - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSWORDException(e); - } - } - - /** - * Can the given context submit to the specified dspace object. - * - * This forwards to the individual methods for different object types; see - * their documentation for details of the conditions. - * - * @param context - * @param dso - * @throws DSpaceSWORDException - */ - public boolean canSubmitTo(SWORDContext context, DSpaceObject dso) - throws DSpaceSWORDException - { - if (dso instanceof org.dspace.content.Collection) - { - return this.canSubmitTo(context, (org.dspace.content.Collection) dso); - } - else - { - return dso instanceof Item && this.canSubmitTo(context, (Item) dso); - } - } + return sc; + } + + /** + * Authenticate the incoming deposit request. Calls: + * + * authenticate(username, password, onBehalfOf) + * + * @param deposit + * @return a SWORDContext object containing the relevant users + * @throws SWORDAuthenticationException + * @throws SWORDException + */ + private SWORDContext authenticate(Context context, Deposit deposit) + throws SWORDAuthenticationException, SWORDException, + SWORDErrorException + { + return this.authenticate(context, deposit.getUsername(), + deposit.getPassword(), deposit.getOnBehalfOf(), + deposit.getIPAddress()); + } + + /** + * Authenticate the given username/password pair, in conjunction with + * the onBehalfOf user. The rules are that the username/password pair + * must successfully authenticate the user, and the onBehalfOf user + * must exist in the user database. + * + * @param un + * @param pw + * @param obo + * @return a SWORD context holding the various user information + * @throws SWORDAuthenticationException + * @throws SWORDException + */ + private SWORDContext authenticate(Context context, String un, String pw, + String obo, String ip) + throws SWORDAuthenticationException, SWORDException, + SWORDErrorException + { + // smooth out the OnBehalfOf request, so that empty strings are + // treated as null + if ("".equals(obo)) + { + obo = null; + } + + // first find out if we support on-behalf-of deposit + boolean mediated = ConfigurationManager + .getBooleanProperty("sword-server", "on-behalf-of.enable"); + if (!mediated && obo != null) + { + // user is trying to do a mediated deposit on a repository which does not support it + log.error( + "Attempted mediated deposit on service not configured to do so"); + throw new SWORDErrorException(ErrorCodes.MEDIATION_NOT_ALLOWED, + "Mediated deposit to this service is not permitted"); + } + + log.info(LogManager.getHeader(context, "sword_authenticate", + "username=" + un + ",on_behalf_of=" + obo)); + + try + { + // attempt to authenticate the primary user + SWORDContext sc = new SWORDContext(); + EPerson ep = null; + boolean authenticated = false; + if (this.authenticates(context, un, pw)) + { + // if authenticated, obtain the eperson object + ep = context.getCurrentUser(); + + if (ep != null) + { + authenticated = true; + sc.setAuthenticated(ep); + // Set any special groups - invoke the authentication mgr. + List groups = authenticationService + .getSpecialGroups(context, null); + + for (Group group : groups) + { + context.setSpecialGroup(group.getID()); + log.debug("Adding Special Group id=" + group.getID()); + } + + sc.setAuthenticatorContext(context); + sc.setContext(context); + } + + // if there is an onBehalfOfuser, then find their eperson + // record, and if it exists set it. If not, then the + // authentication process fails + EPerson epObo = null; + if (obo != null) + { + epObo = ePersonService.findByEmail(context, obo); + if (epObo == null) + { + epObo = ePersonService.findByNetid(context, obo); + } + + if (epObo != null) + { + sc.setOnBehalfOf(epObo); + Context oboContext = this.constructContext(ip); + oboContext.setCurrentUser(epObo); + // Set any special groups - invoke the authentication mgr. + List groups = authenticationService + .getSpecialGroups(oboContext, null); + + for (Group group : groups) + { + oboContext.setSpecialGroup(group.getID()); + log.debug( + "Adding Special Group id=" + group.getID()); + } + sc.setContext(oboContext); + } + else + { + authenticated = false; + throw new SWORDErrorException( + ErrorCodes.TARGET_OWNER_UKNOWN, + "unable to identify on-behalf-of user: " + obo); + } + } + } + + if (!authenticated) + { + // decide what kind of error to throw + if (ep != null) + { + log.info(LogManager + .getHeader(context, "sword_unable_to_set_user", + "username=" + un)); + throw new SWORDAuthenticationException( + "Unable to authenticate the supplied used"); + } + else + { + // FIXME: this shouldn't ever happen now, but may as well leave it in just in case + // there's a bug elsewhere + log.info(LogManager.getHeader(context, + "sword_unable_to_set_on_behalf_of", + "username=" + un + ",on_behalf_of=" + obo)); + throw new SWORDAuthenticationException( + "Unable to authenticate the onBehalfOf account"); + } + } + + return sc; + } + catch (SQLException e) + { + log.error("caught exception: ", e); + throw new SWORDException( + "There was a problem accessing the repository user database", + e); + } + } + + /** + * Can the users contained in this object's member SWORDContext + * make a successful submission to the selected collection. + * + * See javadocs for individual canSubmitTo methods to see the conditions + * which are applied in each situation + * + * @return true if yes, false if not + * @throws DSpaceSWORDException + */ + public boolean canSubmit(SWORDService swordService, Deposit deposit, + DSpaceObject dso) + throws DSpaceSWORDException, SWORDErrorException + { + // get the things we need out of the service + SWORDContext swordContext = swordService.getSwordContext(); + + // determine if we can submit + boolean submit = this.canSubmitTo(swordContext, dso); + + if (submit) + { + swordService.message("User is authorised to submit to collection"); + } + else + { + swordService + .message("User is not authorised to submit to collection"); + } + + return submit; + } + + /** + * Is the authenticated user a DSpace administrator? This translates + * as asking the question of whether the given eperson is a member + * of the special DSpace group Administrator, with id 1 + * + * @param swordContext + * @return true if administrator, false if not + * @throws SQLException + */ + public boolean isUserAdmin(SWORDContext swordContext) + throws DSpaceSWORDException + { + try + { + EPerson authenticated = swordContext.getAuthenticated(); + return authenticated != null && authorizeService + .isAdmin(swordContext.getAuthenticatorContext()); + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Is the given onBehalfOf user DSpace administrator? This translates + * as asking the question of whether the given eperson is a member + * of the special DSpace group Administrator, with id 1 + * + * @param swordContext + * @return true if administrator, false if not + * @throws SQLException + */ + public boolean isOnBehalfOfAdmin(SWORDContext swordContext) + throws DSpaceSWORDException + { + EPerson onBehalfOf = swordContext.getOnBehalfOf(); + try + { + return onBehalfOf != null && authorizeService + .isAdmin(swordContext.getOnBehalfOfContext()); + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Is the authenticated user a member of the given group + * or one of its sub groups? + * + * @param group + */ + public boolean isUserInGroup(SWORDContext swordContext, Group group) + { + EPerson authenticated = swordContext.getAuthenticated(); + return authenticated != null && isInGroup(group, authenticated); + } + + /** + * Is the onBehalfOf user a member of the given group or + * one of its sub groups? + * + * @param group + */ + public boolean isOnBehalfOfInGroup(SWORDContext swordContext, Group group) + { + EPerson onBehalfOf = swordContext.getOnBehalfOf(); + return onBehalfOf != null && isInGroup(group, onBehalfOf); + } + + /** + * Is the given eperson in the given group, or any of the groups + * that are also members of that group. This method recurses + * until it has exhausted the tree of groups or finds the given + * eperson + * + * @param group + * @param eperson + * @return true if in group, false if not + */ + public boolean isInGroup(Group group, EPerson eperson) + { + List eps = group.getMembers(); + List groups = group.getMemberGroups(); + + // is the user in the current group + for (EPerson ep : eps) + { + if (eperson.getID().equals(ep.getID())) + { + return true; + } + } + + // is the eperson in the sub-groups (recurse) + if (groups != null && !groups.isEmpty()) + { + for (Group group1 : groups) + { + if (isInGroup(group1, eperson)) + { + return true; + } + } + } + + // ok, we didn't find you + return false; + } + + /** + * Get an array of all the communities that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * The user may submit to a community if the following conditions + * are met: + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to READ + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public List getAllowedCommunities(SWORDContext swordContext) + throws DSpaceSWORDException + { + // a community is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + // - the authenticated user is authorised to READ + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + try + { + // locate all the top level communities + Context context = swordContext.getContext(); + List allowed = new ArrayList<>(); + List comms = communityService.findAllTop(context); + for (Community comm : comms) + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), comm, + Constants.READ); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), comm, + Constants.READ); + } + + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(comm); + } + } + return allowed; + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * The user may submit to a community if the following conditions + * are met: + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to READ + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * + * @param community + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public List getCommunities(SWORDContext swordContext, + Community community) + throws DSpaceSWORDException + { + // a community is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + // - the authenticated user is authorised to READ + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + try + { + List comms = community.getSubcommunities(); + List allowed = new ArrayList<>(); + + for (Community comm : comms) + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), comm, + Constants.READ); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), comm, + Constants.READ); + } + + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(comm); + } + } + return allowed; + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * Forwards to: + * + * getAllowedCollections(swordContext, null) + * + * See that method for details of the conditions applied + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public List getAllowedCollections( + SWORDContext swordContext) + throws DSpaceSWORDException + { + return this.getAllowedCollections(swordContext, null); + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to ADD + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public List getAllowedCollections( + SWORDContext swordContext, Community community) + throws DSpaceSWORDException + { + // a collection is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD + // -- the on-behalf-of user is null + // - the authenticated user is authorised to ADD + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD + // -- the on-behalf-of user is null + + try + { + // get the context of the authenticated user + Context authContext = swordContext.getAuthenticatorContext(); + + // short cut by obtaining the collections to which the authenticated user can submit + List cols = collectionService + .findAuthorized(authContext, community, Constants.ADD); + List allowed = new ArrayList<>(); + + // now find out if the obo user is allowed to submit to any of these collections + for (Collection col : cols) + { + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), col, + Constants.ADD); + } + + // final check to see if we are allowed to READ + if (oboAllowed) + { + allowed.add(col); + } + } + return allowed; + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Get a list of all the items that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public List getAllowedItems(SWORDContext swordContext, + org.dspace.content.Collection collection) + throws DSpaceSWORDException + { + // an item is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + + try + { + List allowed = new ArrayList<>(); + Iterator ii = itemService + .findByCollection(swordContext.getContext(), collection); + + while (ii.hasNext()) + { + Item item = ii.next(); + + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // get the "ORIGINAL" bundle(s) + List bundles = item.getBundles(); + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), item, + Constants.WRITE); + + boolean add = false; + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME + .equals(bundle.getName())) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), + bundle, Constants.ADD); + if (!add) + { + break; + } + } + } + + authAllowed = write && add; + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), item, + Constants.WRITE); + + boolean add = false; + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME + .equals(bundle.getName())) + add = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), bundle, + Constants.ADD); + if (!add) + { + break; + } + } + + oboAllowed = write && add; + } + + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(item); + } + } + + return allowed; + } + catch (SQLException e) + { + throw new DSpaceSWORDException(e); + } + } + + /** + * Can the current SWORD Context permit deposit into the given + * collection in the given DSpace Context? + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to ADD + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * + * @param swordContext + * @param collection + * @throws DSpaceSWORDException + */ + public boolean canSubmitTo(SWORDContext swordContext, + org.dspace.content.Collection collection) + throws DSpaceSWORDException + { + // a user can submit to a collection in the following conditions: + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD/in the submission group + // -- the on-behalf-of user is null + // - the authenticated user is authorised to ADD/in the submission group + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD/in the submission group + // -- the on-behalf-of user is null + + try + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // look up the READ policy on the collection. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), collection, + Constants.ADD); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), collection, + Constants.ADD); + } + + // final check to see if we are allowed to READ + return (authAllowed && oboAllowed); + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Does the given context have the authority to submit to the given item. + * + * The context has permission of the following conditions are met: + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSWORDException + */ + public boolean canSubmitTo(SWORDContext swordContext, Item item) + throws DSpaceSWORDException + { + // a user can submit to a collection in the following conditions: + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + + try + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // get the "ORIGINAL" bundle(s) + List bundles = item.getBundles(); + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), item, + Constants.WRITE); + + boolean add = false; + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), bundle, + Constants.ADD); + if (!add) + { + break; + } + } + } + + authAllowed = write && add; + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), item, + Constants.WRITE); + + boolean add = false; + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), bundle, + Constants.ADD); + if (!add) + { + break; + } + } + } + + oboAllowed = write && add; + } + + // final check to see if we are allowed to READ + return (authAllowed && oboAllowed); + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSWORDException(e); + } + } + + /** + * Can the given context submit to the specified dspace object. + * + * This forwards to the individual methods for different object types; see + * their documentation for details of the conditions. + * + * @param context + * @param dso + * @throws DSpaceSWORDException + */ + public boolean canSubmitTo(SWORDContext context, DSpaceObject dso) + throws DSpaceSWORDException + { + if (dso instanceof org.dspace.content.Collection) + { + return this + .canSubmitTo(context, (org.dspace.content.Collection) dso); + } + else + { + return dso instanceof Item && this.canSubmitTo(context, (Item) dso); + } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDConfiguration.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDConfiguration.java index 2691387164..ef718d8997 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDConfiguration.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDConfiguration.java @@ -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 - * + *

* 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"; - - /** 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; + /** 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; + + /** location of directory to store packages on ingest error */ + private String failedPackageDir = null; /** Accepted formats */ private List 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(); 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; - } - - /** - * 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; - } + * Get the bundle name that SWORD will store its original deposit + * packages in, when storing them inside an item. + */ + public String getSwordBundle() + { + return swordBundle; + } - /** - * Get the list of mime types that the given dspace object will - * accept as packages. - * - * @param context - * @param dso - * @throws DSpaceSWORDException - */ - public List getAccepts(Context context, DSpaceObject dso) - throws DSpaceSWORDException - { - try - { - List accepts = new ArrayList(); - if (dso instanceof Collection) - { - for (String format : swordaccepts) + /** + * 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; + } + + /** + * 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; + } + + /** + * Get the list of mime types that the given dspace object will + * accept as packages. + * + * @param context + * @param dso + * @throws DSpaceSWORDException + */ + public List getAccepts(Context context, DSpaceObject dso) + throws DSpaceSWORDException + { + try + { + List accepts = new ArrayList(); + if (dso instanceof Collection) + { + for (String format : swordaccepts) { accepts.add(format); } - } - else if (dso instanceof Item) - { - List bfs = bitstreamFormatService.findNonInternal(context); - for (BitstreamFormat bf : bfs) { - accepts.add(bf.getMIMEType()); - } - } + } + else if (dso instanceof Item) + { + List 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 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 getCollectionAccepts() throws DSpaceSWORDException + { List accepts = new ArrayList(); 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 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 getAcceptPackaging(Collection col) { Map identifiers = new HashMap(); Map qs = new HashMap(); - 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 ap = new HashMap(); - 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 ap = new HashMap(); + 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 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 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 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 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"); + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDContext.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDContext.java index 1b850a3dfd..a5fc9e9daa 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDContext.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDContext.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -31,157 +31,157 @@ import org.dspace.eperson.EPerson; * * and not from any of the other context retrieval methods in this * class - * + * * @author Richard Jones * */ -public class SWORDContext +public class SWORDContext { - /** The primary authenticated user for the request */ - private EPerson authenticated = null; - - /** The onBehalfOf user for the request */ - private EPerson onBehalfOf = null; + /** The primary authenticated user for the request */ + private EPerson authenticated = null; - /** The primary context, representing the on behalf of user if exists, and the authenticated user if not */ - private Context context; + /** The onBehalfOf user for the request */ + private EPerson onBehalfOf = null; - /** the context for the authenticated user, which may not, therefore, be the primary context also */ - private Context authenticatorContext; + /** The primary context, representing the on behalf of user if exists, and the authenticated user if not */ + private Context context; - /** - * @return the authenticated user - */ - public EPerson getAuthenticated() - { - return authenticated; - } + /** the context for the authenticated user, which may not, therefore, be the primary context also */ + private Context authenticatorContext; - /** - * @param authenticated the eperson to set - */ - public void setAuthenticated(EPerson authenticated) - { - this.authenticated = authenticated; - } + /** + * @return the authenticated user + */ + public EPerson getAuthenticated() + { + return authenticated; + } - /** - * @return the onBehalfOf user - */ - public EPerson getOnBehalfOf() - { - return onBehalfOf; - } + /** + * @param authenticated the eperson to set + */ + public void setAuthenticated(EPerson authenticated) + { + this.authenticated = authenticated; + } - /** - * @param onBehalfOf the eperson to set - */ - public void setOnBehalfOf(EPerson onBehalfOf) - { - this.onBehalfOf = onBehalfOf; - } + /** + * @return the onBehalfOf user + */ + public EPerson getOnBehalfOf() + { + return 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; - } + /** + * @param onBehalfOf the eperson to set + */ + public void setOnBehalfOf(EPerson onBehalfOf) + { + this.onBehalfOf = onBehalfOf; + } - public void setContext(Context context) - { - this.context = 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; + } - /** - * 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 setContext(Context context) + { + this.context = context; + } - public void setAuthenticatorContext(Context authenticatorContext) - { - this.authenticatorContext = 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; + } - /** - * 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; - } + public void setAuthenticatorContext(Context authenticatorContext) + { + this.authenticatorContext = authenticatorContext; + } - /** - * 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(); - } + /** + * 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; + } - if (authenticatorContext != null && authenticatorContext.isValid()) - { - authenticatorContext.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(); + } - /** - * 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(); - } + if (authenticatorContext != null && authenticatorContext.isValid()) + { + authenticatorContext.abort(); + } + } - // 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); - } - } + /** + * 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); + } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDIngester.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDIngester.java index 0993d1f2c1..8ff203e38e 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDIngester.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDIngester.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -16,19 +16,21 @@ import org.purl.sword.base.SWORDErrorException; * Interface behind which can be implemented ingest mechanisms * for SWORD deposit requests. Instances of this class should * be obtained via the SWORDIngesterFactory class. - * + * * @author Richard Jones * */ 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; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDIngesterFactory.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDIngesterFactory.java index ef6a2bd2d0..23860b01b7 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDIngesterFactory.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDIngesterFactory.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -20,48 +20,56 @@ import org.purl.sword.base.ErrorCodes; /** * Factory class which will mint objects conforming to the * SWORDIngester interface. - * + * * @author Richard Jones * */ 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"); + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDMETSIngester.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDMETSIngester.java index 47f41b3bb4..4d708d8c3a 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDMETSIngester.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDMETSIngester.java @@ -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 - * + *

* 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); - - PackageIngester pi = (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, cfg); - swordService.message("Loaded package ingester: " + pi.getClass().getName()); - - // 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(); + // 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 + } + swordService.message("Using package manifest format: " + cfg); + + PackageIngester pi = (PackageIngester) PluginManager + .getNamedPlugin(PackageIngester.class, cfg); + swordService.message( + "Loaded package ingester: " + pi.getClass().getName()); + + // 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)); - - // 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"); - } - - // 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); - - // 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(); - - // 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)"); - } - - DepositResult dr = new DepositResult(); - dr.setItem(installedItem); - dr.setHandle(handle); - dr.setTreatment(this.getTreatment()); - - return dr; - } + 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"); + } + + //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; + + // 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()); + + // 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); + + 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()); + + 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"); - } - - /** - * 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"); - } + swordService.message( + "Updated date added to response from item metadata where available"); + } - 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); - } + /** + * 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; + } - 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; - - StringTokenizer stz = new StringTokenizer(config, "."); - mfi.schema = stz.nextToken(); - mfi.element = stz.nextToken(); - if (stz.hasMoreTokens()) - { - mfi.qualifier = stz.nextToken(); - } - - return mfi; - } + 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"); + } - /** - * 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."; - } + 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); + } - private class MetadataFieldInfo { - private String schema; - private String element; - private String qualifier; - } + 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; + + StringTokenizer stz = new StringTokenizer(config, "."); + mfi.schema = stz.nextToken(); + mfi.element = stz.nextToken(); + if (stz.hasMoreTokens()) + { + mfi.qualifier = stz.nextToken(); + } + + 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."; + } + + private class MetadataFieldInfo + { + private String schema; + + private String element; + + private String qualifier; + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDProperties.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDProperties.java index ce26394d5a..c3a405f264 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDProperties.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDProperties.java @@ -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 - * + *

* 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"; } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDService.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDService.java index 639e26d4aa..e7030facba 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDService.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDService.java @@ -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 - * + *

* 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 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 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(); + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/SWORDUrlManager.java b/dspace-sword/src/main/java/org/dspace/sword/SWORDUrlManager.java index 55301bb8c6..542217c54a 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SWORDUrlManager.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SWORDUrlManager.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword; @@ -31,530 +31,559 @@ import java.util.List; */ public class SWORDUrlManager { - /** the sword configuration */ - private SWORDConfiguration config; + /** the sword configuration */ + private SWORDConfiguration config; - /** the active dspace context */ - private Context context; - protected HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); - protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService(); + /** the active dspace context */ + private Context context; - public SWORDUrlManager(SWORDConfiguration config, Context context) - { - this.config = config; - this.context = context; - } + protected HandleService handleService = HandleServiceFactory.getInstance() + .getHandleService(); - /** - * Get the generator URL for ATOM entry documents. This can be - * overridden from the default in configuration. - */ - public String getGeneratorUrl() - { - String cfg = ConfigurationManager.getProperty("sword-server", "generator.url"); - if (cfg == null || "".equals(cfg)) - { - return SWORDProperties.SOFTWARE_URI; - } - return cfg; - } + protected BitstreamService bitstreamService = ContentServiceFactory + .getInstance().getBitstreamService(); - /** - * 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.getBaseDepositUrl() + "/" + collection.getHandle(); - } + public SWORDUrlManager(SWORDConfiguration config, Context context) + { + this.config = config; + this.context = context; + } - /** - * Obtain the deposit URL for the given item. These URLs - * should not be considered persistent, but will remain consistent - * unless configuration changes are made to DSpace - * - * @param item - * @return The Deposit URL - * @throws DSpaceSWORDException - */ - public String getDepositLocation(Item item) - throws DSpaceSWORDException - { - return this.getBaseDepositUrl() + "/" + item.getHandle(); - } + /** + * Get the generator URL for ATOM entry documents. This can be + * overridden from the default in configuration. + */ + public String getGeneratorUrl() + { + String cfg = ConfigurationManager + .getProperty("sword-server", "generator.url"); + if (cfg == null || "".equals(cfg)) + { + return SWORDProperties.SOFTWARE_URI; + } + return cfg; + } - /** - * 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 - { - // FIXME: there is no deposit url for communities yet, so this could - // be misleading - return this.getBaseDepositUrl() + "/" + community.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 getDepositLocation(Collection collection) + throws DSpaceSWORDException + { + return this.getBaseDepositUrl() + "/" + 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 - */ - // 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, SWORDErrorException - { - try - { - String baseUrl = this.getBaseDepositUrl(); - if (baseUrl.length() == location.length()) - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.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 SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, "The deposit URL is incomplete"); - } + /** + * Obtain the deposit URL for the given item. These URLs + * should not be considered persistent, but will remain consistent + * unless configuration changes are made to DSpace + * + * @param item + * @return The Deposit URL + * @throws DSpaceSWORDException + */ + public String getDepositLocation(Item item) + throws DSpaceSWORDException + { + return this.getBaseDepositUrl() + "/" + item.getHandle(); + } - DSpaceObject dso = handleService.resolveToObject(context, handle); + /** + * 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 + { + // FIXME: there is no deposit url for communities yet, so this could + // be misleading + return this.getBaseDepositUrl() + "/" + community.getHandle(); + } - if (!(dso instanceof Collection)) - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, "The deposit URL does not resolve to a valid collection"); - } + /** + * 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, SWORDErrorException + { + try + { + String baseUrl = this.getBaseDepositUrl(); + if (baseUrl.length() == location.length()) + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.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 SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, + "The deposit URL is incomplete"); + } - return (Collection) dso; - } - catch (SQLException e) - { - // log.error("Caught exception:", e); - throw new DSpaceSWORDException("There was a problem resolving the collection", e); - } - } + DSpaceObject dso = handleService.resolveToObject(context, handle); - /** - * 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 DSpaceObject getDSpaceObject(Context context, String location) - throws DSpaceSWORDException, SWORDErrorException - { - try - { - String baseUrl = this.getBaseDepositUrl(); - if (baseUrl.length() == location.length()) - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.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 SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, "The deposit URL is incomplete"); - } + if (!(dso instanceof Collection)) + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, + "The deposit URL does not resolve to a valid collection"); + } - DSpaceObject dso = handleService.resolveToObject(context, handle); + return (Collection) dso; + } + catch (SQLException e) + { + // log.error("Caught exception:", e); + throw new DSpaceSWORDException( + "There was a problem resolving the collection", e); + } + } - if (!(dso instanceof Collection) && !(dso instanceof Item)) - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, "The deposit URL does not resolve to a valid deposit target"); - } + /** + * 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 DSpaceObject getDSpaceObject(Context context, String location) + throws DSpaceSWORDException, SWORDErrorException + { + try + { + String baseUrl = this.getBaseDepositUrl(); + if (baseUrl.length() == location.length()) + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.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 SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, + "The deposit URL is incomplete"); + } - return dso; - } - catch (SQLException e) - { - // log.error("Caught exception:", e); - throw new DSpaceSWORDException("There was a problem resolving the collection", e); - } - } + DSpaceObject dso = handleService.resolveToObject(context, 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; - } + if (!(dso instanceof Collection) && !(dso instanceof Item)) + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, + "The deposit URL does not resolve to a valid deposit target"); + } - /** - * 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; - } + return dso; + } + catch (SQLException e) + { + // log.error("Caught exception:", e); + throw new DSpaceSWORDException( + "There was a problem resolving the collection", e); + } + } - /** - * 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 SWORDErrorException - */ - public DSpaceObject extractDSpaceObject(String url) - throws DSpaceSWORDException, SWORDErrorException - { - try - { - String sdBase = this.getBaseServiceDocumentUrl(); - String mlBase = this.getBaseMediaLinkUrl(); + /** + * 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; + } - 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); - } + /** + * 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; + } - DSpaceObject dso = handleService.resolveToObject(context, url); - if (dso instanceof Collection || dso instanceof Community) - { - return dso; - } - else - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, - "Service Document request does not refer to a DSpace Collection or Community"); - } - } - else if (url.startsWith(mlBase)) - { - // we are dealing with a bitstream media link + /** + * 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 SWORDErrorException + */ + public DSpaceObject extractDSpaceObject(String url) + throws DSpaceSWORDException, SWORDErrorException + { + try + { + String sdBase = this.getBaseServiceDocumentUrl(); + String mlBase = this.getBaseMediaLinkUrl(); - // find the index of the "/bitstream/" segment of the url - int bsi = url.indexOf("/bitstream/"); + if (url.startsWith(sdBase)) + { + // we are dealing with a service document request - // subtsring the url from the end of this "/bitstream/" string, to get the bitstream id - String bsid = url.substring(bsi + 11); + // 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); + } - // strip off extraneous slashes - if (bsid.endsWith("/")) - { - bsid = bsid.substring(0, url.length() - 1); - } - return bitstreamService.findByIdOrLegacyId(context, bsid); - } - else - { - throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, - "Unable to recognise URL as a valid service document: " + url); - } - } - catch (SQLException e) - { - throw new DSpaceSWORDException(e); - } - } + DSpaceObject dso = handleService.resolveToObject(context, url); + if (dso instanceof Collection || dso instanceof Community) + { + return dso; + } + else + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.BAD_URL, + "Service Document request does not refer to a DSpace Collection or Community"); + } + } + else if (url.startsWith(mlBase)) + { + // we are dealing with a bitstream media link - /** - * Get the base URL for service document requests. - * - * @throws DSpaceSWORDException - */ - public String getBaseServiceDocumentUrl() - throws DSpaceSWORDException - { - String depositUrl = ConfigurationManager.getProperty("sword-server", "servicedocument.url"); - if (depositUrl == null || "".equals(depositUrl)) - { - 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 sword.servicedocument.url and/or dspace.baseUrl"); - } + // find the index of the "/bitstream/" segment of the url + int bsi = url.indexOf("/bitstream/"); + + // subtsring the url from the end of this "/bitstream/" string, to get the bitstream id + String bsid = url.substring(bsi + 11); + + // strip off extraneous slashes + if (bsid.endsWith("/")) + { + bsid = bsid.substring(0, url.length() - 1); + } + return bitstreamService.findByIdOrLegacyId(context, bsid); + } + else + { + throw new SWORDErrorException(DSpaceSWORDErrorCodes.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 depositUrl = ConfigurationManager + .getProperty("sword-server", "servicedocument.url"); + if (depositUrl == null || "".equals(depositUrl)) + { + 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 sword.servicedocument.url and/or dspace.baseUrl"); + } try { URL url = new URL(dspaceUrl); - depositUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/sword/servicedocument").toString(); + depositUrl = new URL(url.getProtocol(), url.getHost(), + url.getPort(), "/sword/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 depositUrl; + } - } - return depositUrl; - } - - /** - * 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 getBaseDepositUrl() - 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 + */ + public String getBaseDepositUrl() + 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; - } + /** + * 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); - } + /** + * Is the given URL the base media link URL? + * + * @param url + * @throws DSpaceSWORDException + */ + public boolean isBaseMediaLinkUrl(String url) + throws DSpaceSWORDException + { + return this.getBaseMediaLinkUrl().equals(url); + } - /** - * Is the given URL the base media link URL? - * - * @param url - * @throws DSpaceSWORDException - */ - public boolean isBaseMediaLinkUrl(String url) - throws DSpaceSWORDException - { - return this.getBaseMediaLinkUrl().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 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 bundles = bitstream.getBundles(); - Bundle parent = null; - if (!bundles.isEmpty()) - { - parent = bundles.get(0).getBundle(); - } - else - { - throw new DSpaceSWORDException("Encountered orphaned bitstream"); - } + List items = parent.getItems(); + Item item; + if (!items.isEmpty()) + { + item = items.get(0); + } + else + { + throw new DSpaceSWORDException("Encountered orphaned bundle"); + } - List 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(); + } - if (handle != null && !"".equals(handle)) - { - bsLink = bsLink + "/bitstream/" + handle + "/" + bitstream.getSequenceID() + "/" + bitstream.getName(); - } - else - { - bsLink = bsLink + "/retrieve/" + bitstream.getID(); - } + return bsLink; + } + catch (SQLException e) + { + throw new DSpaceSWORDException(e); + } + } - return bsLink; - } - catch (SQLException e) - { - throw new DSpaceSWORDException(e); - } - } - - /** - * Get the base media link url. - * - * @throws DSpaceSWORDException - */ - public String getBaseMediaLinkUrl() - throws DSpaceSWORDException - { - String mlUrl = ConfigurationManager.getProperty("sword-server", "media-link.url"); - if (StringUtils.isBlank(mlUrl)) - { - String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl"); - if (dspaceUrl == null || "".equals(dspaceUrl)) - { - throw new DSpaceSWORDException("Unable to construct media-link urls, due to missing/invalid config in " + - "media-link.url and/or dspace.baseUrl"); - } + /** + * Get the base media link url. + * + * @throws DSpaceSWORDException + */ + public String getBaseMediaLinkUrl() + throws DSpaceSWORDException + { + String mlUrl = ConfigurationManager + .getProperty("sword-server", "media-link.url"); + if (StringUtils.isBlank(mlUrl)) + { + String dspaceUrl = ConfigurationManager + .getProperty("dspace.baseUrl"); + if (dspaceUrl == null || "".equals(dspaceUrl)) + { + throw new DSpaceSWORDException( + "Unable to construct media-link urls, due to missing/invalid config in " + + "media-link.url and/or dspace.baseUrl"); + } try { URL url = new URL(dspaceUrl); - mlUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/sword/media-link").toString(); + mlUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), + "/sword/media-link").toString(); } catch (MalformedURLException e) { - throw new DSpaceSWORDException("Unable to construct media-link urls, due to invalid dspace.baseUrl " + - e.getMessage(),e); + throw new DSpaceSWORDException( + "Unable to construct media-link urls, due to invalid dspace.baseUrl " + + e.getMessage(), e); } + } + return mlUrl; + } - } - return mlUrl; - } + /** + * get the media link url for the given item + * + * @param dso + * @return + * @throws DSpaceSWORDException + */ + private String getMediaLink(Item dso) + throws DSpaceSWORDException + { + String ml = this.getBaseMediaLinkUrl(); + String handle = dso.getHandle(); + if (handle != null) + { + ml = ml + "/" + dso.getHandle(); + } + return ml; + } - /** - * get the media link url for the given item - * - * @param dso - * @return - * @throws DSpaceSWORDException - */ - private String getMediaLink(Item dso) - throws DSpaceSWORDException - { - String ml = this.getBaseMediaLinkUrl(); - String handle = dso.getHandle(); - if (handle != null) - { - ml = ml + "/" + dso.getHandle(); - } - return ml; - } + /** + * Get the media link URL for the given bitstream. + * + * @param bitstream + * @throws DSpaceSWORDException + */ + public String getMediaLink(Bitstream bitstream) + throws DSpaceSWORDException + { + try + { + List bundles = bitstream.getBundles(); + Bundle parent = null; + if (!bundles.isEmpty()) + { + parent = bundles.get(0).getBundle(); + } + else + { + throw new DSpaceSWORDException( + "Encountered orphaned bitstream"); + } - /** - * Get the media link URL for the given bitstream. - * - * @param bitstream - * @throws DSpaceSWORDException - */ - public String getMediaLink(Bitstream bitstream) - throws DSpaceSWORDException - { - try - { - List bundles = bitstream.getBundles(); - Bundle parent = null; - if (!bundles.isEmpty()) - { - parent = bundles.get(0).getBundle(); - } - else - { - throw new DSpaceSWORDException("Encountered orphaned bitstream"); - } + List items = parent.getItems(); + Item item; + if (!items.isEmpty()) + { + item = items.get(0); + } + else + { + throw new DSpaceSWORDException("Encountered orphaned bundle"); + } - List items = parent.getItems(); - Item item; - if (!items.isEmpty()) - { - item = items.get(0); - } - else - { - throw new DSpaceSWORDException("Encountered orphaned bundle"); - } + String itemUrl = this.getMediaLink(item); + if (itemUrl.equals(this.getBaseMediaLinkUrl())) + { + return itemUrl; + } - String itemUrl = this.getMediaLink(item); - if (itemUrl.equals(this.getBaseMediaLinkUrl())) - { - return itemUrl; - } - - return itemUrl + "/bitstream/" + bitstream.getID(); - } - catch (SQLException e) - { - throw new DSpaceSWORDException(e); - } - } + return itemUrl + "/bitstream/" + bitstream.getID(); + } + catch (SQLException e) + { + throw new DSpaceSWORDException(e); + } + } } diff --git a/dspace-sword/src/main/java/org/dspace/sword/ServiceDocumentManager.java b/dspace-sword/src/main/java/org/dspace/sword/ServiceDocumentManager.java index 532f74e155..8ee7a1f5a3 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/ServiceDocumentManager.java +++ b/dspace-sword/src/main/java/org/dspace/sword/ServiceDocumentManager.java @@ -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 - * + *

* 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 comms = swordAuth.getAllowedCommunities(swordContext); - for (Community comm : comms) - { - org.purl.sword.base.Collection scol = comGen.buildCollection(comm); - workspace.addCollection(scol); - } - } - else - { - List cols = swordAuth.getAllowedCollections(swordContext); - for (Collection col : cols) - { - org.purl.sword.base.Collection scol = colGen.buildCollection(col); - workspace.addCollection(scol); - } - } + if (swordCommunities) + { + List comms = swordAuth + .getAllowedCommunities(swordContext); + for (Community comm : comms) + { + org.purl.sword.base.Collection scol = comGen + .buildCollection(comm); + workspace.addCollection(scol); + } + } + else + { + List 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 items = swordAuth.getAllowedItems(swordContext, collection); - for (Item item : items) - { - org.purl.sword.base.Collection scol = itemGen.buildCollection(item); - workspace.addCollection(scol); - } + List 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 collections = swordAuth.getAllowedCollections(swordContext, community); - for (Collection collection : collections) - { - org.purl.sword.base.Collection scol = colGen.buildCollection(collection); - workspace.addCollection(scol); - } + List collections = swordAuth + .getAllowedCollections(swordContext, community); + for (Collection collection : collections) + { + org.purl.sword.base.Collection scol = colGen + .buildCollection(collection); + workspace.addCollection(scol); + } - List communities = swordAuth.getCommunities(swordContext, community); - for (Community comm : communities) - { - org.purl.sword.base.Collection scol = comGen.buildCollection(comm); - workspace.addCollection(scol); - } + List 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) diff --git a/dspace-sword/src/main/java/org/dspace/sword/SimpleFileIngester.java b/dspace-sword/src/main/java/org/dspace/sword/SimpleFileIngester.java index 57ece7b9b3..f0fdc6ac7c 100644 --- a/dspace-sword/src/main/java/org/dspace/sword/SimpleFileIngester.java +++ b/dspace-sword/src/main/java/org/dspace/sword/SimpleFileIngester.java @@ -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 - * + *

* 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 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 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"; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSimpleDC.java b/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSimpleDC.java index ed5aed31b1..b087457ce0 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSimpleDC.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSimpleDC.java @@ -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 - * + *

* http://www.dspace.org/license/ */ @@ -22,9 +22,11 @@ import java.util.Properties; public class AbstractSimpleDC { protected HashMap dcMap = null; + protected HashMap 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 all = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY); + List 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(); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSwordContentIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSwordContentIngester.java index f20c23f9f2..ac02167b42 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSwordContentIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/AbstractSwordContentIngester.java @@ -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 - * + *

* 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 formats = bitstreamFormatService.findAll(context); - for (BitstreamFormat format : formats) - { - List 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"); - } + List formats = bitstreamFormatService.findAll(context); + for (BitstreamFormat format : formats) + { + List extensions = format.getExtensions(); + for (String ext : extensions) + { + if (ext.equals(fext)) + { + return format; + } + } + } + return null; + } - 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); - } + /** + * 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"); + } - verboseDescription.append("Updated date added to response from item metadata where available"); - } + 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); + } - /** - * 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; - } + verboseDescription + .append("Updated date added to response from item metadata where available"); + } - 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"); - } + /** + * 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; + } - 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); - } + 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"); + } - verboseDescription.append("Slug value set in response where available"); - } + 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); + } - /** - * 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; + verboseDescription.append("Slug value set in response where available"); + } - StringTokenizer stz = new StringTokenizer(config, "."); - mfi.schema = stz.nextToken(); - mfi.element = stz.nextToken(); - if (stz.hasMoreTokens()) - { - mfi.qualifier = stz.nextToken(); - } + /** + * 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; - return mfi; - } + StringTokenizer stz = new StringTokenizer(config, "."); + mfi.schema = stz.nextToken(); + mfi.element = stz.nextToken(); + if (stz.hasMoreTokens()) + { + mfi.qualifier = stz.nextToken(); + } - private class MetadataFieldInfo { - private String schema; - private String element; - private String qualifier; - } + return mfi; + } + + private class MetadataFieldInfo + { + private String schema; + + private String element; + + private String qualifier; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomCollectionGenerator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomCollectionGenerator.java index 75a21c1609..b1a907eab2 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomCollectionGenerator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomCollectionGenerator.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -13,17 +13,18 @@ import org.swordapp.server.SwordCollection; /** * @author Richard Jones - * + * * Define an abstract interface for classes wishing to generate ATOM Collections * for SWORD service documents */ 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; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java index 3e7e6ae5c9..ef68a6fdf7 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/AtomStatementDisseminator.java @@ -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 - * + *

* 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(); - - public Statement disseminate(Context context, Item item) throws DSpaceSwordException, SwordError, SwordServerException - { - SwordUrlManager urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context); - String feedUri = urlManager.getAtomStatementUri(item); + protected ItemService itemService = ContentServiceFactory.getInstance() + .getItemService(); - String authorField = ConfigurationManager.getProperty("swordv2-server", "author.field"); - String titleField = ConfigurationManager.getProperty("swordv2-server", "title.field"); - String updatedField = ConfigurationManager.getProperty("swordv2-server", "updated.field"); + public Statement disseminate(Context context, Item item) + throws DSpaceSwordException, SwordError, SwordServerException + { + SwordUrlManager urlManager = new SwordUrlManager( + new SwordConfigurationDSpace(), context); + String feedUri = urlManager.getAtomStatementUri(item); - String author = this.stringMetadata(item, authorField); - String title = this.stringMetadata(item, titleField); - String updated = this.stringMetadata(item, updatedField); + String authorField = ConfigurationManager + .getProperty("swordv2-server", "author.field"); + String titleField = ConfigurationManager + .getProperty("swordv2-server", "title.field"); + String updatedField = ConfigurationManager + .getProperty("swordv2-server", "updated.field"); - Statement s = new AtomStatement(feedUri, author, title, updated); - this.populateStatement(context, item, s); - return s; - } + String author = this.stringMetadata(item, authorField); + String title = this.stringMetadata(item, titleField); + String updated = this.stringMetadata(item, updatedField); - private String stringMetadata(Item item, String field) - { - if (field == null) - { - return null; - } + Statement s = new AtomStatement(feedUri, author, title, updated); + this.populateStatement(context, item, s); + return s; + } - List dcvs = itemService.getMetadataByMetadataString(item, field); - if (dcvs == null || dcvs.isEmpty()) - { - return null; - } + private String stringMetadata(Item item, String field) + { + if (field == null) + { + return null; + } - StringBuilder md = new StringBuilder(); - for (MetadataValue dcv : dcvs) - { - if (md.length() > 0) - { - md.append(", "); - } - md.append(dcv.getValue()); - } - return md.toString(); - } + List 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(); + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/BinaryContentIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/BinaryContentIngester.java index 5b580f75a6..7130664d8e 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/BinaryContentIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/BinaryContentIngester.java @@ -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 - * + *

* 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 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 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"; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionCollectionGenerator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionCollectionGenerator.java index 019ba3b4a5..375c1665f2 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionCollectionGenerator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionCollectionGenerator.java @@ -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 - * + *

* 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 dcAbstracts = collectionService.getMetadataByMetadataString(col, "short_description"); + // abstract is the short description of the collection + List 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 accepts = swordConfig.getCollectionAccepts(); for (String accept : accepts) { scol.addAccepts(accept); - scol.addMultipartAccepts(accept); + scol.addMultipartAccepts(accept); } - // add the accept packaging values - List aps = swordConfig.getAcceptPackaging(col); - for (String ap : aps) - { - scol.addAcceptPackaging(ap); - } + // add the accept packaging values + List 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java index 75d36f8619..6a6d01aec2 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionDepositManagerDSpace.java @@ -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 - * + *

* 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java index b565cc990f..144c15786e 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CollectionListManagerDSpace.java @@ -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 - * + *

* 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 items = this.listItems(sc, collection, swordConfig); - return this.itemListToFeed(sc, items, swordConfig); - } - catch (DSpaceSwordException e) - { - throw new SwordServerException(e); - } - finally + List 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 items, SwordConfiguration swordConfig) - throws DSpaceSwordException - { - SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - SwordUrlManager urlManager = config.getUrlManager(sc.getContext(), config); + private Feed itemListToFeed(SwordContext sc, List 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 listItems(SwordContext sc, Collection collection, SwordConfiguration swordConfig) - throws DSpaceSwordException - { - try - { - EPerson person = sc.getOnBehalfOf() != null ? sc.getOnBehalfOf() : sc.getAuthenticated(); - List collectionItems = new ArrayList(); + private List listItems(SwordContext sc, Collection collection, + SwordConfiguration swordConfig) + throws DSpaceSwordException + { + try + { + EPerson person = sc.getOnBehalfOf() != null ? + sc.getOnBehalfOf() : + sc.getAuthenticated(); + List collectionItems = new ArrayList(); - // first get the ones out of the archive - Iterator items = itemService.findBySubmitter(sc.getContext(), person); - while(items.hasNext()) - { - Item item = items.next(); - List 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 items = itemService + .findBySubmitter(sc.getContext(), person); + while (items.hasNext()) + { + Item item = items.next(); + List 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 wsis = workspaceItemService.findByEPerson(sc.getContext(), person); - for (WorkspaceItem wsi : wsis) - { + // now get the ones out of the workspace + List 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 cols = item.getCollections(); - for (Collection col : cols) - { - if (col.getID().equals(collection.getID())) - { - collectionItems.add(item); - break; - } - } - } + List 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 wfis = basicWorkflowItemService.findByOwner(sc.getContext(), person); - for (BasicWorkflowItem wfi : wfis) - { - Item item = wfi.getItem(); + // finally get the ones out of the workflow + List 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 cols = item.getCollections(); - for (Collection col : cols) - { - if (col.getID().equals(collection.getID())) - { - collectionItems.add(item); - break; - } - } - } + List 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 dcvs = itemService.getMetadataByMetadataString(item, field); - if (dcvs == null) - { - return null; - } + List 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(); + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/CommunityCollectionGenerator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/CommunityCollectionGenerator.java index 2205e247c7..f51095ed44 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/CommunityCollectionGenerator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/CommunityCollectionGenerator.java @@ -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 - * + *

* 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 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 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java index 9357394844..33ca29e729 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -31,51 +31,64 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; -public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerManager +public class ContainerManagerDSpace extends DSpaceSwordAPI + implements ContainerManager { - private static Logger log = Logger.getLogger(ContainerManagerDSpace.class); + private static Logger log = Logger.getLogger(ContainerManagerDSpace.class); - protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); - protected WorkflowItemService workflowItemService = WorkflowServiceFactory.getInstance().getWorkflowItemService(); - protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); + protected AuthorizeService authorizeService = AuthorizeServiceFactory + .getInstance().getAuthorizeService(); - private VerboseDescription verboseDescription = new VerboseDescription(); + protected CollectionService collectionService = ContentServiceFactory + .getInstance().getCollectionService(); - public boolean isStatementRequest(String editIRI, Map accept, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - SwordContext sc = null; - try - { - sc = this.noAuthContext(); - SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - Context context = sc.getContext(); + protected WorkflowItemService workflowItemService = WorkflowServiceFactory + .getInstance().getWorkflowItemService(); - String acceptContentType = this.getHeader(accept, "Accept", null); - TreeMap> analysed = this.analyseAccept(acceptContentType); + protected WorkspaceItemService workspaceItemService = ContentServiceFactory + .getInstance().getWorkspaceItemService(); - // a request is for a statement if the content negotiation asks for a format that the - // Statement disseminator supports - SwordStatementDisseminator disseminator = null; - try - { - disseminator = SwordDisseminatorFactory.getStatementInstance(analysed); - } - catch (SwordError swordError) - { - // in this case, it means that no relevant disseminator could be found, which means - // this is not a statement request - return false; - } - return true; - } - catch (DSpaceSwordException e) - { - log.error("caught exception:", e); - throw new SwordServerException("There was a problem determining the request type", e); - } - finally + private VerboseDescription verboseDescription = new VerboseDescription(); + + public boolean isStatementRequest(String editIRI, + Map accept, AuthCredentials authCredentials, + SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + SwordContext sc = null; + try + { + sc = this.noAuthContext(); + SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; + Context context = sc.getContext(); + + String acceptContentType = this.getHeader(accept, "Accept", null); + TreeMap> analysed = this + .analyseAccept(acceptContentType); + + // a request is for a statement if the content negotiation asks for a format that the + // Statement disseminator supports + SwordStatementDisseminator disseminator = null; + try + { + disseminator = SwordDisseminatorFactory + .getStatementInstance(analysed); + } + catch (SwordError swordError) + { + // in this case, it means that no relevant disseminator could be found, which means + // this is not a statement request + return false; + } + return true; + } + catch (DSpaceSwordException e) + { + log.error("caught exception:", e); + throw new SwordServerException( + "There was a problem determining the request type", e); + } + finally { // this is a read operation only, so there's never any need to commit the context if (sc != null) @@ -83,20 +96,21 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - public DepositReceipt getEntry(String editIRI, Map accept, 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); + public DepositReceipt getEntry(String editIRI, Map accept, + 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); - Item item = urlManager.getItem(context, editIRI); + Item item = urlManager.getItem(context, editIRI); if (item == null) { throw new SwordError(404); @@ -105,11 +119,11 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM // we can't give back an entry unless the user is authorised to retrieve it authorizeService.authorizeAction(context, item, Constants.READ); - ReceiptGenerator genny = new ReceiptGenerator(); - DepositReceipt receipt = genny.createReceipt(context, item, config); - sc.abort(); - return receipt; - } + ReceiptGenerator genny = new ReceiptGenerator(); + DepositReceipt receipt = genny.createReceipt(context, item, config); + sc.abort(); + return receipt; + } catch (AuthorizeException e) { throw new SwordAuthException(); @@ -117,7 +131,8 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM catch (SQLException | DSpaceSwordException e) { throw new SwordServerException(e); - } finally + } + finally { // this is a read operation only, so there's never any need to commit the context if (sc != null) @@ -125,21 +140,23 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - public DepositReceipt replaceMetadata(String editIRI, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - // start the timer + public DepositReceipt replaceMetadata(String editIRI, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose replace of metadata"); + this.verboseDescription + .append("Initialising verbose replace of metadata"); - SwordContext sc = null; + SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - try + try { sc = this.doAuth(authCredentials); Context context = sc.getContext(); @@ -156,10 +173,10 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.replaceMetadata(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.replaceMetadata(context, item); // find out if the supplied SWORDContext can submit to the given // dspace object @@ -172,22 +189,30 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); + log.info(LogManager + .getHeader(context, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item with this context"); } - // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().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()); + this.verboseDescription.append("Depositing on behalf of: " + + sc.getOnBehalfOf().getEmail()); } - DepositResult result = null; - try + DepositResult result = null; + try { - result = this.doReplaceMetadata(sc, item, deposit, authCredentials, config); + result = this + .doReplaceMetadata(sc, item, deposit, authCredentials, + config); } catch (DSpaceSwordException | SwordError e) { @@ -197,7 +222,7 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { this.storeEntryAsFile(deposit, authCredentials, config); } - catch(IOException e2) + catch (IOException e2) { log.warn("Unable to store SWORD entry as file: " + e); } @@ -209,23 +234,27 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM wfm.resolveState(context, deposit, result, this.verboseDescription); ReceiptGenerator genny = new ReceiptGenerator(); - DepositReceipt receipt = genny.createReceipt(context, result, config); + DepositReceipt receipt = genny + .createReceipt(context, result, config); 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(); - return receipt; - } + return receipt; + } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } finally { @@ -235,139 +264,158 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - public DepositReceipt replaceMetadataAndMediaResource(String editIRI, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - // start the timer - Date start = new Date(); + public DepositReceipt replaceMetadataAndMediaResource(String editIRI, + Deposit deposit, AuthCredentials authCredentials, + SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + // start the timer + Date start = new Date(); - // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose multipart replace"); + // store up the verbose description, which we can then give back at the end if necessary + this.verboseDescription + .append("Initialising verbose multipart replace"); - SwordContext sc = null; - SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; + SwordContext sc = null; + SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - try - { - // first authenticate the request - // note: this will build our various DSpace contexts for us - sc = this.doAuth(authCredentials); - Context context = sc.getContext(); + try + { + // first authenticate the request + // note: this will build our various DSpace contexts for us + sc = this.doAuth(authCredentials); + Context context = sc.getContext(); - if (log.isDebugEnabled()) - { - log.debug(LogManager.getHeader(context, "sword_create_new", "")); - } + if (log.isDebugEnabled()) + { + log.debug( + LogManager.getHeader(context, "sword_create_new", "")); + } - // get the deposit target + // get the deposit target Item item = this.getDSpaceTarget(context, editIRI, config); if (item == null) { throw new SwordError(404); } - // Ensure that this method is allowed - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.replaceMetadataAndMediaResource(context, item); + // Ensure that this method is allowed + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.replaceMetadataAndMediaResource(context, item); - // 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, item, 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, item, 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 - { - result = this.replaceFromMultipart(sc, item, deposit, authCredentials, config); - } - catch (DSpaceSwordException | SwordError e) - { - if (config.isKeepPackageOnFailedIngest()) - { - try - { - 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 + { + result = this.replaceFromMultipart(sc, item, deposit, + authCredentials, config); + } + catch (DSpaceSwordException | SwordError e) + { + if (config.isKeepPackageOnFailedIngest()) + { + try + { + 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(); + } + } + } - public DepositReceipt addMetadataAndResources(String s, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration config) - throws SwordError, SwordServerException - { - return null; - } + public DepositReceipt addMetadataAndResources(String s, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration config) + throws SwordError, SwordServerException + { + return null; + } - public DepositReceipt addMetadata(String editIRI, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - // start the timer + public DepositReceipt addMetadata(String editIRI, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose replace of metadata"); + this.verboseDescription + .append("Initialising verbose replace of metadata"); - SwordContext sc = null; + SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - try + try { sc = this.doAuth(authCredentials); Context context = sc.getContext(); @@ -384,10 +432,10 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.addMetadata(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.addMetadata(context, item); // find out if the supplied SWORDContext can submit to the given // dspace object @@ -400,22 +448,29 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); + log.info(LogManager + .getHeader(context, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item with this context"); } - // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().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()); + this.verboseDescription.append("Depositing on behalf of: " + + sc.getOnBehalfOf().getEmail()); } - DepositResult result = null; - try + DepositResult result = null; + try { - result = this.doAddMetadata(sc, item, deposit, authCredentials, config); + result = this.doAddMetadata(sc, item, deposit, authCredentials, + config); } catch (DSpaceSwordException | SwordError e) { @@ -425,7 +480,7 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { this.storeEntryAsFile(deposit, authCredentials, config); } - catch(IOException e2) + catch (IOException e2) { log.warn("Unable to store SWORD entry as file: " + e); } @@ -437,23 +492,27 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM wfm.resolveState(context, deposit, result, this.verboseDescription); ReceiptGenerator genny = new ReceiptGenerator(); - DepositReceipt receipt = genny.createReceipt(context, result, config); + DepositReceipt receipt = genny + .createReceipt(context, result, config); 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(); - return receipt; - } + return receipt; + } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } finally { @@ -463,27 +522,29 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - public DepositReceipt addResources(String s, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration config) - throws SwordError, SwordServerException - { - return null; - } + public DepositReceipt addResources(String s, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration config) + throws SwordError, SwordServerException + { + return null; + } - public void deleteContainer(String editIRI, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - // start the timer + public void deleteContainer(String editIRI, AuthCredentials authCredentials, + SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary this.verboseDescription.append("Initialising verbose container delete"); - SwordContext sc = null; + SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - try + try { sc = this.doAuth(authCredentials); Context context = sc.getContext(); @@ -500,10 +561,10 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.deleteItem(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.deleteItem(context, item); // find out if the supplied SWORDContext can submit to the given // dspace object @@ -516,32 +577,41 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot delete the given item with this context"); + log.info(LogManager + .getHeader(context, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot delete the given item with this context"); } - // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().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()); + this.verboseDescription.append("Depositing on behalf of: " + + sc.getOnBehalfOf().getEmail()); } - this.doContainerDelete(sc, item, authCredentials, config); + this.doContainerDelete(sc, item, authCredentials, config); 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"); // if something hasn't killed it already (allowed), then complete the transaction sc.commit(); - } + } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } finally { @@ -551,28 +621,31 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - public DepositReceipt useHeaders(String editIRI, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException - { - // start the timer + public DepositReceipt useHeaders(String editIRI, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException + { + // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose empty request (headers only)"); + this.verboseDescription + .append("Initialising verbose empty request (headers only)"); - SwordContext sc = null; + SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; - try + try { sc = this.doAuth(authCredentials); Context context = sc.getContext(); if (log.isDebugEnabled()) { - log.debug(LogManager.getHeader(context, "sword_modify_by_headers", "")); + log.debug(LogManager + .getHeader(context, "sword_modify_by_headers", "")); } // get the deposit target @@ -582,10 +655,10 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.modifyState(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.modifyState(context, item); // find out if the supplied SWORDContext can submit to the given // dspace object @@ -598,43 +671,52 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "modify_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot modify the given item with this context"); + log.info(LogManager + .getHeader(context, "modify_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot modify the given item with this context"); } - // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().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("Modifying on behalf of: " + sc.getOnBehalfOf().getEmail()); + this.verboseDescription.append("Modifying on behalf of: " + + sc.getOnBehalfOf().getEmail()); } - DepositResult result = new DepositResult(); - result.setItem(item); + DepositResult result = new DepositResult(); + result.setItem(item); - // the main objective here is just to resolve the state + // the main objective here is just to resolve the state wfm.resolveState(context, deposit, result, this.verboseDescription); - // now return the usual deposit receipt + // now return the usual deposit receipt ReceiptGenerator genny = new ReceiptGenerator(); DepositReceipt receipt = genny.createReceipt(context, item, config); Date finish = new Date(); long delta = finish.getTime() - start.getTime(); - this.verboseDescription.append("Total time for modify processing: " + delta + " ms"); + this.verboseDescription + .append("Total time for modify processing: " + delta + + " ms"); this.addVerboseDescription(receipt, this.verboseDescription); // if something hasn't killed it already (allowed), then complete the transaction sc.commit(); - return receipt; - } + return receipt; + } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } finally { @@ -644,170 +726,212 @@ public class ContainerManagerDSpace extends DSpaceSwordAPI implements ContainerM sc.abort(); } } - } + } - private DepositResult replaceFromMultipart(SwordContext swordContext, Item item, 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); + private DepositResult replaceFromMultipart(SwordContext swordContext, + Item item, 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, item); - // Obtain the relevant content ingester from the factory - SwordContentIngester sci = SwordIngesterFactory.getContentInstance(context, deposit, item); - this.verboseDescription.append("Loaded content ingester: " + sci.getClass().getName()); + // Obtain the relevant content ingester from the factory + SwordContentIngester sci = SwordIngesterFactory + .getContentInstance(context, deposit, item); + this.verboseDescription + .append("Loaded content ingester: " + sci.getClass().getName()); // obtain the relevant entry intester from the factory - SwordEntryIngester sei = SwordIngesterFactory.getEntryInstance(context, deposit, item); - this.verboseDescription.append("Loaded entry ingester: " + sei.getClass().getName()); + SwordEntryIngester sei = SwordIngesterFactory + .getEntryInstance(context, deposit, item); + this.verboseDescription + .append("Loaded entry ingester: " + sei.getClass().getName()); - try - { - // delegate the to the version manager to get rid of any existing content and to version - // if if necessary - VersionManager vm = new VersionManager(); - vm.removeBundle(context, item, "ORIGINAL"); - } - catch (SQLException | IOException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + try + { + // delegate the to the version manager to get rid of any existing content and to version + // if if necessary + VersionManager vm = new VersionManager(); + vm.removeBundle(context, item, "ORIGINAL"); + } + catch (SQLException | IOException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } DepositResult result; if (swordConfig.isEntryFirst()) { // do the entry deposit - result = sei.ingest(context, deposit, item, this.verboseDescription, null, true); + result = sei.ingest(context, deposit, item, this.verboseDescription, + null, true); // do the content deposit - result = sci.ingest(context, deposit, item, this.verboseDescription, result); - this.verboseDescription.append("Archive ingest completed successfully"); + result = sci.ingest(context, deposit, item, this.verboseDescription, + result); + this.verboseDescription + .append("Archive ingest completed successfully"); } else { // do the content deposit - result = sci.ingest(context, deposit, item, this.verboseDescription, null); + result = sci.ingest(context, deposit, item, this.verboseDescription, + null); // do the entry deposit - result = sei.ingest(context, deposit, item, this.verboseDescription, result, true); - this.verboseDescription.append("Archive ingest completed successfully"); + result = sei.ingest(context, deposit, item, this.verboseDescription, + result, true); + 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; - } - - private DepositResult doReplaceMetadata(SwordContext swordContext, Item item, 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, null); - this.verboseDescription.append("Loaded ingester: " + si.getClass().getName()); - - // do the deposit - DepositResult result = si.ingest(context, deposit, item, this.verboseDescription, null, true); - this.verboseDescription.append("Replace completed successfully"); - - // store the originals (this code deals with the possibility that that's not required) - this.storeOriginals(swordConfig, context, this.verboseDescription, deposit, result); - - return result; - } - - protected DepositResult doAddMetadata(SwordContext swordContext, Item item, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException - { - return this.doAddMetadata(swordContext, item, deposit, authCredentials, swordConfig, null); - } - - protected DepositResult doAddMetadata(SwordContext swordContext, Item item, Deposit deposit, AuthCredentials authCredentials, - SwordConfigurationDSpace swordConfig, DepositResult result) - throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException - { - if (result == null) - { - result = new DepositResult(); - } - - // 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, null); - this.verboseDescription.append("Loaded ingester: " + si.getClass().getName()); - - // do the deposit - result = si.ingest(context, deposit, item, this.verboseDescription, result, false); - this.verboseDescription.append("Replace completed successfully"); - - // store the originals (this code deals with the possibility that that's not required) - this.storeOriginals(swordConfig, context, this.verboseDescription, deposit, result); - - return result; - } - - protected void doContainerDelete(SwordContext swordContext, Item item, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordAuthException - { - try - { - Context context = swordContext.getContext(); - - // first figure out if there's anything we need to do about the workflow/workspace state - WorkflowTools wft = new WorkflowTools(); - if (wft.isItemInWorkspace(swordContext.getContext(), item)) - { - WorkspaceItem wsi = wft.getWorkspaceItem(context, item); - workspaceItemService.deleteAll(context, wsi); - } - else if (wft.isItemInWorkflow(context, item)) - { - InProgressSubmission wfi = wft.getWorkflowItem(context, item); - workflowItemService.deleteWrapper(context, wfi); - } - - // then delete the item - itemService.delete(context, item); - } - catch (SQLException | IOException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + return result; } - private Item getDSpaceTarget(Context context, String editUrl, SwordConfigurationDSpace config) - throws DSpaceSwordException, SwordError - { - SwordUrlManager urlManager = config.getUrlManager(context, config); + private DepositResult doReplaceMetadata(SwordContext swordContext, + Item item, 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); - // get the target collection - Item item = urlManager.getItem(context, editUrl); + // Obtain the relevant ingester from the factory + SwordEntryIngester si = SwordIngesterFactory + .getEntryInstance(context, deposit, null); + this.verboseDescription + .append("Loaded ingester: " + si.getClass().getName()); + + // do the deposit + DepositResult result = si + .ingest(context, deposit, item, this.verboseDescription, null, + true); + this.verboseDescription.append("Replace completed successfully"); + + // store the originals (this code deals with the possibility that that's not required) + this.storeOriginals(swordConfig, context, this.verboseDescription, + deposit, result); + + return result; + } + + protected DepositResult doAddMetadata(SwordContext swordContext, Item item, + Deposit deposit, AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig) + throws DSpaceSwordException, SwordError, SwordAuthException, + SwordServerException + { + return this.doAddMetadata(swordContext, item, deposit, authCredentials, + swordConfig, null); + } + + protected DepositResult doAddMetadata(SwordContext swordContext, Item item, + Deposit deposit, AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig, DepositResult result) + throws DSpaceSwordException, SwordError, SwordAuthException, + SwordServerException + { + if (result == null) + { + result = new DepositResult(); + } + + // 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, null); + this.verboseDescription + .append("Loaded ingester: " + si.getClass().getName()); + + // do the deposit + result = si + .ingest(context, deposit, item, this.verboseDescription, result, + false); + this.verboseDescription.append("Replace completed successfully"); + + // store the originals (this code deals with the possibility that that's not required) + this.storeOriginals(swordConfig, context, this.verboseDescription, + deposit, result); + + return result; + } + + protected void doContainerDelete(SwordContext swordContext, Item item, + AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig) + throws DSpaceSwordException, SwordAuthException + { + try + { + Context context = swordContext.getContext(); + + // first figure out if there's anything we need to do about the workflow/workspace state + WorkflowTools wft = new WorkflowTools(); + if (wft.isItemInWorkspace(swordContext.getContext(), item)) + { + WorkspaceItem wsi = wft.getWorkspaceItem(context, item); + workspaceItemService.deleteAll(context, wsi); + } + else if (wft.isItemInWorkflow(context, item)) + { + InProgressSubmission wfi = wft.getWorkflowItem(context, item); + workflowItemService.deleteWrapper(context, wfi); + } + + // then delete the item + itemService.delete(context, item); + } + catch (SQLException | IOException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } + } + + private Item getDSpaceTarget(Context context, String editUrl, + SwordConfigurationDSpace config) + throws DSpaceSwordException, SwordError + { + SwordUrlManager urlManager = config.getUrlManager(context, config); + + // get the target collection + Item item = urlManager.getItem(context, editUrl); if (item == null) { throw new SwordError(404); } - this.verboseDescription.append("Performing replace using edit-media URL: " + editUrl); - this.verboseDescription.append("Location resolves to item with handle: " + item.getHandle()); + this.verboseDescription + .append("Performing replace using edit-media URL: " + editUrl); + this.verboseDescription + .append("Location resolves to item with handle: " + + item.getHandle()); - return item; - } + return item; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordAPI.java b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordAPI.java index 7f23cb7043..4b09437ecb 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordAPI.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordAPI.java @@ -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 - * + *

* 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 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()); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordException.java b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordException.java index 925234d3a4..9d6c0b8d0e 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordException.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceSwordException.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -12,31 +12,31 @@ import org.swordapp.server.SwordServerException; /** * This Exception class can be thrown by the internals of the * DSpace SWORD implementation - * + * * @author Richard Jones * */ 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); + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceUriRegistry.java b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceUriRegistry.java index 9df390e306..256311a276 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceUriRegistry.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/DSpaceUriRegistry.java @@ -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 - * + *

* 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"; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java b/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java index 166633f6f7..78e4b8ef6e 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/DepositResult.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -17,61 +17,61 @@ import java.util.Map; * The DSpace class for representing the results of a deposit * request. This class can be used to hold all of the relevant * components required to later build the SWORD response - * + * * @author Richard Jones * */ 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 derivedResources; + private List 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 getDerivedResources() - { - return derivedResources; - } + public List getDerivedResources() + { + return derivedResources; + } - public void setDerivedResources(List derivedResources) - { - this.derivedResources = derivedResources; - } + public void setDerivedResources(List 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/FeedContentDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/FeedContentDisseminator.java index 6d99c15995..99e84f8dde 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/FeedContentDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/FeedContentDisseminator.java @@ -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 - * + *

* 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 bundleBitstreams = bundle.getBitstreams(); - for (BundleBitstream bundleBitstream : bundleBitstreams) { + List 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; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/GenericStatementDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/GenericStatementDisseminator.java index d952337921..13b1656992 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/GenericStatementDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/GenericStatementDisseminator.java @@ -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 - * + *

* 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 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 originalDeposits = this.getOriginalDeposits(context, item, originalDepositBundle); + List originalDeposits = this + .getOriginalDeposits(context, item, originalDepositBundle); statement.setOriginalDeposits(originalDeposits); } - Map states = this.getStates(context, item); + Map states = this.getStates(context, item); statement.setStates(states); // remove the original deposit bundle from the include bundles includeBundles.remove(originalDepositBundle); - List resources = this.getResourceParts(context, item, includeBundles); + List resources = this + .getResourceParts(context, item, includeBundles); statement.setResources(resources); Date lastModified = this.getLastModified(context, item); statement.setLastModified(lastModified); - } + } - protected List getOriginalDeposits(Context context, Item item, String swordBundle) - throws DSpaceSwordException - { - try - { + protected List 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 originalDeposits = new ArrayList(); + List originalDeposits = new ArrayList(); // an original deposit is everything in the SWORD bundle - List bundles = item.getBundles(); - for (Bundle bundle : bundles) - { - if (swordBundle.equals(bundle.getName())) - { - List 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 bundles = item.getBundles(); + for (Bundle bundle : bundles) + { + if (swordBundle.equals(bundle.getName())) + { + List 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 getStates(Context context, Item item) - throws DSpaceSwordException - { - SwordConfigurationDSpace config = new SwordConfigurationDSpace(); - WorkflowTools wft = new WorkflowTools(); - Map states = new HashMap(); - 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 getStates(Context context, Item item) + throws DSpaceSwordException + { + SwordConfigurationDSpace config = new SwordConfigurationDSpace(); + WorkflowTools wft = new WorkflowTools(); + Map states = new HashMap(); + 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 getResourceParts(Context context, Item item, List includeBundles) - throws DSpaceSwordException - { - try - { - // the list of resource parts is everything in the bundles to be included - List resources = new ArrayList(); + protected List getResourceParts(Context context, Item item, + List includeBundles) + throws DSpaceSwordException + { + try + { + // the list of resource parts is everything in the bundles to be included + List resources = new ArrayList(); for (String bundleName : includeBundles) { List bundles = item.getBundles(); for (Bundle bundle : bundles) { - if (bundleName.equals(bundle.getName())) - { - List 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 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 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"; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/MediaResourceManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/MediaResourceManagerDSpace.java index 4dcac66f3a..003eb59f5b 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/MediaResourceManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/MediaResourceManagerDSpace.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -27,12 +27,17 @@ import java.io.InputStream; import java.sql.SQLException; import java.util.*; -public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaResourceManager +public class MediaResourceManagerDSpace extends DSpaceSwordAPI + implements MediaResourceManager { - private static Logger log = Logger.getLogger(MediaResourceManagerDSpace.class); + private static Logger log = Logger + .getLogger(MediaResourceManagerDSpace.class); - protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService(); + protected AuthorizeService authorizeService = AuthorizeServiceFactory + .getInstance().getAuthorizeService(); + + protected BitstreamService bitstreamService = ContentServiceFactory + .getInstance().getBitstreamService(); private VerboseDescription verboseDescription = new VerboseDescription(); @@ -41,7 +46,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { try { - return authorizeService.authorizeActionBoolean(context, bitstream, Constants.READ); + return authorizeService + .authorizeActionBoolean(context, bitstream, Constants.READ); } catch (SQLException e) { @@ -54,7 +60,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { try { - return authorizeService.authorizeActionBoolean(context, item, Constants.READ); + return authorizeService + .authorizeActionBoolean(context, item, Constants.READ); } catch (SQLException e) { @@ -62,13 +69,15 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } } - private MediaResource getBitstreamResource(Context context, Bitstream bitstream) + private MediaResource getBitstreamResource(Context context, + Bitstream bitstream) throws SwordServerException, SwordAuthException { try { InputStream stream = bitstreamService.retrieve(context, bitstream); - MediaResource mr = new MediaResource(stream, bitstream.getFormat(context).getMIMEType(), null, true); + MediaResource mr = new MediaResource(stream, + bitstream.getFormat(context).getMIMEType(), null, true); mr.setContentMD5(bitstream.getChecksum()); mr.setLastModified(this.getLastModified(context, bitstream)); return mr; @@ -76,13 +85,15 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR catch (IOException | SQLException e) { throw new SwordServerException(e); - } catch (AuthorizeException e) + } + catch (AuthorizeException e) { throw new SwordAuthException(e); } } - private MediaResource getItemResource(Context context, Item item, SwordUrlManager urlManager, String uri, Map accept) + private MediaResource getItemResource(Context context, Item item, + SwordUrlManager urlManager, String uri, Map accept) throws SwordError, DSpaceSwordException, SwordServerException { boolean feedRequest = urlManager.isFeedRequest(context, uri); @@ -94,16 +105,19 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR if (!feedRequest) { String acceptContentType = this.getHeader(accept, "Accept", null); - String acceptPackaging = this.getHeader(accept, "Accept-Packaging", UriRegistry.PACKAGE_SIMPLE_ZIP); + String acceptPackaging = this.getHeader(accept, "Accept-Packaging", + UriRegistry.PACKAGE_SIMPLE_ZIP); // we know that only one Accept-Packaging value is allowed, so we don't need // to do any further work on it. // we extract from the Accept header the ordered list of content types - TreeMap> analysed = this.analyseAccept(acceptContentType); + TreeMap> analysed = this + .analyseAccept(acceptContentType); // the meat of this is done by the package disseminator - disseminator = SwordDisseminatorFactory.getContentInstance(analysed, acceptPackaging); + disseminator = SwordDisseminatorFactory + .getContentInstance(analysed, acceptPackaging); } else { @@ -113,17 +127,21 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR List list = new ArrayList(); list.add("application/atom+xml"); analysed.put((float) 1.0, list); - disseminator = SwordDisseminatorFactory.getContentInstance(analysed, null); + disseminator = SwordDisseminatorFactory + .getContentInstance(analysed, null); } // Note that at this stage, if we don't have a desiredContentType, it will // be null, and the disseminator is free to choose the format InputStream stream = disseminator.disseminate(context, item); - return new MediaResource(stream, disseminator.getContentType(), disseminator.getPackaging()); + return new MediaResource(stream, disseminator.getContentType(), + disseminator.getPackaging()); } - public MediaResource getMediaResourceRepresentation(String uri, Map accept, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordError, SwordServerException, SwordAuthException + public MediaResource getMediaResourceRepresentation(String uri, + Map accept, AuthCredentials authCredentials, + SwordConfiguration swordConfig) + throws SwordError, SwordServerException, SwordAuthException { // all the bits we need to make this method function SwordContext sc = null; @@ -149,7 +167,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } // find out, now we know what we're being asked for, whether this is allowed - WorkflowManagerFactory.getInstance().retrieveBitstream(ctx, bitstream); + WorkflowManagerFactory.getInstance() + .retrieveBitstream(ctx, bitstream); // we can do this in principle, but now find out whether the bitstream is accessible without credentials boolean accessible = this.isAccessible(ctx, bitstream); @@ -212,7 +231,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR // if we get to here we are either allowed to access the bitstream without credentials, // or we have been authenticated - MediaResource mr = this.getItemResource(ctx, item, urlManager, uri, accept); + MediaResource mr = this + .getItemResource(ctx, item, urlManager, uri, accept); // sc.abort(); ctx.abort(); return mr; @@ -221,7 +241,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR catch (SQLException | DSpaceSwordException e) { throw new SwordServerException(e); - } finally + } + finally { // if there is a sword context, abort it (this will abort the inner dspace context as well) if (sc != null) @@ -263,14 +284,16 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR return lm; } - public DepositReceipt replaceMediaResource(String emUri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) + public DepositReceipt replaceMediaResource(String emUri, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration swordConfig) throws SwordError, SwordServerException, SwordAuthException { // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose replace of media resource"); + this.verboseDescription + .append("Initialising verbose replace of media resource"); SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; @@ -286,9 +309,9 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } DepositReceipt receipt; - SwordUrlManager urlManager = config.getUrlManager(context, config); - if (urlManager.isActionableBitstreamUrl(context, emUri)) - { + SwordUrlManager urlManager = config.getUrlManager(context, config); + if (urlManager.isActionableBitstreamUrl(context, emUri)) + { Bitstream bitstream = urlManager.getBitstream(context, emUri); if (bitstream == null) { @@ -301,29 +324,34 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR wfm.replaceBitstream(context, bitstream); // check that we can submit to ALL the items this bitstream is in - List items = new ArrayList<>(); + List items = new ArrayList<>(); List bundleBitstreams = bitstream.getBundles(); for (BundleBitstream bundleBitstream : bundleBitstreams) - { - List bundleItems = bundleBitstream.getBundle().getItems(); + { + List bundleItems = bundleBitstream.getBundle() + .getItems(); for (Item item : bundleItems) - { - this.checkAuth(sc, item); - items.add(item); - } - } + { + this.checkAuth(sc, item); + items.add(item); + } + } - // 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 { - result = this.replaceBitstream(sc, items, bitstream, deposit, authCredentials, config); + result = this + .replaceBitstream(sc, items, bitstream, deposit, + authCredentials, config); } catch (DSpaceSwordException | SwordError e) { @@ -331,22 +359,25 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { try { - this.storePackageAsFile(deposit, authCredentials, config); + this.storePackageAsFile(deposit, authCredentials, + config); } - catch(IOException e2) + catch (IOException e2) { - log.warn("Unable to store SWORD package as file: " + e); + 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, null, this.verboseDescription, false); + wfm.resolveState(context, deposit, null, + this.verboseDescription, false); ReceiptGenerator genny = new ReceiptGenerator(); receipt = genny.createFileReceipt(context, result, config); - } + } else { // get the deposit target @@ -372,21 +403,28 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); + log.info(LogManager + .getHeader(context, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item with this context"); } // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().getEmail()); + this.verboseDescription.append("Authenticated user: " + + sc.getAuthenticated().getEmail()); if (sc.getOnBehalfOf() != null) { - this.verboseDescription.append("Depositing on behalf of: " + sc.getOnBehalfOf().getEmail()); + this.verboseDescription.append("Depositing on behalf of: " + + sc.getOnBehalfOf().getEmail()); } try { - this.replaceContent(sc, item, deposit, authCredentials, config); + this.replaceContent(sc, item, deposit, authCredentials, + config); } catch (DSpaceSwordException | SwordError e) { @@ -394,27 +432,33 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { try { - this.storePackageAsFile(deposit, authCredentials, config); + this.storePackageAsFile(deposit, authCredentials, + config); } - catch(IOException e2) + catch (IOException e2) { - log.warn("Unable to store SWORD package as file: " + e); + 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, null, this.verboseDescription, false); + wfm.resolveState(context, deposit, null, + this.verboseDescription, false); ReceiptGenerator genny = new ReceiptGenerator(); - receipt = genny.createMediaResourceReceipt(context, item, config); + receipt = genny + .createMediaResourceReceipt(context, item, config); } 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"); // receipt.setVerboseDescription(this.verboseDescription.toString()); // if something hasn't killed it already (allowed), then complete the transaction @@ -426,12 +470,13 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } catch (SQLException e) - { - throw new SwordServerException(e); - } + { + throw new SwordServerException(e); + } finally { // this is a read operation only, so there's never any need to commit the context @@ -442,14 +487,16 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } } - public void deleteMediaResource(String emUri, AuthCredentials authCredentials, SwordConfiguration swordConfig) + public void deleteMediaResource(String emUri, + AuthCredentials authCredentials, SwordConfiguration swordConfig) throws SwordError, SwordServerException, SwordAuthException { // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose delete of media resource"); + this.verboseDescription + .append("Initialising verbose delete of media resource"); SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; @@ -464,109 +511,123 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR log.debug(LogManager.getHeader(context, "sword_delete", "")); } - SwordUrlManager urlManager = config.getUrlManager(context, config); - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + SwordUrlManager urlManager = config.getUrlManager(context, config); + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); // get the deposit target - if (urlManager.isActionableBitstreamUrl(context, emUri)) - { - Bitstream bitstream = urlManager.getBitstream(context, emUri); + if (urlManager.isActionableBitstreamUrl(context, emUri)) + { + Bitstream bitstream = urlManager.getBitstream(context, emUri); if (bitstream == null) { throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - wfm.deleteBitstream(context, bitstream); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + wfm.deleteBitstream(context, bitstream); - // check that we can submit to ALL the items this bitstream is in - List items = new ArrayList<>(); - for (BundleBitstream bundleBitstream : bitstream.getBundles()) - { - List bundleItems = bundleBitstream.getBundle().getItems(); + // check that we can submit to ALL the items this bitstream is in + List items = new ArrayList<>(); + for (BundleBitstream bundleBitstream : bitstream.getBundles()) + { + List bundleItems = bundleBitstream.getBundle() + .getItems(); for (Item item : bundleItems) - { - this.checkAuth(sc, item); - items.add(item); - } - } + { + this.checkAuth(sc, item); + items.add(item); + } + } - // 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()); + } - this.removeBitstream(sc, bitstream, items, authCredentials, config); - } - else - { - Item item = this.getDSpaceTarget(context, emUri, config); + this.removeBitstream(sc, bitstream, items, authCredentials, + config); + } + else + { + Item item = this.getDSpaceTarget(context, emUri, config); if (item == null) { throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - wfm.deleteMediaResource(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + wfm.deleteMediaResource(context, item); - // find out if the supplied SWORDContext can submit to the given - // dspace object - SwordAuthenticator auth = new SwordAuthenticator(); - if (!auth.canSubmit(sc, item, 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, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); - } + // find out if the supplied SWORDContext can submit to the given + // dspace object + SwordAuthenticator auth = new SwordAuthenticator(); + if (!auth.canSubmit(sc, item, 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, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item 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()); + } - // do the business of removal - this.removeContent(sc, item, authCredentials, config); - } + // do the business of removal + this.removeContent(sc, item, authCredentials, config); + } - // now we've produced a deposit, we need to decide on its workflow state - wfm.resolveState(context, null, null, this.verboseDescription, false); + // now we've produced a deposit, we need to decide on its workflow state + wfm.resolveState(context, null, null, this.verboseDescription, + false); - //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"); - // receipt.setVerboseDescription(this.verboseDescription.toString()); + this.verboseDescription + .append("Total time for deposit processing: " + delta + + " ms"); + // receipt.setVerboseDescription(this.verboseDescription.toString()); - // 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(); - // So, we don't actually return a receipt, but it was useful constructing it. Perhaps this will - // change in the spec? + // So, we don't actually return a receipt, but it was useful constructing it. Perhaps this will + // change in the spec? } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); + } + catch (SQLException e) + { + throw new SwordServerException(e); } - catch (SQLException e) - { - throw new SwordServerException(e); - } finally { // this is a read operation only, so there's never any need to commit the context @@ -577,14 +638,16 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } } - public DepositReceipt addResource(String emUri, Deposit deposit, AuthCredentials authCredentials, SwordConfiguration swordConfig) + public DepositReceipt addResource(String emUri, Deposit deposit, + AuthCredentials authCredentials, SwordConfiguration swordConfig) throws SwordError, SwordServerException, SwordAuthException { // start the timer Date start = new Date(); // store up the verbose description, which we can then give back at the end if necessary - this.verboseDescription.append("Initialising verbose add to media resource"); + this.verboseDescription + .append("Initialising verbose add to media resource"); SwordContext sc = null; SwordConfigurationDSpace config = (SwordConfigurationDSpace) swordConfig; @@ -606,10 +669,10 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR throw new SwordError(404); } - // now we have the deposit target, we can determine whether this operation is allowed - // at all - WorkflowManager wfm = WorkflowManagerFactory.getInstance(); - wfm.addResourceContent(context, item); + // now we have the deposit target, we can determine whether this operation is allowed + // at all + WorkflowManager wfm = WorkflowManagerFactory.getInstance(); + wfm.addResourceContent(context, item); // find out if the supplied SWORDContext can submit to the given // dspace object @@ -622,27 +685,36 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { oboEmail = sc.getOnBehalfOf().getEmail(); } - log.info(LogManager.getHeader(context, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); + log.info(LogManager + .getHeader(context, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item with this context"); } // make a note of the authentication in the verbose string - this.verboseDescription.append("Authenticated user: " + sc.getAuthenticated().getEmail()); + this.verboseDescription.append("Authenticated user: " + + sc.getAuthenticated().getEmail()); if (sc.getOnBehalfOf() != null) { - this.verboseDescription.append("Depositing on behalf of: " + sc.getOnBehalfOf().getEmail()); + this.verboseDescription.append("Depositing on behalf of: " + + sc.getOnBehalfOf().getEmail()); } - DepositResult result; + DepositResult result; try { - result = this.addContent(sc, item, deposit, authCredentials, config); - if (deposit.isMultipart()) - { - ContainerManagerDSpace cm = new ContainerManagerDSpace(); - result = cm.doAddMetadata(sc, item, deposit, authCredentials, config, result); - } + result = this + .addContent(sc, item, deposit, authCredentials, config); + if (deposit.isMultipart()) + { + ContainerManagerDSpace cm = new ContainerManagerDSpace(); + result = cm + .doAddMetadata(sc, item, deposit, authCredentials, + config, result); + } } catch (DSpaceSwordException | SwordError e) { @@ -650,13 +722,15 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR { try { - this.storePackageAsFile(deposit, authCredentials, config); - if (deposit.isMultipart()) - { - this.storeEntryAsFile(deposit, authCredentials, config); - } + this.storePackageAsFile(deposit, authCredentials, + config); + if (deposit.isMultipart()) + { + this.storeEntryAsFile(deposit, authCredentials, + config); + } } - catch(IOException e2) + catch (IOException e2) { log.warn("Unable to store SWORD package as file: " + e); } @@ -665,40 +739,43 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } // now we've produced a deposit, we need to decide on its workflow state - wfm.resolveState(context, deposit, null, this.verboseDescription, false); + wfm.resolveState(context, deposit, null, this.verboseDescription, + false); ReceiptGenerator genny = new ReceiptGenerator(); - // Now, this bit is tricky: - DepositReceipt receipt; - // If this was a single file deposit, then we don't return a receipt, we just - // want to specify the location header + // Now, this bit is tricky: + DepositReceipt receipt; + // If this was a single file deposit, then we don't return a receipt, we just + // want to specify the location header if (deposit.getPackaging().equals(UriRegistry.PACKAGE_BINARY)) - { - receipt = genny.createFileReceipt(context, result, config); - } - // if, on the other-hand, this was a package, then we want to generate a - // deposit receipt proper, but with the location being for the media resource - else - { - receipt = genny.createReceipt(context, result, config, true); - } + { + receipt = genny.createFileReceipt(context, result, config); + } + // if, on the other-hand, this was a package, then we want to generate a + // deposit receipt proper, but with the location being for the media resource + else + { + receipt = genny.createReceipt(context, result, config, true); + } Date finish = new Date(); long delta = finish.getTime() - start.getTime(); - this.verboseDescription.append("Total time for add processing: " + delta + " ms"); + this.verboseDescription + .append("Total time for add processing: " + delta + " ms"); this.addVerboseDescription(receipt, this.verboseDescription); // if something hasn't killed it already (allowed), then complete the transaction sc.commit(); - return receipt; + return receipt; } catch (DSpaceSwordException e) { log.error("caught exception:", e); - throw new SwordServerException("There was a problem depositing the item", e); + throw new SwordServerException( + "There was a problem depositing the item", e); } finally { @@ -710,98 +787,114 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR } } - private void removeContent(SwordContext swordContext, Item item, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordAuthException - { - try - { - // remove content only really means everything from the ORIGINAL bundle - VersionManager vm = new VersionManager(); - Iterator bundles = item.getBundles().iterator(); - while (bundles.hasNext()) - { + private void removeContent(SwordContext swordContext, Item item, + AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig) + throws DSpaceSwordException, SwordAuthException + { + try + { + // remove content only really means everything from the ORIGINAL bundle + VersionManager vm = new VersionManager(); + Iterator bundles = item.getBundles().iterator(); + while (bundles.hasNext()) + { Bundle bundle = bundles.next(); if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) { bundles.remove(); vm.removeBundle(swordContext.getContext(), item, bundle); } - } - } - catch (SQLException | IOException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + } + } + catch (SQLException | IOException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } } - private void removeBitstream(SwordContext swordContext, Bitstream bitstream, List items, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordAuthException - { - try - { - // remove content only really means everything from the ORIGINAL bundle - VersionManager vm = new VersionManager(); - for (Item item : items) - { - vm.removeBitstream(swordContext.getContext(), item, bitstream); - } - } - catch (SQLException | IOException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + private void removeBitstream(SwordContext swordContext, Bitstream bitstream, + List items, AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig) + throws DSpaceSwordException, SwordAuthException + { + try + { + // remove content only really means everything from the ORIGINAL bundle + VersionManager vm = new VersionManager(); + for (Item item : items) + { + vm.removeBitstream(swordContext.getContext(), item, bitstream); + } + } + catch (SQLException | IOException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } } - private void replaceContent(SwordContext swordContext, Item item, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException + private void replaceContent(SwordContext swordContext, Item item, + 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); + 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, item); - // Obtain the relevant ingester from the factory - SwordContentIngester si = SwordIngesterFactory.getContentInstance(context, deposit, null); - this.verboseDescription.append("Loaded ingester: " + si.getClass().getName()); + // Obtain the relevant ingester from the factory + SwordContentIngester si = SwordIngesterFactory + .getContentInstance(context, deposit, null); + this.verboseDescription + .append("Loaded ingester: " + si.getClass().getName()); - try - { - // delegate the to the version manager to get rid of any existing content and to version - // if if necessary - VersionManager vm = new VersionManager(); - vm.removeBundle(swordContext.getContext(), item, "ORIGINAL"); - } - catch (SQLException | IOException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + try + { + // delegate the to the version manager to get rid of any existing content and to version + // if if necessary + VersionManager vm = new VersionManager(); + vm.removeBundle(swordContext.getContext(), item, "ORIGINAL"); + } + catch (SQLException | IOException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } // do the deposit - DepositResult result = si.ingest(context, deposit, item, this.verboseDescription); - this.verboseDescription.append("Replace completed successfully"); + DepositResult result = si + .ingest(context, deposit, item, this.verboseDescription); + this.verboseDescription.append("Replace 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); } - private DepositResult replaceBitstream(SwordContext swordContext, List items, Bitstream bitstream, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException + private DepositResult replaceBitstream(SwordContext swordContext, + List items, Bitstream bitstream, Deposit deposit, + AuthCredentials authCredentials, + SwordConfigurationDSpace swordConfig) + throws DSpaceSwordException, SwordError, SwordAuthException, + SwordServerException { - // FIXME: this is basically not possible with the existing DSpace API. + // FIXME: this is basically not possible with the existing DSpace API. // We hack around it by deleting the old bitstream and // adding the new one and returning it, @@ -809,23 +902,27 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR // 405 the client // get the things out of the service that we need - Context context = swordContext.getContext(); - SwordUrlManager urlManager = swordConfig.getUrlManager(swordContext.getContext(), swordConfig); + Context context = swordContext.getContext(); + SwordUrlManager urlManager = swordConfig + .getUrlManager(swordContext.getContext(), swordConfig); // is the content acceptable to the items? If not, this will throw an error - for (Item item : items) - { - this.isAcceptable(swordConfig, context, deposit, item); - } - - // Obtain the relevant ingester from the factory - SwordContentIngester si = SwordIngesterFactory.getContentInstance(context, deposit, null); - this.verboseDescription.append("Loaded ingester: " + si.getClass().getName()); + for (Item item : items) + { + this.isAcceptable(swordConfig, context, deposit, item); + } - try - { + // Obtain the relevant ingester from the factory + SwordContentIngester si = SwordIngesterFactory + .getContentInstance(context, deposit, null); + this.verboseDescription + .append("Loaded ingester: " + si.getClass().getName()); + + try + { // first we delete the original bitstream - this.removeBitstream(swordContext, bitstream, items, authCredentials, swordConfig); + this.removeBitstream(swordContext, bitstream, items, + authCredentials, swordConfig); DepositResult result = null; boolean first = true; @@ -834,7 +931,8 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR if (first) { // just do this to the first item - result = this.addContent(swordContext, item, deposit, authCredentials, swordConfig); + result = this.addContent(swordContext, item, deposit, + authCredentials, swordConfig); } else { @@ -842,86 +940,106 @@ public class MediaResourceManagerDSpace extends DSpaceSwordAPI implements MediaR List bundles = item.getBundles(); if (!bundles.isEmpty()) { - bundleService.addBitstream(context, bundles.get(0), result.getOriginalDeposit()); + bundleService.addBitstream(context, bundles.get(0), + result.getOriginalDeposit()); } else { - Bundle bundle = bundleService.create(context, item, Constants.CONTENT_BUNDLE_NAME); - bundleService.addBitstream(context, bundle, result.getOriginalDeposit()); + Bundle bundle = bundleService.create(context, item, + Constants.CONTENT_BUNDLE_NAME); + bundleService.addBitstream(context, bundle, + result.getOriginalDeposit()); } } } // DepositResult result = si.ingest(context, deposit, items, this.verboseDescription); - this.verboseDescription.append("Replace completed successfully"); + this.verboseDescription.append("Replace completed successfully"); return result; - } - catch (SQLException e) - { - throw new DSpaceSwordException(e); - } - catch (AuthorizeException e) - { - throw new SwordAuthException(e); - } + } + catch (SQLException e) + { + throw new DSpaceSwordException(e); + } + catch (AuthorizeException e) + { + throw new SwordAuthException(e); + } } - private DepositResult addContent(SwordContext swordContext, Item item, Deposit deposit, AuthCredentials authCredentials, SwordConfigurationDSpace swordConfig) - throws DSpaceSwordException, SwordError, SwordAuthException, SwordServerException + private DepositResult addContent(SwordContext swordContext, Item item, + 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); + 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, item); - // Obtain the relevant ingester from the factory - SwordContentIngester si = SwordIngesterFactory.getContentInstance(context, deposit, null); - this.verboseDescription.append("Loaded ingester: " + si.getClass().getName()); + // Obtain the relevant ingester from the factory + SwordContentIngester si = SwordIngesterFactory + .getContentInstance(context, deposit, null); + this.verboseDescription + .append("Loaded ingester: " + si.getClass().getName()); - // do the deposit - DepositResult result = si.ingest(context, deposit, item, this.verboseDescription); - this.verboseDescription.append("Add completed successfully"); + // do the deposit + DepositResult result = si + .ingest(context, deposit, item, this.verboseDescription); + this.verboseDescription.append("Add 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; } - private Item getDSpaceTarget(Context context, String editMediaUrl, SwordConfigurationDSpace config) - throws DSpaceSwordException, SwordError - { - SwordUrlManager urlManager = config.getUrlManager(context, config); + private Item getDSpaceTarget(Context context, String editMediaUrl, + SwordConfigurationDSpace config) + throws DSpaceSwordException, SwordError + { + SwordUrlManager urlManager = config.getUrlManager(context, config); - // get the target collection - Item item = urlManager.getItem(context, editMediaUrl); + // get the target collection + Item item = urlManager.getItem(context, editMediaUrl); - this.verboseDescription.append("Performing replace using edit-media URL: " + editMediaUrl); - this.verboseDescription.append("Location resolves to item with handle: " + item.getHandle()); + this.verboseDescription + .append("Performing replace using edit-media URL: " + + editMediaUrl); + this.verboseDescription + .append("Location resolves to item with handle: " + + item.getHandle()); - return item; - } + return item; + } - private void checkAuth(SwordContext sc, Item item) - throws DSpaceSwordException, SwordError, SwordAuthException - { - Context context = sc.getContext(); - SwordAuthenticator auth = new SwordAuthenticator(); - if (!auth.canSubmit(sc, item, 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, "replace_failed_authorisation", "user=" + - sc.getAuthenticated().getEmail() + ",on_behalf_of=" + oboEmail)); - throw new SwordAuthException("Cannot replace the given item with this context"); - } - } + private void checkAuth(SwordContext sc, Item item) + throws DSpaceSwordException, SwordError, SwordAuthException + { + Context context = sc.getContext(); + SwordAuthenticator auth = new SwordAuthenticator(); + if (!auth.canSubmit(sc, item, 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, "replace_failed_authorisation", + "user=" + + sc.getAuthenticated().getEmail() + + ",on_behalf_of=" + oboEmail)); + throw new SwordAuthException( + "Cannot replace the given item with this context"); + } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/OreStatementDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/OreStatementDisseminator.java index 048e9dfaeb..cde93bbf3e 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/OreStatementDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/OreStatementDisseminator.java @@ -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 - * + *

* 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java index 1b8efff298..2d6ee46331 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ReceiptGenerator.java @@ -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 - * + *

* 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 derived = new HashMap(); - List 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 derived = new HashMap(); + List 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 bundles = result.getItem().getBundles(); - for (Bundle bundle : bundles) { + StringBuilder rightsString = new StringBuilder(); + List bundles = result.getItem().getBundles(); + for (Bundle bundle : bundles) + { if (!Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName())) { continue; } List 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 bundles = item.getBundles(); - for (Bundle bundle : bundles) { + StringBuilder rightsString = new StringBuilder(); + List bundles = item.getBundles(); + for (Bundle bundle : bundles) + { if (!Constants.LICENSE_BUNDLE_NAME.equals(bundle.getName())) { continue; } List 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 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 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 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 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 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 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 dcv = itemService.getMetadataByMetadataString(item, "dc.date.issued"); - if (dcv != null && dcv.size() == 1) + protected void addPublishDate(Item item, DepositReceipt receipt) + { + List 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 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 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 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 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); } } - } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/ServiceDocumentManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/ServiceDocumentManagerDSpace.java index 4a4ffddc83..8a88cd3eee 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/ServiceDocumentManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/ServiceDocumentManagerDSpace.java @@ -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 - * + *

* 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 comms = swordAuth.getAllowedCommunities(context); - for (Community comm : comms) - { - SwordCollection scol = comGen.buildCollection(context.getContext(), comm, swordConfig); - workspace.addCollection(scol); - } - } - else - { - List cols = swordAuth.getAllowedCollections(context); - for (Collection col : cols) - { - SwordCollection scol = colGen.buildCollection(context.getContext(), col, swordConfig); - workspace.addCollection(scol); - } - } + if (swordCommunities) + { + List comms = swordAuth + .getAllowedCommunities(context); + for (Community comm : comms) + { + SwordCollection scol = comGen + .buildCollection(context.getContext(), comm, + swordConfig); + workspace.addCollection(scol); + } + } + else + { + List 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 collections = swordAuth.getAllowedCollections(context, community); - for (Collection collection : collections) - { - SwordCollection scol = colGen.buildCollection(context.getContext(), collection, swordConfig); - workspace.addCollection(scol); - } + List collections = swordAuth + .getAllowedCollections(context, community); + for (Collection collection : collections) + { + SwordCollection scol = colGen + .buildCollection(context.getContext(), collection, + swordConfig); + workspace.addCollection(scol); + } - List communities = swordAuth.getCommunities(context, community); - for (Community comm : communities) - { - SwordCollection scol = comGen.buildCollection(context.getContext(), comm, swordConfig); - workspace.addCollection(scol); - } + List 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; - } - + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryDisseminator.java index 4852b39bf9..f408d8fe6f 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryDisseminator.java @@ -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 - * + *

* 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)) { diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryIngester.java index 5ba45f917f..847e8d536c 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCEntryIngester.java @@ -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 - * + *

* 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 existing = itemService.getMetadata(item, info.schema, info.element, qual, lang); + List 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> 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> 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCMetadata.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCMetadata.java index db57f3e3f9..b971ad9c4a 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCMetadata.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleDCMetadata.java @@ -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 - * + *

* http://www.dspace.org/license/ */ @@ -14,6 +14,7 @@ import java.util.Map; public class SimpleDCMetadata { private Map dublinCore = new HashMap(); + private Map atom = new HashMap(); public void addDublinCore(String element, String value) diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentDisseminator.java index aa62fafce1..d5bbd2f7c0 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentDisseminator.java @@ -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 - * + *

* 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 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(); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentIngester.java index 79f49dbcec..9b1bba47b6 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SimpleZipContentIngester.java @@ -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 - * + *

* 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 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 derivedResources = this.unzipToBundle(context, depositFile, original); + // unzip the file into the bundle + List 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 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 derivedResources = new ArrayList(); - 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 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 derivedResources = new ArrayList(); + 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 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 derivedResources = this.unzipToBundle(context, depositFile, original); + // we are now free to go and unpack the new zip into the original bundle + List 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"; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/StatementManagerDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/StatementManagerDSpace.java index 13465a3008..ca536425db 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/StatementManagerDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/StatementManagerDSpace.java @@ -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 - * + *

* 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 accept, AuthCredentials authCredentials, SwordConfiguration swordConfig) - throws SwordServerException, SwordError, SwordAuthException - { + public Statement getStatement(String stateIRI, Map 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> analysed = new HashMap<>(); List 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> analysed = this.analyseAccept(acceptContentType); + TreeMap> 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(); } } - } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordAuthenticator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordAuthenticator.java index 3f22bba4d7..de0b0262a8 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordAuthenticator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordAuthenticator.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -42,71 +42,83 @@ import java.util.ArrayList; /** * This class offers a thin wrapper for the default DSpace * authentication module for the SWORD implementation - * + * * @author Richard Jones * */ public class SwordAuthenticator { - /** logger */ - private static Logger log = Logger.getLogger(SwordAuthenticator.class); + /** logger */ + private static Logger log = Logger.getLogger(SwordAuthenticator.class); - protected AuthenticationService authenticationService = AuthenticateServiceFactory.getInstance().getAuthenticationService(); - protected AuthorizeService authorizeService = AuthorizeServiceFactory.getInstance().getAuthorizeService(); - protected EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); - protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService(); - protected ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + protected AuthenticationService authenticationService = AuthenticateServiceFactory + .getInstance().getAuthenticationService(); - /** - * 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) - { - int auth = authenticationService.authenticate(context, un, pw, null, null); - return auth == AuthenticationMethod.SUCCESS; - } + protected AuthorizeService authorizeService = AuthorizeServiceFactory + .getInstance().getAuthorizeService(); - /** - * Construct the context object member variable of this class - * using the passed IP address as part of the loggable - * information - * - * @throws org.dspace.sword2.DSpaceSwordException - */ - private Context constructContext() - throws DSpaceSwordException - { - Context context = new Context(); - // Set the session ID and IP address - context.setExtraLogInfo("session_id=0"); + protected EPersonService ePersonService = EPersonServiceFactory + .getInstance().getEPersonService(); - return context; - } + protected CommunityService communityService = ContentServiceFactory + .getInstance().getCommunityService(); - /** - * Authenticate the given service document request. This extracts the appropriate - * information from the request and forwards to the appropriate authentication - * method - * - * @param auth - * @return - * @throws DSpaceSwordException - * @throws SwordError - * @throws SwordAuthException - */ - public SwordContext authenticate(AuthCredentials auth) - throws DSpaceSwordException, SwordError, SwordAuthException - { - Context context = this.constructContext(); - SwordContext sc; - try + protected CollectionService collectionService = ContentServiceFactory + .getInstance().getCollectionService(); + + protected ItemService itemService = ContentServiceFactory.getInstance() + .getItemService(); + + /** + * 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) + { + int auth = authenticationService + .authenticate(context, un, pw, null, null); + return auth == AuthenticationMethod.SUCCESS; + } + + /** + * Construct the context object member variable of this class + * using the passed IP address as part of the loggable + * information + * + * @throws org.dspace.sword2.DSpaceSwordException + */ + private Context constructContext() + throws DSpaceSwordException + { + Context context = new Context(); + // Set the session ID and IP address + context.setExtraLogInfo("session_id=0"); + + return context; + } + + /** + * Authenticate the given service document request. This extracts the appropriate + * information from the request and forwards to the appropriate authentication + * method + * + * @param auth + * @return + * @throws DSpaceSwordException + * @throws SwordError + * @throws SwordAuthException + */ + public SwordContext authenticate(AuthCredentials auth) + throws DSpaceSwordException, SwordError, SwordAuthException + { + Context context = this.constructContext(); + SwordContext sc; + try { sc = this.authenticate(context, auth); } @@ -118,739 +130,801 @@ public class SwordAuthenticator } throw e; } - return sc; - } + return sc; + } - /** - * Authenticate the given username/password pair, in conjunction with - * the onBehalfOf user. The rules are that the username/password pair - * must successfully authenticate the user, and the onBehalfOf user - * must exist in the user database. - * - * @param context - * @param auth - * @return a SWORD context holding the various user information - * @throws SwordAuthException - * @throws SwordError - * @throws DSpaceSwordException - */ - private SwordContext authenticate(Context context, AuthCredentials auth) - throws SwordAuthException, SwordError, DSpaceSwordException - { - String obo = auth.getOnBehalfOf(); - String un = auth.getUsername(); - String pw = auth.getPassword(); + /** + * Authenticate the given username/password pair, in conjunction with + * the onBehalfOf user. The rules are that the username/password pair + * must successfully authenticate the user, and the onBehalfOf user + * must exist in the user database. + * + * @param context + * @param auth + * @return a SWORD context holding the various user information + * @throws SwordAuthException + * @throws SwordError + * @throws DSpaceSwordException + */ + private SwordContext authenticate(Context context, AuthCredentials auth) + throws SwordAuthException, SwordError, DSpaceSwordException + { + String obo = auth.getOnBehalfOf(); + String un = auth.getUsername(); + String pw = auth.getPassword(); - // smooth out the OnBehalfOf request, so that empty strings are - // treated as null - if ("".equals(obo)) - { - obo = null; - } + // smooth out the OnBehalfOf request, so that empty strings are + // treated as null + if ("".equals(obo)) + { + obo = null; + } - // first find out if we support on-behalf-of deposit - boolean mediated = ConfigurationManager.getBooleanProperty("swordv2-server", "on-behalf-of.enable"); - if (!mediated && obo != null) - { - // user is trying to do a mediated deposit on a repository which does not support it - log.error("Attempted mediated deposit on service not configured to do so"); - throw new SwordError(UriRegistry.ERROR_MEDIATION_NOT_ALLOWED, "Mediated deposit to this service is not permitted"); - } + // first find out if we support on-behalf-of deposit + boolean mediated = ConfigurationManager + .getBooleanProperty("swordv2-server", "on-behalf-of.enable"); + if (!mediated && obo != null) + { + // user is trying to do a mediated deposit on a repository which does not support it + log.error( + "Attempted mediated deposit on service not configured to do so"); + throw new SwordError(UriRegistry.ERROR_MEDIATION_NOT_ALLOWED, + "Mediated deposit to this service is not permitted"); + } - log.info(LogManager.getHeader(context, "sword_authenticate", "username=" + un + ",on_behalf_of=" + obo)); - - try - { - // attempt to authenticate the primary user - SwordContext sc = new SwordContext(); - EPerson ep = null; - boolean authenticated = false; - if (this.authenticates(context, un, pw)) - { - // if authenticated, obtain the eperson object - ep = context.getCurrentUser(); + log.info(LogManager.getHeader(context, "sword_authenticate", + "username=" + un + ",on_behalf_of=" + obo)); - if (ep != null) - { - authenticated = true; - sc.setAuthenticated(ep); - // Set any special groups - invoke the authentication mgr. - List specialGroups = authenticationService.getSpecialGroups(context, null); + try + { + // attempt to authenticate the primary user + SwordContext sc = new SwordContext(); + EPerson ep = null; + boolean authenticated = false; + if (this.authenticates(context, un, pw)) + { + // if authenticated, obtain the eperson object + ep = context.getCurrentUser(); - for (Group specialGroup : specialGroups) { - context.setSpecialGroup(specialGroup.getID()); - log.debug("Adding Special Group id=" + specialGroup.getID()); - } - - sc.setAuthenticatorContext(context); - sc.setContext(context); - } + if (ep != null) + { + authenticated = true; + sc.setAuthenticated(ep); + // Set any special groups - invoke the authentication mgr. + List specialGroups = authenticationService + .getSpecialGroups(context, null); - // if there is an onBehalfOfuser, then find their eperson - // record, and if it exists set it. If not, then the - // authentication process fails - EPerson epObo = null; - if (obo != null) - { - epObo = ePersonService.findByEmail(context, obo); - if (epObo == null) - { - epObo = ePersonService.findByNetid(context, obo); - } - - if (epObo != null) - { - sc.setOnBehalfOf(epObo); - Context oboContext = this.constructContext(); - oboContext.setCurrentUser(epObo); - // Set any special groups - invoke the authentication mgr. - List specialGroups = authenticationService.getSpecialGroups(oboContext, null); - - for (Group specialGroup : specialGroups) { - oboContext.setSpecialGroup(specialGroup.getID()); - log.debug("Adding Special Group id=" + specialGroup.getID()); - } - sc.setContext(oboContext); - } - else - { - authenticated = false; - throw new SwordError(UriRegistry.ERROR_TARGET_OWNER_UNKNOWN, "unable to identify on-behalf-of user: " + obo); - } - } - } - - if (!authenticated) - { - // decide what kind of error to throw - if (ep != null) - { - log.info(LogManager.getHeader(context, "sword_unable_to_set_user", "username=" + un)); - throw new SwordAuthException("Unable to authenticate with the supplied credentials"); - } - else - { - // FIXME: this shouldn't ever happen now, but may as well leave it in just in case - // there's a bug elsewhere - log.info(LogManager.getHeader(context, "sword_unable_to_set_on_behalf_of", "username=" + un + ",on_behalf_of=" + obo)); - throw new SwordAuthException("Unable to authenticate the onBehalfOf account"); - } - } - - return sc; - } - catch (SQLException e) - { - log.error("caught exception: ", e); - throw new DSpaceSwordException("There was a problem accessing the repository user database", e); - } - } - - /** - * Can the users contained in this object's member SwordContext - * make a successful submission to the selected collection. - * - * See javadocs for individual canSubmitTo methods to see the conditions - * which are applied in each situation - * - * @return true if yes, false if not - * @throws DSpaceSwordException - */ - public boolean canSubmit(SwordContext swordContext, DSpaceObject dso, VerboseDescription msg) - throws DSpaceSwordException, SwordError - { - // determine if we can submit - boolean submit = this.canSubmitTo(swordContext, dso); - - if (submit) - { - msg.append("User is authorised to submit to collection"); - } - else - { - msg.append("User is not authorised to submit to collection"); - } - - return submit; - } - - /** - * Is the authenticated user a DSpace administrator? This translates - * as asking the question of whether the given eperson is a member - * of the special DSpace group Administrator, with id 1 - * - * @param swordContext - * @return true if administrator, false if not - * @throws java.sql.SQLException - */ - public boolean isUserAdmin(SwordContext swordContext) - throws DSpaceSwordException - { - try - { - EPerson authenticated = swordContext.getAuthenticated(); - if (authenticated != null) - { - return authorizeService.isAdmin(swordContext.getAuthenticatorContext()); - } - return false; - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } - - /** - * Is the given onBehalfOf user DSpace administrator? This translates - * as asking the question of whether the given eperson is a member - * of the special DSpace group Administrator, with id 1 - * - * @param swordContext - * @return true if administrator, false if not - * @throws java.sql.SQLException - */ - public boolean isOnBehalfOfAdmin(SwordContext swordContext) - throws DSpaceSwordException - { - EPerson onBehalfOf = swordContext.getOnBehalfOf(); - try - { - if (onBehalfOf != null) - { - return authorizeService.isAdmin(swordContext.getOnBehalfOfContext()); - } - return false; - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } - - /** - * Is the authenticated user a member of the given group - * or one of its sub groups? - * - * @param group - */ - public boolean isUserInGroup(SwordContext swordContext, Group group) - { - EPerson authenticated = swordContext.getAuthenticated(); - if (authenticated != null) - { - return isInGroup(group, authenticated); - } - return false; - } - - /** - * Is the onBehalfOf user a member of the given group or - * one of its sub groups? - * - * @param group - */ - public boolean isOnBehalfOfInGroup(SwordContext swordContext, Group group) - { - EPerson onBehalfOf = swordContext.getOnBehalfOf(); - if (onBehalfOf != null) - { - return isInGroup(group, onBehalfOf); - } - return false; - } - - /** - * Is the given eperson in the given group, or any of the groups - * that are also members of that group. This method recurses - * until it has exhausted the tree of groups or finds the given - * eperson - * - * @param group - * @param eperson - * @return true if in group, false if not - */ - public boolean isInGroup(Group group, EPerson eperson) - { - List eps = group.getMembers(); - List groups = group.getMemberGroups(); - - // is the user in the current group - for (EPerson ep : eps) { - if (eperson.getID().equals(ep.getID())) { - return true; - } - } - - // is the eperson in the sub-groups (recurse) - if (groups != null && !groups.isEmpty()) - { - for (Group group1 : groups) { - if (isInGroup(group1, eperson)) { - return true; - } - } - } - - // ok, we didn't find you - return false; - } - - /** - * Get an array of all the communities that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * The user may submit to a community if the following conditions - * are met: - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to READ - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSwordException - */ - public List getAllowedCommunities(SwordContext swordContext) - throws DSpaceSwordException - { - // a community is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - // - the authenticated user is authorised to READ - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - try - { - // locate all the top level communities - Context context = swordContext.getContext(); - List allowed = new ArrayList(); - List comms = communityService.findAllTop(context); - for (Community comm : comms) - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), comm, Constants.READ); - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), comm, Constants.READ); - } - - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(comm); - } - } - return allowed; - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * The user may submit to a community if the following conditions - * are met: - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to READ - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to READ - * OR the on-behalf-of user is null) - * - * @param community - * @return the array of allowed collections - * @throws DSpaceSwordException - */ - public List getCommunities(SwordContext swordContext, Community community) - throws DSpaceSwordException - { - // a community is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - // - the authenticated user is authorised to READ - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to READ - // -- the on-behalf-of user is null - try - { - List comms = community.getSubcommunities(); - List allowed = new ArrayList<>(); - - for (Community comm : comms) - { - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), comm, Constants.READ); - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), comm, Constants.READ); - } - - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(comm); - } - } - return allowed; - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * Forwards to: - * - * getAllowedCollections(swordContext, null) - * - * See that method for details of the conditions applied - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSwordException - */ - public List getAllowedCollections(SwordContext swordContext) - throws DSpaceSwordException - { - return this.getAllowedCollections(swordContext, null); - } - - /** - * Get an array of all the collections that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to ADD - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSwordException - */ - public List getAllowedCollections(SwordContext swordContext, Community community) - throws DSpaceSwordException - { - // a collection is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD - // -- the on-behalf-of user is null - // - the authenticated user is authorised to ADD - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD - // -- the on-behalf-of user is null - - try - { - // get the context of the authenticated user - Context authContext = swordContext.getAuthenticatorContext(); - - // short cut by obtaining the collections to which the authenticated user can submit - List cols = collectionService.findAuthorized(authContext, community, Constants.ADD); - List allowed = new ArrayList<>(); - - // now find out if the obo user is allowed to submit to any of these collections - for (Collection col : cols) - { - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), col, Constants.ADD); - } - - // final check to see if we are allowed to READ - if (oboAllowed) - { - allowed.add(col); - } - } - return allowed; - - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } - - /** - * Get a list of all the items that the current SWORD - * context will allow deposit onto in the given DSpace context - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - * OR the on-behalf-of user is null) - * - * @param swordContext - * @return the array of allowed collections - * @throws DSpaceSwordException - */ - public List getAllowedItems(SwordContext swordContext, org.dspace.content.Collection collection) - throws DSpaceSwordException - { - // an item is allowed if the following conditions are met - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle - // -- the on-behalf-of user is null - - try - { - List allowed = new ArrayList<>(); - Iterator ii = itemService.findByCollection(swordContext.getContext(), collection); - - while (ii.hasNext()) - { - Item item = ii.next(); - - boolean authAllowed = false; - boolean oboAllowed = false; - - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } - - // get the "ORIGINAL" bundle(s) - List bundles = item.getBundles(); - - // look up the READ policy on the community. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), item, Constants.WRITE); - - boolean add = false; - if (bundles.isEmpty()) + for (Group specialGroup : specialGroups) { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), item, Constants.ADD); + context.setSpecialGroup(specialGroup.getID()); + log.debug("Adding Special Group id=" + + specialGroup.getID()); + } + + sc.setAuthenticatorContext(context); + sc.setContext(context); + } + + // if there is an onBehalfOfuser, then find their eperson + // record, and if it exists set it. If not, then the + // authentication process fails + EPerson epObo = null; + if (obo != null) + { + epObo = ePersonService.findByEmail(context, obo); + if (epObo == null) + { + epObo = ePersonService.findByNetid(context, obo); + } + + if (epObo != null) + { + sc.setOnBehalfOf(epObo); + Context oboContext = this.constructContext(); + oboContext.setCurrentUser(epObo); + // Set any special groups - invoke the authentication mgr. + List specialGroups = authenticationService + .getSpecialGroups(oboContext, null); + + for (Group specialGroup : specialGroups) + { + oboContext.setSpecialGroup(specialGroup.getID()); + log.debug("Adding Special Group id=" + + specialGroup.getID()); + } + sc.setContext(oboContext); } else { - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - } + authenticated = false; + throw new SwordError( + UriRegistry.ERROR_TARGET_OWNER_UNKNOWN, + "unable to identify on-behalf-of user: " + obo); } + } + } - authAllowed = write && add; - } + if (!authenticated) + { + // decide what kind of error to throw + if (ep != null) + { + log.info(LogManager + .getHeader(context, "sword_unable_to_set_user", + "username=" + un)); + throw new SwordAuthException( + "Unable to authenticate with the supplied credentials"); + } + else + { + // FIXME: this shouldn't ever happen now, but may as well leave it in just in case + // there's a bug elsewhere + log.info(LogManager.getHeader(context, + "sword_unable_to_set_on_behalf_of", + "username=" + un + ",on_behalf_of=" + obo)); + throw new SwordAuthException( + "Unable to authenticate the onBehalfOf account"); + } + } - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - boolean write = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), item, Constants.WRITE); + return sc; + } + catch (SQLException e) + { + log.error("caught exception: ", e); + throw new DSpaceSwordException( + "There was a problem accessing the repository user database", + e); + } + } - boolean add = false; - if (bundles.isEmpty()) + /** + * Can the users contained in this object's member SwordContext + * make a successful submission to the selected collection. + * + * See javadocs for individual canSubmitTo methods to see the conditions + * which are applied in each situation + * + * @return true if yes, false if not + * @throws DSpaceSwordException + */ + public boolean canSubmit(SwordContext swordContext, DSpaceObject dso, + VerboseDescription msg) + throws DSpaceSwordException, SwordError + { + // determine if we can submit + boolean submit = this.canSubmitTo(swordContext, dso); + + if (submit) + { + msg.append("User is authorised to submit to collection"); + } + else + { + msg.append("User is not authorised to submit to collection"); + } + + return submit; + } + + /** + * Is the authenticated user a DSpace administrator? This translates + * as asking the question of whether the given eperson is a member + * of the special DSpace group Administrator, with id 1 + * + * @param swordContext + * @return true if administrator, false if not + * @throws java.sql.SQLException + */ + public boolean isUserAdmin(SwordContext swordContext) + throws DSpaceSwordException + { + try + { + EPerson authenticated = swordContext.getAuthenticated(); + if (authenticated != null) + { + return authorizeService + .isAdmin(swordContext.getAuthenticatorContext()); + } + return false; + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } + + /** + * Is the given onBehalfOf user DSpace administrator? This translates + * as asking the question of whether the given eperson is a member + * of the special DSpace group Administrator, with id 1 + * + * @param swordContext + * @return true if administrator, false if not + * @throws java.sql.SQLException + */ + public boolean isOnBehalfOfAdmin(SwordContext swordContext) + throws DSpaceSwordException + { + EPerson onBehalfOf = swordContext.getOnBehalfOf(); + try + { + if (onBehalfOf != null) + { + return authorizeService + .isAdmin(swordContext.getOnBehalfOfContext()); + } + return false; + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } + + /** + * Is the authenticated user a member of the given group + * or one of its sub groups? + * + * @param group + */ + public boolean isUserInGroup(SwordContext swordContext, Group group) + { + EPerson authenticated = swordContext.getAuthenticated(); + if (authenticated != null) + { + return isInGroup(group, authenticated); + } + return false; + } + + /** + * Is the onBehalfOf user a member of the given group or + * one of its sub groups? + * + * @param group + */ + public boolean isOnBehalfOfInGroup(SwordContext swordContext, Group group) + { + EPerson onBehalfOf = swordContext.getOnBehalfOf(); + if (onBehalfOf != null) + { + return isInGroup(group, onBehalfOf); + } + return false; + } + + /** + * Is the given eperson in the given group, or any of the groups + * that are also members of that group. This method recurses + * until it has exhausted the tree of groups or finds the given + * eperson + * + * @param group + * @param eperson + * @return true if in group, false if not + */ + public boolean isInGroup(Group group, EPerson eperson) + { + List eps = group.getMembers(); + List groups = group.getMemberGroups(); + + // is the user in the current group + for (EPerson ep : eps) + { + if (eperson.getID().equals(ep.getID())) + { + return true; + } + } + + // is the eperson in the sub-groups (recurse) + if (groups != null && !groups.isEmpty()) + { + for (Group group1 : groups) + { + if (isInGroup(group1, eperson)) + { + return true; + } + } + } + + // ok, we didn't find you + return false; + } + + /** + * Get an array of all the communities that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * The user may submit to a community if the following conditions + * are met: + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to READ + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSwordException + */ + public List getAllowedCommunities(SwordContext swordContext) + throws DSpaceSwordException + { + // a community is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + // - the authenticated user is authorised to READ + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + try + { + // locate all the top level communities + Context context = swordContext.getContext(); + List allowed = new ArrayList(); + List comms = communityService.findAllTop(context); + for (Community comm : comms) + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), comm, + Constants.READ); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), comm, + Constants.READ); + } + + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(comm); + } + } + return allowed; + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * The user may submit to a community if the following conditions + * are met: + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to READ + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to READ + * OR the on-behalf-of user is null) + * + * @param community + * @return the array of allowed collections + * @throws DSpaceSwordException + */ + public List getCommunities(SwordContext swordContext, + Community community) + throws DSpaceSwordException + { + // a community is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + // - the authenticated user is authorised to READ + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to READ + // -- the on-behalf-of user is null + try + { + List comms = community.getSubcommunities(); + List allowed = new ArrayList<>(); + + for (Community comm : comms) + { + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), comm, + Constants.READ); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), comm, + Constants.READ); + } + + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(comm); + } + } + return allowed; + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * Forwards to: + * + * getAllowedCollections(swordContext, null) + * + * See that method for details of the conditions applied + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSwordException + */ + public List getAllowedCollections( + SwordContext swordContext) + throws DSpaceSwordException + { + return this.getAllowedCollections(swordContext, null); + } + + /** + * Get an array of all the collections that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to ADD + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSwordException + */ + public List getAllowedCollections( + SwordContext swordContext, Community community) + throws DSpaceSwordException + { + // a collection is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD + // -- the on-behalf-of user is null + // - the authenticated user is authorised to ADD + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD + // -- the on-behalf-of user is null + + try + { + // get the context of the authenticated user + Context authContext = swordContext.getAuthenticatorContext(); + + // short cut by obtaining the collections to which the authenticated user can submit + List cols = collectionService + .findAuthorized(authContext, community, Constants.ADD); + List allowed = new ArrayList<>(); + + // now find out if the obo user is allowed to submit to any of these collections + for (Collection col : cols) + { + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), col, + Constants.ADD); + } + + // final check to see if we are allowed to READ + if (oboAllowed) + { + allowed.add(col); + } + } + return allowed; + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } + + /** + * Get a list of all the items that the current SWORD + * context will allow deposit onto in the given DSpace context + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + * OR the on-behalf-of user is null) + * + * @param swordContext + * @return the array of allowed collections + * @throws DSpaceSwordException + */ + public List getAllowedItems(SwordContext swordContext, + org.dspace.content.Collection collection) + throws DSpaceSwordException + { + // an item is allowed if the following conditions are met + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + // - the authenticated user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to WRITE on the item and ADD on the ORIGINAL bundle + // -- the on-behalf-of user is null + + try + { + List allowed = new ArrayList<>(); + Iterator ii = itemService + .findByCollection(swordContext.getContext(), collection); + + while (ii.hasNext()) + { + Item item = ii.next(); + + boolean authAllowed = false; + boolean oboAllowed = false; + + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } + + // get the "ORIGINAL" bundle(s) + List bundles = item.getBundles(); + + // look up the READ policy on the community. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), item, + Constants.WRITE); + + boolean add = false; + if (bundles.isEmpty()) { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), item, Constants.ADD); + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), item, + Constants.ADD); } else { - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), bundle, Constants.ADD); - if (!add) - { - break; - } - } - } + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME + .equals(bundle.getName())) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), + bundle, Constants.ADD); + if (!add) + { + break; + } + } + } } - oboAllowed = write && add; - } + authAllowed = write && add; + } - // final check to see if we are allowed to READ - if (authAllowed && oboAllowed) - { - allowed.add(item); - } - } + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + boolean write = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), item, + Constants.WRITE); - return allowed; - } - catch (SQLException e) - { - throw new DSpaceSwordException(e); - } - } + boolean add = false; + if (bundles.isEmpty()) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), item, + Constants.ADD); + } + else + { + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME + .equals(bundle.getName())) + { + add = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), + bundle, Constants.ADD); + if (!add) + { + break; + } + } + } + } - /** - * Can the current SWORD Context permit deposit into the given - * collection in the given DSpace Context? - * - * IF: the authenticated user is an administrator - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * OR IF: the authenticated user is authorised to ADD - * AND: - * (the on-behalf-of user is an administrator - * OR the on-behalf-of user is authorised to ADD - * OR the on-behalf-of user is null) - * - * @param swordContext - * @param collection - * @throws DSpaceSwordException - */ - public boolean canSubmitTo(SwordContext swordContext, org.dspace.content.Collection collection) - throws DSpaceSwordException - { - // a user can submit to a collection in the following conditions: - // - // - the authenticated user is an administrator - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD/in the submission group - // -- the on-behalf-of user is null - // - the authenticated user is authorised to ADD/in the submission group - // -- the on-behalf-of user is an administrator - // -- the on-behalf-of user is authorised to ADD/in the submission group - // -- the on-behalf-of user is null + oboAllowed = write && add; + } - try - { - boolean authAllowed = false; - boolean oboAllowed = false; + // final check to see if we are allowed to READ + if (authAllowed && oboAllowed) + { + allowed.add(item); + } + } - // check for obo null - if (swordContext.getOnBehalfOf() == null) - { - oboAllowed = true; - } + return allowed; + } + catch (SQLException e) + { + throw new DSpaceSwordException(e); + } + } - // look up the READ policy on the collection. This will include determining if the user is an administrator - // so we do not need to check that separately - if (!authAllowed) - { - authAllowed = authorizeService.authorizeActionBoolean(swordContext.getAuthenticatorContext(), collection, Constants.ADD); - } + /** + * Can the current SWORD Context permit deposit into the given + * collection in the given DSpace Context? + * + * IF: the authenticated user is an administrator + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * OR IF: the authenticated user is authorised to ADD + * AND: + * (the on-behalf-of user is an administrator + * OR the on-behalf-of user is authorised to ADD + * OR the on-behalf-of user is null) + * + * @param swordContext + * @param collection + * @throws DSpaceSwordException + */ + public boolean canSubmitTo(SwordContext swordContext, + org.dspace.content.Collection collection) + throws DSpaceSwordException + { + // a user can submit to a collection in the following conditions: + // + // - the authenticated user is an administrator + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD/in the submission group + // -- the on-behalf-of user is null + // - the authenticated user is authorised to ADD/in the submission group + // -- the on-behalf-of user is an administrator + // -- the on-behalf-of user is authorised to ADD/in the submission group + // -- the on-behalf-of user is null - // if we have not already determined that the obo user is ok to submit, look up the READ policy on the - // community. THis will include determining if the user is an administrator. - if (!oboAllowed) - { - oboAllowed = authorizeService.authorizeActionBoolean(swordContext.getOnBehalfOfContext(), collection, Constants.ADD); - } + try + { + boolean authAllowed = false; + boolean oboAllowed = false; - // final check to see if we are allowed to READ - return (authAllowed && oboAllowed); + // check for obo null + if (swordContext.getOnBehalfOf() == null) + { + oboAllowed = true; + } - } - catch (SQLException e) - { - log.error("Caught exception: ", e); - throw new DSpaceSwordException(e); - } - } + // look up the READ policy on the collection. This will include determining if the user is an administrator + // so we do not need to check that separately + if (!authAllowed) + { + authAllowed = authorizeService.authorizeActionBoolean( + swordContext.getAuthenticatorContext(), collection, + Constants.ADD); + } + + // if we have not already determined that the obo user is ok to submit, look up the READ policy on the + // community. THis will include determining if the user is an administrator. + if (!oboAllowed) + { + oboAllowed = authorizeService.authorizeActionBoolean( + swordContext.getOnBehalfOfContext(), collection, + Constants.ADD); + } + + // final check to see if we are allowed to READ + return (authAllowed && oboAllowed); + + } + catch (SQLException e) + { + log.error("Caught exception: ", e); + throw new DSpaceSwordException(e); + } + } public boolean canSubmitTo(SwordContext swordContext, Item item) throws DSpaceSwordException @@ -872,7 +946,8 @@ public class SwordAuthenticator if (isObo) { // we need to find out if the authenticated user is permitted to mediate - if (!this.allowedToMediate(swordContext.getAuthenticatorContext())) + if (!this.allowedToMediate( + swordContext.getAuthenticatorContext())) { return false; } @@ -885,27 +960,33 @@ public class SwordAuthenticator // we now need to check whether the selected context that we are authorising // has the appropriate permissions - boolean write = authorizeService.authorizeActionBoolean(allowContext, item, Constants.WRITE); + boolean write = authorizeService + .authorizeActionBoolean(allowContext, item, + Constants.WRITE); List bundles = item.getBundles(); boolean add = false; if (bundles.isEmpty()) { - add = authorizeService.authorizeActionBoolean(allowContext, item, Constants.ADD); + add = authorizeService + .authorizeActionBoolean(allowContext, item, + Constants.ADD); } else { - for (Bundle bundle : bundles) - { - if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) - { - add = authorizeService.authorizeActionBoolean(allowContext, bundle, Constants.ADD); - if (!add) - { - break; - } - } - } + for (Bundle bundle : bundles) + { + if (Constants.CONTENT_BUNDLE_NAME.equals(bundle.getName())) + { + add = authorizeService + .authorizeActionBoolean(allowContext, bundle, + Constants.ADD); + if (!add) + { + break; + } + } + } } boolean allowed = write && add; @@ -921,7 +1002,8 @@ public class SwordAuthenticator private boolean allowedToMediate(Context context) { // get the configuration - String mediatorCfg = ConfigurationManager.getProperty("swordv2-server", "on-behalf-of.update.mediators"); + String mediatorCfg = ConfigurationManager + .getProperty("swordv2-server", "on-behalf-of.update.mediators"); if (mediatorCfg == null) { // if there's no explicit list of mediators, then anyone can mediate @@ -954,22 +1036,24 @@ public class SwordAuthenticator return false; } - /** - * Can the given context submit to the specified DSpace object? - * - * This forwards to the individual methods for different object types; - * see their documentation for details of the conditions. - * - * @param context - * @param dso - * @throws DSpaceSwordException - */ - public boolean canSubmitTo(SwordContext context, DSpaceObject dso) - throws DSpaceSwordException - { - if (dso instanceof Collection) { - return this.canSubmitTo(context, (Collection) dso); - } else - return dso instanceof Item && this.canSubmitTo(context, (Item) dso); - } + /** + * Can the given context submit to the specified DSpace object? + * + * This forwards to the individual methods for different object types; + * see their documentation for details of the conditions. + * + * @param context + * @param dso + * @throws DSpaceSwordException + */ + public boolean canSubmitTo(SwordContext context, DSpaceObject dso) + throws DSpaceSwordException + { + if (dso instanceof Collection) + { + return this.canSubmitTo(context, (Collection) dso); + } + else + return dso instanceof Item && this.canSubmitTo(context, (Item) dso); + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordConfigurationDSpace.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordConfigurationDSpace.java index 21c35f15ec..202df032ac 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordConfigurationDSpace.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordConfigurationDSpace.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -29,73 +29,83 @@ import java.util.Set; public class SwordConfigurationDSpace implements SwordConfiguration { - /** logger */ - public static final Logger log = Logger.getLogger(SwordConfigurationDSpace.class); + /** logger */ + public static final Logger log = Logger + .getLogger(SwordConfigurationDSpace.class); - protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory.getInstance().getBitstreamFormatService(); + protected BitstreamFormatService bitstreamFormatService = ContentServiceFactory + .getInstance().getBitstreamFormatService(); - /** 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; - private boolean allowCommunityDeposit = false; + private boolean allowCommunityDeposit = false; private boolean entryFirst = false; /** Accepted formats */ private List swordaccepts; - /** - * Initialise the sword configuration. It is at this stage that the - * object will interrogate the DSpace Configuration for details - */ - public SwordConfigurationDSpace() - { - // set the max upload size - int mus = ConfigurationManager.getIntProperty("swordv2-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 SwordConfigurationDSpace() + { + // set the max upload size + int mus = ConfigurationManager + .getIntProperty("swordv2-server", "max-upload-size"); + if (mus > 0) + { + this.maxUploadSize = mus; + } - // set the mediation value - this.mediated = ConfigurationManager.getBooleanProperty("swordv2-server", "on-behalf-of.enable"); + // set the mediation value + this.mediated = ConfigurationManager + .getBooleanProperty("swordv2-server", "on-behalf-of.enable"); - // find out if we keep the original as bitstream - this.keepOriginal = ConfigurationManager.getBooleanProperty("swordv2-server", "keep-original-package"); + // find out if we keep the original as bitstream + this.keepOriginal = ConfigurationManager + .getBooleanProperty("swordv2-server", "keep-original-package"); - // get the sword bundle - String bundle = ConfigurationManager.getProperty("swordv2-server", "bundle.name"); - if (bundle != null && "".equals(bundle)) - { - this.swordBundle = bundle; - } + // get the sword bundle + String bundle = ConfigurationManager + .getProperty("swordv2-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("swordv2-server", "keep-package-on-fail", false); + this.keepPackageOnFailedIngest = ConfigurationManager + .getBooleanProperty("swordv2-server", "keep-package-on-fail", + false); // get directory path and name - this.failedPackageDir = ConfigurationManager.getProperty("swordv2-server", "failed-package.dir"); + this.failedPackageDir = ConfigurationManager + .getProperty("swordv2-server", "failed-package.dir"); // Get the accepted formats - String acceptsProperty = ConfigurationManager.getProperty("swordv2-server", "accepts"); + String acceptsProperty = ConfigurationManager + .getProperty("swordv2-server", "accepts"); swordaccepts = new ArrayList(); if (acceptsProperty == null) { @@ -106,20 +116,25 @@ public class SwordConfigurationDSpace implements SwordConfiguration swordaccepts.add(element.trim()); } - // find out if community deposit is allowed - this.allowCommunityDeposit = ConfigurationManager.getBooleanProperty("swordv2-server", "allow-community-deposit"); + // find out if community deposit is allowed + this.allowCommunityDeposit = ConfigurationManager + .getBooleanProperty("swordv2-server", + "allow-community-deposit"); // find out if we keep the package as a file in specified directory - this.entryFirst = ConfigurationManager.getBooleanProperty("swordv2-server", "multipart.entry-first", false); + this.entryFirst = ConfigurationManager + .getBooleanProperty("swordv2-server", "multipart.entry-first", + false); - } + } - //////////////////////////////////////////////////////////////////////////////////// - // Utilities - /////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + // Utilities + /////////////////////////////////////////////////////////////////////////////////// - public String getStringProperty(String module, String propName, String defaultValue, String[] allowedValues) - { + public String getStringProperty(String module, String propName, + String defaultValue, String[] allowedValues) + { String cfg; if (module == null) { @@ -127,121 +142,127 @@ public class SwordConfigurationDSpace implements SwordConfiguration } else { - cfg = ConfigurationManager.getProperty(module, propName); + cfg = ConfigurationManager.getProperty(module, propName); } - if (cfg == null || "".equals(cfg)) - { - return defaultValue; - } - boolean allowed = false; - if (allowedValues != null) - { - for (String value : allowedValues) - { - if (cfg.equals(value)) - { - allowed = true; - } - } - } - else - { - allowed = true; - } - if (allowed) - { - return cfg; - } - return defaultValue; - } + if (cfg == null || "".equals(cfg)) + { + return defaultValue; + } + boolean allowed = false; + if (allowedValues != null) + { + for (String value : allowedValues) + { + if (cfg.equals(value)) + { + allowed = true; + } + } + } + else + { + allowed = true; + } + if (allowed) + { + return cfg; + } + return defaultValue; + } - public String getStringProperty(String module, String propName, String defaultValue) - { - return this.getStringProperty(module, propName, defaultValue, null); - } + public String getStringProperty(String module, String propName, + String defaultValue) + { + return this.getStringProperty(module, propName, defaultValue, null); + } - /////////////////////////////////////////////////////////////////////////////////// - // Required by the SwordConfiguration interface - ////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////// + // Required by the SwordConfiguration interface + ////////////////////////////////////////////////////////////////////////////////// + public boolean returnDepositReceipt() + { + return true; + } + public boolean returnStackTraceInError() + { + return ConfigurationManager.getBooleanProperty("swordv2-server", + "verbose-description.error.enable"); + } - public boolean returnDepositReceipt() - { - return true; - } + public boolean returnErrorBody() + { + return true; + } - public boolean returnStackTraceInError() - { - return ConfigurationManager.getBooleanProperty("swordv2-server", "verbose-description.error.enable"); - } + public String generator() + { + return this.getStringProperty("swordv2-server", "generator.url", + DSpaceUriRegistry.DSPACE_SWORD_NS); + } - public boolean returnErrorBody() - { - return true; - } + public String generatorVersion() + { + return this.getStringProperty("swordv2-server", "generator.version", + "2.0"); + } - public String generator() - { - return this.getStringProperty("swordv2-server", "generator.url", DSpaceUriRegistry.DSPACE_SWORD_NS); - } + public String administratorEmail() + { + return this.getStringProperty(null, "mail.admin", null); + } - public String generatorVersion() - { - return this.getStringProperty("swordv2-server", "generator.version", "2.0"); - } + public String getAuthType() + { + return this.getStringProperty("swordv2-server", "auth-type", "Basic", + new String[] { "Basic", "None" }); + } - public String administratorEmail() - { - return this.getStringProperty(null, "mail.admin", null); - } + public boolean storeAndCheckBinary() + { + return true; + } - public String getAuthType() - { - return this.getStringProperty("swordv2-server", "auth-type", "Basic", new String[] { "Basic", "None" } ); - } - - public boolean storeAndCheckBinary() - { - return true; - } - - public String getTempDirectory() - { - return this.getStringProperty("swordv2-server", "upload.tempdir", null); - } + public String getTempDirectory() + { + return this.getStringProperty("swordv2-server", "upload.tempdir", null); + } public String getAlternateUrl() { - return ConfigurationManager.getProperty("swordv2-server", "error.alternate.url"); + return ConfigurationManager + .getProperty("swordv2-server", "error.alternate.url"); } public String getAlternateUrlContentType() { - return ConfigurationManager.getProperty("swordv2-server", "error.alternate.content-type"); + return ConfigurationManager + .getProperty("swordv2-server", "error.alternate.content-type"); } /////////////////////////////////////////////////////////////////////////////////// - // Required by DSpace-side implementation - /////////////////////////////////////////////////////////////////////////////////// + // Required by DSpace-side implementation + /////////////////////////////////////////////////////////////////////////////////// - public SwordUrlManager getUrlManager(Context context, SwordConfigurationDSpace config) - { - return new SwordUrlManager(config, context); - } + public SwordUrlManager getUrlManager(Context context, + SwordConfigurationDSpace config) + { + return new SwordUrlManager(config, context); + } - public List getDisseminatePackaging() + public List getDisseminatePackaging() throws DSpaceSwordException, SwordError - { - List dps = new ArrayList(); - Properties props = ConfigurationManager.getProperties("swordv2-server"); + { + List dps = new ArrayList(); + Properties props = ConfigurationManager.getProperties("swordv2-server"); Set keyset = props.keySet(); for (Object keyObj : keyset) { - // start by getting anything that starts with sword.disseminate-packging. - String sw = "disseminate-packaging."; + // start by getting anything that starts with sword.disseminate-packging. + String sw = "disseminate-packaging."; - if (!(keyObj instanceof String)) + if (!(keyObj instanceof String)) { continue; } @@ -252,14 +273,15 @@ public class SwordConfigurationDSpace implements SwordConfiguration continue; } - String value = props.getProperty((key)); + String value = props.getProperty((key)); // now we want to ensure that the packaging format we offer has a disseminator // associated with it boolean disseminable = true; try { - SwordContentDisseminator disseminator = SwordDisseminatorFactory.getContentInstance(null, value); + SwordContentDisseminator disseminator = SwordDisseminatorFactory + .getContentInstance(null, value); } catch (SwordError e) { @@ -268,290 +290,239 @@ public class SwordConfigurationDSpace implements SwordConfiguration if (disseminable) { - dps.add(value); + dps.add(value); } - } - return dps; - } + } + return dps; + } public boolean isEntryFirst() { return this.entryFirst; } - public boolean allowCommunityDeposit() - { - return this.allowCommunityDeposit; - } - - /** - * Get the bundle name that sword will store its original deposit packages in, when - * storing them inside an item - * @return - */ - 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 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; - } + public boolean allowCommunityDeposit() + { + return this.allowCommunityDeposit; + } /** - * 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 + * @return + */ + 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 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 getAccepts(Context context, DSpaceObject dso) - throws DSpaceSwordException - { - try - { - List accepts = new ArrayList(); - 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 getAccepts(Context context, DSpaceObject dso) + throws DSpaceSwordException + { + try + { + List accepts = new ArrayList(); + if (dso instanceof Collection) + { + for (String format : swordaccepts) { accepts.add(format); } - } - else if (dso instanceof Item) - { - // items will take any of the bitstream formats registered, plus - // any swordaccepts mimetypes - List bfs = bitstreamFormatService.findNonInternal(context); - for (BitstreamFormat bf : bfs) { - accepts.add(bf.getMIMEType()); - } - for (String format : swordaccepts) + } + else if (dso instanceof Item) + { + // items will take any of the bitstream formats registered, plus + // any swordaccepts mimetypes + List bfs = bitstreamFormatService + .findNonInternal(context); + for (BitstreamFormat bf : bfs) { - if (!accepts.contains(format)) - { - accepts.add(format); - } + accepts.add(bf.getMIMEType()); } - } + for (String format : swordaccepts) + { + if (!accepts.contains(format)) + { + accepts.add(format); + } + } + } - 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 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 getCollectionAccepts() throws DSpaceSwordException + { List accepts = new ArrayList(); 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 List getAcceptPackaging(Collection col) - { - // accept-packaging.METSDSpaceSIP = http://purl.org/net/sword-types/METSDSpaceSIP - // accept-packaging.[handle].METSDSpaceSIP = http://purl.org/net/sword-types/METSDSpaceSIP - String handle = col.getHandle(); - List aps = new ArrayList(); - - // build the holding maps of identifiers - Properties props = ConfigurationManager.getProperties("swordv2-server"); - Set keyset = props.keySet(); - for (Object keyObj : keyset) - { - // start by getting anything that starts with sword.accept-packaging.collection. - String sw = "accept-packaging.collection."; - - if (!(keyObj instanceof String)) - { - continue; - } - String key = (String) keyObj; - - if (!key.startsWith(sw)) - { - continue; - } - - // extract the configuration into the holding Maps - - // the suffix will be [typeid] or [handle].[typeid] - String suffix = key.substring(sw.length()); - - // is there a handle which represents this collection? - boolean withHandle = false; - if (suffix.startsWith(handle)) - { - withHandle = true; - } - - // is there NO handle - boolean general = false; - if (suffix.indexOf(".") == -1) - { - // a handle would be separated from the identifier of the package type - general = true; - } - - if (withHandle || general) - { - String value = props.getProperty((key)); - aps.add(value); - } - } - - return aps; } - public List getItemAcceptPackaging() - { - List aps = new ArrayList(); + /** + * 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 List getAcceptPackaging(Collection col) + { + // accept-packaging.METSDSpaceSIP = http://purl.org/net/sword-types/METSDSpaceSIP + // accept-packaging.[handle].METSDSpaceSIP = http://purl.org/net/sword-types/METSDSpaceSIP + String handle = col.getHandle(); + List aps = new ArrayList(); - // build the holding maps of identifiers + // build the holding maps of identifiers Properties props = ConfigurationManager.getProperties("swordv2-server"); Set keyset = props.keySet(); for (Object keyObj : keyset) { - // start by getting anything that starts with sword.accept-packging.collection. - String sw = "accept-packaging.item."; + // start by getting anything that starts with sword.accept-packaging.collection. + String sw = "accept-packaging.collection."; if (!(keyObj instanceof String)) { @@ -564,68 +535,122 @@ public class SwordConfigurationDSpace implements SwordConfiguration continue; } - // extract the configuration into the holding Maps - String value = props.getProperty((key)); - aps.add(value); - } + // extract the configuration into the holding Maps - return aps; - } + // the suffix will be [typeid] or [handle].[typeid] + String suffix = key.substring(sw.length()); - /** - * Is the given packaging/media type supported by the given DSpace - * object? - * - * @param packageFormat - * @param dso - * @throws DSpaceSwordException - * @throws SwordError - */ - public boolean isAcceptedPackaging(String packageFormat, DSpaceObject dso) - throws DSpaceSwordException, SwordError - { - if (packageFormat == null || "".equals(packageFormat)) - { - return true; - } + // is there a handle which represents this collection? + boolean withHandle = false; + if (suffix.startsWith(handle)) + { + withHandle = true; + } - if (dso instanceof Collection) - { - List accepts = this.getAcceptPackaging((Collection) dso); - for (String accept : accepts) - { - if (accept.equals(packageFormat)) - { - return true; - } - } - } - else if (dso instanceof Item) - { - List accepts = this.getItemAcceptPackaging(); - for (String accept : accepts) - { - if (accept.equals(packageFormat)) - { - return true; - } - } - } - - return false; - } + // is there NO handle + boolean general = false; + if (suffix.indexOf(".") == -1) + { + // a handle would be separated from the identifier of the package type + general = true; + } - /** - * 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 accepts = this.getAccepts(context, dso); + if (withHandle || general) + { + String value = props.getProperty((key)); + aps.add(value); + } + } + + return aps; + } + + public List getItemAcceptPackaging() + { + List aps = new ArrayList(); + + // build the holding maps of identifiers + Properties props = ConfigurationManager.getProperties("swordv2-server"); + Set keyset = props.keySet(); + for (Object keyObj : keyset) + { + // start by getting anything that starts with sword.accept-packging.collection. + String sw = "accept-packaging.item."; + + if (!(keyObj instanceof String)) + { + continue; + } + String key = (String) keyObj; + + if (!key.startsWith(sw)) + { + continue; + } + + // extract the configuration into the holding Maps + String value = props.getProperty((key)); + aps.add(value); + } + + return aps; + } + + /** + * Is the given packaging/media type supported by the given DSpace + * object? + * + * @param packageFormat + * @param dso + * @throws DSpaceSwordException + * @throws SwordError + */ + public boolean isAcceptedPackaging(String packageFormat, DSpaceObject dso) + throws DSpaceSwordException, SwordError + { + if (packageFormat == null || "".equals(packageFormat)) + { + return true; + } + + if (dso instanceof Collection) + { + List accepts = this.getAcceptPackaging((Collection) dso); + for (String accept : accepts) + { + if (accept.equals(packageFormat)) + { + return true; + } + } + } + else if (dso instanceof Item) + { + List accepts = this.getItemAcceptPackaging(); + for (String accept : accepts) + { + if (accept.equals(packageFormat)) + { + 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 accepts = this.getAccepts(context, dso); for (String acc : accepts) { if (this.contentTypeMatches(type, acc)) @@ -633,8 +658,8 @@ public class SwordConfigurationDSpace implements SwordConfiguration return true; } } - return accepts.contains(type); - } + return accepts.contains(type); + } private boolean contentTypeMatches(String type, String pattern) { @@ -669,15 +694,17 @@ public class SwordConfigurationDSpace implements SwordConfiguration return prefixMatch && suffixMatch; } - public String getStateUri(String state) - { - return ConfigurationManager.getProperty("swordv2-server", "state." + state + ".uri"); - } + public String getStateUri(String state) + { + return ConfigurationManager + .getProperty("swordv2-server", "state." + state + ".uri"); + } - public String getStateDescription(String state) - { - return ConfigurationManager.getProperty("swordv2-server", "state." + state + ".description"); - } + public String getStateDescription(String state) + { + return ConfigurationManager.getProperty("swordv2-server", + "state." + state + ".description"); + } public boolean allowUnauthenticatedMediaAccess() { diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentDisseminator.java index 39d4df10f1..13c8597aaa 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentDisseminator.java @@ -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 - * + *

* 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); diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentIngester.java index 27ab36c346..d432b99e44 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContentIngester.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -18,23 +18,27 @@ import org.swordapp.server.SwordServerException; * Interface behind which can be implemented ingest mechanisms * for SWORD deposit requests. Instances of this class should * be obtained via the SwordIngesterFactory class. - * + * * @author Richard Jones * */ 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; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContext.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContext.java index 6109c66999..79b0e3de61 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContext.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordContext.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -31,157 +31,157 @@ import org.dspace.eperson.EPerson; * * and not from any of the other context retrieval methods in this * class - * + * * @author Richard Jones * */ public class SwordContext { - /** The primary authenticated user for the request */ - private EPerson authenticated = null; - - /** The onBehalfOf user for the request */ - private EPerson onBehalfOf = null; + /** The primary authenticated user for the request */ + private EPerson authenticated = null; - /** The primary context, representing the on behalf of user if exists, and the authenticated user if not */ - private Context context; + /** The onBehalfOf user for the request */ + private EPerson onBehalfOf = null; - /** the context for the authenticated user, which may not, therefore, be the primary context also */ - private Context authenticatorContext; + /** The primary context, representing the on behalf of user if exists, and the authenticated user if not */ + private Context context; - /** - * @return the authenticated user - */ - public EPerson getAuthenticated() - { - return authenticated; - } + /** the context for the authenticated user, which may not, therefore, be the primary context also */ + private Context authenticatorContext; - /** - * @param authenticated the eperson to set - */ - public void setAuthenticated(EPerson authenticated) - { - this.authenticated = authenticated; - } + /** + * @return the authenticated user + */ + public EPerson getAuthenticated() + { + return authenticated; + } - /** - * @return the onBehalfOf user - */ - public EPerson getOnBehalfOf() - { - return onBehalfOf; - } + /** + * @param authenticated the eperson to set + */ + public void setAuthenticated(EPerson authenticated) + { + this.authenticated = authenticated; + } - /** - * @param onBehalfOf the eperson to set - */ - public void setOnBehalfOf(EPerson onBehalfOf) - { - this.onBehalfOf = onBehalfOf; - } + /** + * @return the onBehalfOf user + */ + public EPerson getOnBehalfOf() + { + return 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; - } + /** + * @param onBehalfOf the eperson to set + */ + public void setOnBehalfOf(EPerson onBehalfOf) + { + this.onBehalfOf = onBehalfOf; + } - public void setContext(Context context) - { - this.context = 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; + } - /** - * 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 setContext(Context context) + { + this.context = context; + } - public void setAuthenticatorContext(Context authenticatorContext) - { - this.authenticatorContext = 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; + } - /** - * 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; - } + public void setAuthenticatorContext(Context authenticatorContext) + { + this.authenticatorContext = authenticatorContext; + } - /** - * 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(); - } + /** + * 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; + } - if (authenticatorContext != null && authenticatorContext.isValid()) - { - authenticatorContext.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(); + } - /** - * 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(); - } + if (authenticatorContext != null && authenticatorContext.isValid()) + { + authenticatorContext.abort(); + } + } - // 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); - } - } + /** + * 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); + } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordDisseminatorFactory.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordDisseminatorFactory.java index 5bbc1b537f..f681894f6b 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordDisseminatorFactory.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordDisseminatorFactory.java @@ -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 - * + *

* 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> accept, String acceptPackaging) + public static SwordContentDisseminator getContentInstance( + Map> 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> accept) + public static SwordStatementDisseminator getStatementInstance( + Map> 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; - } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryDisseminator.java index 2c0a86cb43..0f167569a8 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryDisseminator.java @@ -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 - * + *

* 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; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryIngester.java index 1aa6992740..b5372d0b35 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordEntryIngester.java @@ -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 - * + *

* 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; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordIngesterFactory.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordIngesterFactory.java index e9850e6bd5..4707408fcf 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordIngesterFactory.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordIngesterFactory.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; @@ -15,37 +15,39 @@ 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. - * + * * @author Richard Jones * */ 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; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSContentIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSContentIngester.java index a3fd2639d6..55cc7acaac 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSContentIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSContentIngester.java @@ -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 - * + *

* 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."; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSPackageIngester.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSPackageIngester.java index 0fe5c9f828..d2b4501925 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSPackageIngester.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordMETSPackageIngester.java @@ -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 - * + *

* 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); } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordStatementDisseminator.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordStatementDisseminator.java index c37c9a1a59..f94e8302c6 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordStatementDisseminator.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordStatementDisseminator.java @@ -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 - * + *

* 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; } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordUrlManager.java b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordUrlManager.java index fa902e872e..735c7200f5 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/SwordUrlManager.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/SwordUrlManager.java @@ -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 - * + *

* 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 - - // 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); - } + if (url.startsWith(sdBase)) + { + // we are dealing with a service document request - DSpaceObject dso = handleService.resolveToObject(context, url); + // 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); 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 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 bundles = bitstream.getBundles(); - Bundle parent = null; - if (!bundles.isEmpty()) - { - parent = bundles.get(0).getBundle(); - } - else - { - throw new DSpaceSwordException("Encountered orphaned bitstream"); - } + List items = parent.getItems(); + Item item; + if (!items.isEmpty()) + { + item = items.get(0); + } + else + { + throw new DSpaceSwordException("Encountered orphaned bundle"); + } - List 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"); + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/TempFileInputStream.java b/dspace-swordv2/src/main/java/org/dspace/sword2/TempFileInputStream.java index 379365cab3..100a65d5ff 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/TempFileInputStream.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/TempFileInputStream.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/VerboseDescription.java b/dspace-swordv2/src/main/java/org/dspace/sword2/VerboseDescription.java index 6253f178e9..47041de63c 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/VerboseDescription.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/VerboseDescription.java @@ -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 - * + *

* http://www.dspace.org/license/ */ package org.dspace.sword2; diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/VersionManager.java b/dspace-swordv2/src/main/java/org/dspace/sword2/VersionManager.java index e4b7086730..fae7ced05c 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/VersionManager.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/VersionManager.java @@ -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 - * + *

* 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 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 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 bundleBitstreams = source.getBitstreams().iterator(); - while (bundleBitstreams.hasNext()) - { - BundleBitstream bundleBitstream = bundleBitstreams.next(); - bundleBitstreams.remove(); - bundleService.removeBitstream(context, source, bundleBitstream.getBitstream()); - } + Iterator 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 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 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 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 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 bundleBitstreams = source.getBitstreams(); - for (BundleBitstream bundleBitstream : bundleBitstreams) - { - bundleService.addBitstream(context, old, bundleBitstream.getBitstream()); - } - } + Bundle old = bundleService.create(context, item, oldName); + List 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 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 bundles = item.getBundles(); + for (Bundle bundle : bundles) + { + if (nName.equals(bundle.getName())) + { + return this.getNumberedName(item, name, number + 1); + } + } + return nName; + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManager.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManager.java index 000f2b0605..d2b8bb7630 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManager.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManager.java @@ -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 - * + *

* 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; - } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java index 5c38d5376e..0cc65bb555 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerDefault.java @@ -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 - * + *

* 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 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 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 items = bundleBitstream.getBundle().getItems(); - for (Item item : items) - { - this.deleteMediaResource(context, item); - } - } - } - catch (SQLException e) - { - throw new DSpaceSwordException(e); - } - } + List 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 bundleBitstreams = bitstream.getBundles(); - for (BundleBitstream bundleBitstream : bundleBitstreams) - { + try + { + List 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); - } - - public void resolveState(Context context, Deposit deposit, DepositResult result, VerboseDescription verboseDescription, boolean containerOperation) + this.resolveState(context, deposit, result, verboseDescription, true); + } + + 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); } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerFactory.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerFactory.java index 39f6beb189..a55899c214 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerFactory.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerFactory.java @@ -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 - * + *

* 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; - } + } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerUnrestricted.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerUnrestricted.java index a30fb5f58f..ef1d7d9ee1 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerUnrestricted.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowManagerUnrestricted.java @@ -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 - * + *

* 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 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 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); } } diff --git a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java index 04660d1395..4271a5d106 100644 --- a/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java +++ b/dspace-swordv2/src/main/java/org/dspace/sword2/WorkflowTools.java @@ -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 - * + *

* 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()); } } }