org.purl.sword.server.DummyServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dspace-sword-api Show documentation
Show all versions of dspace-sword-api Show documentation
DSpace SWORD Deposit Service Provider Web Application
/**
* Copyright (c) 2009, Aberystwyth University
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* - Neither the name of the Centre for Advanced Software and
* Intelligent Systems (CASIS) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package org.purl.sword.server;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.servlet.http.HttpServletResponse;
import org.purl.sword.atom.Author;
import org.purl.sword.atom.Content;
import org.purl.sword.atom.Contributor;
import org.purl.sword.atom.Generator;
import org.purl.sword.atom.InvalidMediaTypeException;
import org.purl.sword.atom.Link;
import org.purl.sword.atom.Summary;
import org.purl.sword.atom.Title;
import org.purl.sword.base.AtomDocumentRequest;
import org.purl.sword.base.AtomDocumentResponse;
import org.purl.sword.base.Collection;
import org.purl.sword.base.Deposit;
import org.purl.sword.base.DepositResponse;
import org.purl.sword.base.ErrorCodes;
import org.purl.sword.base.SWORDAuthenticationException;
import org.purl.sword.base.SWORDEntry;
import org.purl.sword.base.SWORDErrorException;
import org.purl.sword.base.SWORDException;
import org.purl.sword.base.Service;
import org.purl.sword.base.ServiceDocument;
import org.purl.sword.base.ServiceDocumentRequest;
import org.purl.sword.base.Workspace;
import org.apache.log4j.Logger;
/**
* A 'dummy server' which acts as dumb repository which implements the
* SWORD ServerInterface. It accepts any type of deposit, and tries to
* return appropriate responses.
*
* It supports authentication: if the username and password match
* (case sensitive) it authenticates the user, if not, the authentication
* fails.
*
* @author Stuart Lewis
*/
public class DummyServer implements SWORDServer {
/** A counter to count submissions, so the response to a deposit can increment */
private static int counter = 0;
/** Logger */
private static Logger log = Logger.getLogger(ServiceDocumentServlet.class);
/**
* Provides a dumb but plausible service document - it contains
* an anonymous workspace and collection, and one personalised
* for the onBehalfOf user.
*
* @param onBehalfOf The user that the client is acting on behalf of
* @throws SWORDAuthenticationException If the credentials are bad
* @throws SWORDErrorException If something goes wrong, such as
*/
public ServiceDocument doServiceDocument(ServiceDocumentRequest sdr)
throws SWORDAuthenticationException, SWORDErrorException, SWORDException {
// Authenticate the user
String username = sdr.getUsername();
String password = sdr.getPassword();
if ((username != null) && (password != null) &&
(((username.equals("")) && (password.equals(""))) ||
(!username.equalsIgnoreCase(password))) ) {
// User not authenticated
throw new SWORDAuthenticationException("Bad credentials");
}
// Allow users to force the throwing of a SWORD error exception by setting
// the OBO user to 'error'
if ((sdr.getOnBehalfOf() != null) && (sdr.getOnBehalfOf().equals("error"))) {
// Throw the error exception
throw new SWORDErrorException(ErrorCodes.MEDIATION_NOT_ALLOWED, "Mediated deposits not allowed");
}
// Create and return a dummy ServiceDocument
ServiceDocument document = new ServiceDocument();
Service service = new Service("1.3", true, true);
document.setService(service);
log.debug("sdr.getLocation() is: " + sdr.getLocation());
String location = sdr.getLocation().substring(0, sdr.getLocation().length() - 16);
log.debug("location is: " + location);
if (sdr.getLocation().contains("?nested=")) {
Workspace workspace = new Workspace();
workspace.setTitle("Nested service document workspace");
Collection collection = new Collection();
collection.setTitle("Nested collection: " + sdr.getLocation().substring(sdr.getLocation().indexOf('?') + 1));
collection.setLocation(location + "/deposit/nested");
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit");
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.setAbstract("A nested collection that users can deposit into");
collection.setTreatment("This is a dummy server");
collection.setCollectionPolicy("No guarantee of service, or that deposits will be retained for any length of time.");
workspace.addCollection(collection);
service.addWorkspace(workspace);
} else {
Workspace workspace = new Workspace();
workspace.setTitle("Anonymous submitters workspace");
Collection collection = new Collection();
collection.setTitle("Anonymous submitters collection");
collection.setLocation(location + "/deposit/anon");
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit");
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.setAbstract("A collection that anonymous users can deposit into");
collection.setTreatment("This is a dummy server");
collection.setCollectionPolicy("No guarantee of service, or that deposits will be retained for any length of time.");
collection.setService(location + "/client/servicedocument?nested=anon");
workspace.addCollection(collection);
collection = new Collection();
collection.setTitle("Anonymous submitters other collection");
collection.setLocation(location + "/deposit/anonymous");
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit");
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.setAbstract("Another collection that anonymous users can deposit into");
collection.setTreatment("This is a dummy server");
collection.setCollectionPolicy("No guarantee of service, or that deposits will be retained for any length of time.");
workspace.addCollection(collection);
service.addWorkspace(workspace);
if (sdr.getUsername() != null) {
workspace = new Workspace();
workspace.setTitle("Authenticated workspace for " + username);
collection = new Collection();
collection.setTitle("Authenticated collection for " + username);
collection.setLocation(location + "/deposit/" + username);
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit", 0.8f);
collection.setAbstract("A collection that " + username + " can deposit into");
collection.setTreatment("This is a dummy server");
collection.setCollectionPolicy("No guarantee of service, or that deposits will be retained for any length of time.");
collection.setService(location + "/client/servicedocument?nested=authenticated");
workspace.addCollection(collection);
collection = new Collection();
collection.setTitle("Second authenticated collection for " + username);
collection.setLocation(location + "/deposit/" + username + "-2");
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit", 0.123f);
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.setAbstract("A collection that " + username + " can deposit into");
collection.setTreatment("This is a dummy server");
collection.setCollectionPolicy("No guarantee of service, or that deposits will be retained for any length of time.");
workspace.addCollection(collection);
}
service.addWorkspace(workspace);
}
String onBehalfOf = sdr.getOnBehalfOf();
if ((onBehalfOf != null) && (!onBehalfOf.equals(""))) {
Workspace workspace = new Workspace();
workspace.setTitle("Personal workspace for " + onBehalfOf);
Collection collection = new Collection();
collection.setTitle("Personal collection for " + onBehalfOf);
collection.setLocation(location + "/deposit?user=" + onBehalfOf);
collection.addAccepts("application/zip");
collection.addAccepts("application/xml");
collection.addAcceptPackaging("http://purl.org/net/sword-types/METSDSpaceSIP");
collection.addAcceptPackaging("http://purl.org/net/sword-types/bagit", 0.8f);
collection.setAbstract("An abstract goes in here");
collection.setCollectionPolicy("A collection policy");
collection.setMediation(true);
collection.setTreatment("treatment in here too");
workspace.addCollection(collection);
service.addWorkspace(workspace);
}
return document;
}
public DepositResponse doDeposit(Deposit deposit)
throws SWORDAuthenticationException, SWORDErrorException, SWORDException {
// Authenticate the user
String username = deposit.getUsername();
String password = deposit.getPassword();
if ((username != null) && (password != null) &&
(((username.equals("")) && (password.equals(""))) ||
(!username.equalsIgnoreCase(password))) ) {
// User not authenticated
throw new SWORDAuthenticationException("Bad credentials");
}
// Check this is a collection that takes obo deposits, else thrown an error
if (((deposit.getOnBehalfOf() != null) && (!deposit.getOnBehalfOf().equals(""))) &&
(!deposit.getLocation().contains("deposit?user="))) {
throw new SWORDErrorException(ErrorCodes.MEDIATION_NOT_ALLOWED,
"Mediated deposit not allowed to this collection");
}
// Get the filenames
StringBuffer filenames = new StringBuffer("Deposit file contained: ");
if (deposit.getFilename() != null) {
filenames.append("(filename = " + deposit.getFilename() + ") ");
}
if (deposit.getSlug() != null) {
filenames.append("(slug = " + deposit.getSlug() + ") ");
}
try {
ZipInputStream zip = new ZipInputStream(deposit.getFile());
ZipEntry ze;
while ((ze = zip.getNextEntry()) != null) {
filenames.append(" " + ze.toString());
}
} catch (IOException ioe) {
throw new SWORDException("Failed to open deposited zip file", null, ErrorCodes.ERROR_CONTENT);
}
// Handle the deposit
if (!deposit.isNoOp()) {
counter++;
}
DepositResponse dr = new DepositResponse(Deposit.CREATED);
SWORDEntry se = new SWORDEntry();
Title t = new Title();
t.setContent("DummyServer Deposit: #" + counter);
se.setTitle(t);
se.addCategory("Category");
if (deposit.getSlug() != null) {
se.setId(deposit.getSlug() + " - ID: " + counter);
} else {
se.setId("ID: " + counter);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
TimeZone utc = TimeZone.getTimeZone("UTC");
sdf.setTimeZone (utc);
String milliFormat = sdf.format(new Date());
se.setUpdated(milliFormat);
Summary s = new Summary();
s.setContent(filenames.toString());
se.setSummary(s);
Author a = new Author();
if (username != null) {
a.setName(username);
} else {
a.setName("unknown");
}
se.addAuthors(a);
Link em = new Link();
em.setRel("edit-media");
em.setHref("http://www.myrepository.ac.uk/sdl/workflow/my deposit");
se.addLink(em);
Link e = new Link();
e.setRel("edit");
e.setHref("http://www.myrepository.ac.uk/sdl/workflow/my deposit.atom");
se.addLink(e);
if (deposit.getOnBehalfOf() != null) {
Contributor c = new Contributor();
c.setName(deposit.getOnBehalfOf());
c.setEmail(deposit.getOnBehalfOf() + "@myrepository.ac.uk");
se.addContributor(c);
}
Generator generator = new Generator();
generator.setContent("Stuart's Dummy SWORD Server");
generator.setUri("http://dummy-sword-server.example.com/");
generator.setVersion("1.3");
se.setGenerator(generator);
Content content = new Content();
try {
content.setType("application/zip");
} catch (InvalidMediaTypeException ex) {
ex.printStackTrace();
}
content.setSource("http://www.myrepository.ac.uk/sdl/uploads/upload-" + counter + ".zip");
se.setContent(content);
se.setTreatment("Short back and sides");
if (deposit.isVerbose()) {
se.setVerboseDescription("I've done a lot of hard work to get this far!");
}
se.setNoOp(deposit.isNoOp());
dr.setEntry(se);
dr.setLocation("http://www.myrepository.ac.uk/atom/" + counter);
return dr;
}
public AtomDocumentResponse doAtomDocument(AtomDocumentRequest adr)
throws SWORDAuthenticationException, SWORDErrorException, SWORDException {
// Authenticate the user
String username = adr.getUsername();
String password = adr.getPassword();
if ((username != null) && (password != null) &&
(((username.equals("")) && (password.equals(""))) ||
(!username.equalsIgnoreCase(password))) ) {
// User not authenticated
throw new SWORDAuthenticationException("Bad credentials");
}
return new AtomDocumentResponse(HttpServletResponse.SC_OK);
}
}