mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-23 18:03:11 +00:00
Add the new SWORD module to the 1.5.x branch. This includes the SWORD code, re-structured to meet the standards already laid out for the 1.5 release (top level project, with sub api and webapp projects). In addition to this the following additions have been made to the main part of DSpace, which will need to be removed again if SWORD is modularised out again:
- sword-swap-ingest.xsl has been included into config/crosswalks - sword configuration has been added to dspace.cfg - loading of the required fields for swap ingest has been added to the main build.xml - references to dspace-sword have been added to all the relevant pom.xml files in the main for DSpace Furthermore, this commit includes the source code for the common sword libraries. These need really to be in the main maven repository, which I will work on as soon as possible before the 1.5 beta release. This module has been tested to work previously, so it has not been extensively tested again. Dependency issues in the build system may remain, which have notyet been discovered. git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2598 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
34
dspace-sword/LICENCE.txt
Normal file
34
dspace-sword/LICENCE.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
Copyright (c) 2007, Aberystwyth University
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
- Neither the name of the Centre for Advanced Software and
|
||||
Intelligent Systems (CASIS) nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
64
dspace-sword/README.txt
Normal file
64
dspace-sword/README.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
DSpace SWORD README
|
||||
===================
|
||||
|
||||
Author: Richard Jones
|
||||
Last Updated: 07-02-2007
|
||||
|
||||
This document describes the DSpace implementation of the SWORD deposit
|
||||
standard. This is an extension to the ATOM Publishing Protocol (APP),
|
||||
which provides a framework to discover deposit targets, and to deposit packaged
|
||||
content into remote repositories.
|
||||
|
||||
For more information see:
|
||||
|
||||
http://www.ukoln.ac.uk/repositories/digirep/index/SWORD
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
Supplied along with the source code is a package which can be used for testing.
|
||||
This consists of a mets.xml file, which is a METS document containing a Dublin
|
||||
Core XML section of descriptive metadata which conforms to the SWAP standard.
|
||||
There are additionally 3 example PDF files.
|
||||
|
||||
These files are provided additionally inside a zip file which should form the
|
||||
content of a deposit request (example.zip).
|
||||
|
||||
These files are all available in the directory: [dspace-sword]/example
|
||||
|
||||
Testing can be performed using the separately available SWORD Client
|
||||
|
||||
Implementation Notes
|
||||
--------------------
|
||||
|
||||
- DSpace has no equivalent concept for the SWORD term "treatment". This is
|
||||
therefore always null in the Service Document
|
||||
|
||||
- The logic of onBehalfOf is as follows: The list of collections which is
|
||||
supplied during a request which is done onBehalfOf another user is the
|
||||
intersection of the lists of collections that the authenticated user can
|
||||
submit to and the list that the onBehalfOf user can submit to.
|
||||
|
||||
- This implementation only supports the default PasswordAuthentication
|
||||
mechanism for DSpace. Modifications are required to tie it in to alternative
|
||||
authentication mechanisms.
|
||||
|
||||
- When items are deposited and pass into the DSpace workflow system, they
|
||||
cannot be assigned external identifiers immediately. Therefore the returned
|
||||
id on "Accepted" items will be the front page of the repository on which the
|
||||
deposit happened. Alternatives to this mechanism are being sought, but may
|
||||
require core DSpace modifications.
|
||||
|
||||
- If a request is made with an onBehalfOf user supplied, the authentication
|
||||
process requires that the username/password pair successfully authenticate a
|
||||
user, and that the onBehalfOf user simply exists in the user database. If
|
||||
any of these conditions fail, authentication fails.
|
||||
|
||||
- The DSpace package ingester does not permit for a copy of the orignal package
|
||||
to be retained. To modify this requires changes to the core DSpace which
|
||||
could be considered. In the mean time, it is not possible to return a link
|
||||
to the original package in the <atom:link> element.
|
||||
|
||||
- The ingest stylesheet used by default is available in the file:
|
||||
[dspace-source]/config/crosswalks/sword-swap-ingest.xsl but does not cover
|
||||
the complete SWAP profile yet.
|
109
dspace-sword/dspace-sword-api/pom.xml
Normal file
109
dspace-sword/dspace-sword-api/pom.xml
Normal file
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>DSpace SWORD :: API and Implementation</name>
|
||||
<description>DSpace SWORD Deposit Service Provider Web Application</description>
|
||||
<url>http://www.ukoln.ac.uk/repositories/digirep/index/SWORD</url>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Snapshot Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<updatePolicy>never</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>
|
||||
scm:svn:http://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-api
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-api
|
||||
</developerConnection>
|
||||
<url>
|
||||
http://dspace.svn.sourceforge.net/viewvc/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-api
|
||||
</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Leave this out for the moment, as the source is in the tree -->
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>sword-common</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jaxen</groupId>
|
||||
<artifactId>jaxen</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,155 @@
|
||||
/* CollectionLocation.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.HandleManager;
|
||||
|
||||
/**
|
||||
* 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 Logger log = Logger.getLogger(CollectionLocation.class);
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
|
||||
DSpaceObject dso = HandleManager.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.url]/dspace-sword/deposit
|
||||
*
|
||||
* where dspace.url 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.deposit.url");
|
||||
if (depositUrl == null || "".equals(depositUrl))
|
||||
{
|
||||
String dspaceUrl = ConfigurationManager.getProperty("dspace.url");
|
||||
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.url");
|
||||
}
|
||||
depositUrl = dspaceUrl + "/dspace-sword/deposit";
|
||||
}
|
||||
return depositUrl;
|
||||
}
|
||||
}
|
@@ -0,0 +1,463 @@
|
||||
/* DSpaceATOMEntry.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.DCDate;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.handle.HandleManager;
|
||||
|
||||
import org.purl.sword.base.SWORDEntry;
|
||||
|
||||
import org.w3.atom.Author;
|
||||
import org.w3.atom.Content;
|
||||
import org.w3.atom.ContentType;
|
||||
import org.w3.atom.Contributor;
|
||||
import org.w3.atom.Generator;
|
||||
import org.w3.atom.InvalidMediaTypeException;
|
||||
import org.w3.atom.Link;
|
||||
import org.w3.atom.Rights;
|
||||
import org.w3.atom.Source;
|
||||
import org.w3.atom.Summary;
|
||||
import org.w3.atom.Title;
|
||||
|
||||
/**
|
||||
* Class to represent a DSpace Item as an ATOM Entry. This
|
||||
* 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 class DSpaceATOMEntry
|
||||
{
|
||||
/** the SWORD ATOM entry which this class effectively decorates */
|
||||
protected SWORDEntry entry;
|
||||
|
||||
/** the item this ATOM entry represents */
|
||||
protected Item item;
|
||||
|
||||
/**
|
||||
* 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 item the item to represent
|
||||
* @param handle the handle for the item
|
||||
* @param noOp whether this is a noOp request
|
||||
* @return the SWORDEntry for the item
|
||||
*/
|
||||
public SWORDEntry getSWORDEntry(Item item, String handle, boolean noOp)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
entry = new SWORDEntry();
|
||||
this.item = item;
|
||||
|
||||
// add the authors to the sword entry
|
||||
this.addAuthors();
|
||||
|
||||
// add the category information to the sword entry
|
||||
this.addCategories();
|
||||
|
||||
// add a content element to the sword entry
|
||||
this.addContentElement(handle, noOp);
|
||||
|
||||
// add contributors (authors plus any other bits) to the sword entry
|
||||
this.addContributors();
|
||||
|
||||
// add the identifier for the item, if the id is going
|
||||
// to be valid by the end of the request
|
||||
if (!noOp)
|
||||
{
|
||||
this.addIdentifier(handle, noOp);
|
||||
}
|
||||
|
||||
// add any appropriate links
|
||||
this.addLinks(handle);
|
||||
|
||||
// add the publish date
|
||||
this.addPublishDate();
|
||||
|
||||
// add the rights information
|
||||
this.addRights(handle);
|
||||
|
||||
// add the source infomation
|
||||
this.addSource();
|
||||
|
||||
// add the summary of the item
|
||||
this.addSummary();
|
||||
|
||||
// add the title of the item
|
||||
this.addTitle();
|
||||
|
||||
// add the date on which the entry was last updated
|
||||
this.addLastUpdatedDate();
|
||||
|
||||
// set the format namespace for the response
|
||||
this.setFormatNamespace();
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.contributor.author");
|
||||
if (dcv != null)
|
||||
{
|
||||
for (int i = 0; i < dcv.length; i++)
|
||||
{
|
||||
Author author = new Author();
|
||||
author.setName(dcv[i].value);
|
||||
entry.addAuthors(author);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the subject classifications from the bibliographic
|
||||
* metadata.
|
||||
*
|
||||
*/
|
||||
protected void addCategories()
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.subject.*");
|
||||
if (dcv != null)
|
||||
{
|
||||
for (int i = 0; i < dcv.length; i++)
|
||||
{
|
||||
entry.addCategory(dcv[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content type that DSpace received. This is just
|
||||
* "application/zip" in this default implementation.
|
||||
*
|
||||
*/
|
||||
protected void addContentElement(String handle, boolean noOp)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!noOp)
|
||||
{
|
||||
if (item.getHandle() != null)
|
||||
{
|
||||
handle = item.getHandle();
|
||||
}
|
||||
|
||||
if (handle != null && !"".equals(handle))
|
||||
{
|
||||
Content content = new Content();
|
||||
// content.setType("application/zip");
|
||||
content.setType("text/html");
|
||||
content.setSource(HandleManager.getCanonicalForm(handle));
|
||||
entry.setContent(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvalidMediaTypeException e)
|
||||
{
|
||||
// do nothing; we'll live without the content type declaration!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.contributor.*");
|
||||
if (dcv != null)
|
||||
{
|
||||
for (int i = 0; i < dcv.length; i++)
|
||||
{
|
||||
Contributor cont = new Contributor();
|
||||
cont.setName(dcv[i].value);
|
||||
entry.addContributor(cont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*
|
||||
* @param handle
|
||||
*/
|
||||
protected void addIdentifier(String handle, boolean noOp)
|
||||
{
|
||||
// it's possible that the item hasn't been assigned a handle yet
|
||||
if (!noOp)
|
||||
{
|
||||
if (item.getHandle() != null)
|
||||
{
|
||||
handle = item.getHandle();
|
||||
}
|
||||
|
||||
if (handle != null && !"".equals(handle))
|
||||
{
|
||||
entry.setId(HandleManager.getCanonicalForm(handle));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if we get this far, then we just use the dspace url as the
|
||||
// property
|
||||
String cfg = ConfigurationManager.getProperty("dspace.url");
|
||||
entry.setId(cfg);
|
||||
|
||||
// FIXME: later on we will maybe have a workflow page supplied
|
||||
// by the sword interface?
|
||||
}
|
||||
|
||||
/**
|
||||
* Add links associated with this item. The default implementation
|
||||
* does not support item linking, so this method currently does
|
||||
* nothing
|
||||
*
|
||||
*/
|
||||
protected void addLinks(String handle)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
// if there is no handle, we can't generate links
|
||||
if (handle == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String base = ConfigurationManager.getProperty("dspace.url");
|
||||
|
||||
// in the default set up we just pass urls to all of the
|
||||
// inidivual files in the item
|
||||
Bundle[] bundles = item.getBundles("ORIGINAL");
|
||||
for (int i = 0; i < bundles.length ; i++)
|
||||
{
|
||||
Bitstream[] bss = bundles[i].getBitstreams();
|
||||
for (int j = 0; j < bss.length; j++)
|
||||
{
|
||||
Link link = new Link();
|
||||
String url = base + "/bitstream/" + handle + "/" + bss[j].getSequenceID() + "/" + bss[j].getName();
|
||||
link.setHref(url);
|
||||
entry.addLink(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the date of publication from the bibliographic metadata
|
||||
*
|
||||
*/
|
||||
protected void addPublishDate()
|
||||
{
|
||||
try
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.date.issued");
|
||||
if (dcv != null)
|
||||
{
|
||||
if (dcv.length == 1)
|
||||
{
|
||||
entry.setPublished(dcv[0].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
// do nothing; we'll live without the publication date
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add rights information. This attaches an href to the URL
|
||||
* of the item's licence file
|
||||
*
|
||||
*/
|
||||
protected void addRights(String handle)
|
||||
{
|
||||
try
|
||||
{
|
||||
// if there's no handle, we can't give a link
|
||||
if (handle == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String base = ConfigurationManager.getProperty("dspace.url");
|
||||
|
||||
// if there's no base URL, we are stuck
|
||||
if (base == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder rightsString = new StringBuilder();
|
||||
Bundle[] bundles = item.getBundles("LICENSE");
|
||||
for (int i = 0; i < bundles.length; i++)
|
||||
{
|
||||
Bitstream[] bss = bundles[i].getBitstreams();
|
||||
for (int j = 0; j < bss.length; j++)
|
||||
{
|
||||
String url = base + "/bitstream/" + handle + "/" + bss[j].getSequenceID() + "/" + bss[j].getName();
|
||||
rightsString.append(url + " ");
|
||||
}
|
||||
}
|
||||
|
||||
Rights rights = new Rights();
|
||||
rights.setContent(rightsString.toString());
|
||||
rights.setType(ContentType.TEXT);
|
||||
entry.setRights(rights);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the source of the bibliographic metadata.
|
||||
*
|
||||
*/
|
||||
protected void addSource()
|
||||
{
|
||||
String base = ConfigurationManager.getProperty("dspace.url");
|
||||
String name = ConfigurationManager.getProperty("dspace.name");
|
||||
Source source = new Source();
|
||||
Generator gen = new Generator();
|
||||
gen.setUri(base);
|
||||
gen.setContent(name);
|
||||
source.setGenerator(gen);
|
||||
entry.setSource(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the summary/abstract from the bibliographic metadata
|
||||
*
|
||||
*/
|
||||
protected void addSummary()
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.description.abstract");
|
||||
if (dcv != null)
|
||||
{
|
||||
for (int i = 0; i < dcv.length; i++)
|
||||
{
|
||||
Summary summary = new Summary();
|
||||
summary.setContent(dcv[i].value);
|
||||
summary.setType(ContentType.TEXT);
|
||||
entry.setSummary(summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the title from the bibliographic metadata
|
||||
*
|
||||
*/
|
||||
protected void addTitle()
|
||||
{
|
||||
DCValue[] dcv = item.getMetadata("dc.title");
|
||||
if (dcv != null)
|
||||
{
|
||||
for (int i = 0; i < dcv.length; i++)
|
||||
{
|
||||
Title title = new Title();
|
||||
title.setContent(dcv[i].value);
|
||||
title.setType(ContentType.TEXT);
|
||||
entry.setTitle(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the date that this item was last updated
|
||||
*
|
||||
*/
|
||||
protected void addLastUpdatedDate()
|
||||
{
|
||||
try
|
||||
{
|
||||
String config = ConfigurationManager.getProperty("sword.updated.field");
|
||||
DCValue[] dcv = item.getMetadata(config);
|
||||
if (dcv != null)
|
||||
{
|
||||
if (dcv.length == 1)
|
||||
{
|
||||
DCDate dcd = new DCDate(dcv[0].value);
|
||||
entry.setUpdated(dcd.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
protected void setFormatNamespace()
|
||||
{
|
||||
entry.setFormatNamespace("http://www.log.gov/METS");
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/* DSpaceSWORDException.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
/**
|
||||
* 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(String arg0, Throwable arg1)
|
||||
{
|
||||
super(arg0, arg1);
|
||||
}
|
||||
|
||||
public DSpaceSWORDException(String arg0)
|
||||
{
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
public DSpaceSWORDException(Throwable arg0)
|
||||
{
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,328 @@
|
||||
/* DSpaceSWORDServer.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
|
||||
import org.purl.sword.server.SWORDServer;
|
||||
import org.purl.sword.base.DepositResponse;
|
||||
import org.purl.sword.base.SWORDAuthenticationException;
|
||||
import org.purl.sword.base.SWORDException;
|
||||
import org.purl.sword.base.ServiceDocument;
|
||||
import org.purl.sword.base.ServiceDocumentRequest;
|
||||
import org.purl.sword.base.Deposit;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* 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 Logger log = Logger.getLogger(DSpaceSWORDServer.class);
|
||||
|
||||
/** DSpace context */
|
||||
private Context context;
|
||||
|
||||
// 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
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(LogManager.getHeader(context, "sword_do_service_document", ""));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// first authenticate the request
|
||||
// note: this will build our context for us
|
||||
SWORDContext sc = this.authenticate(request);
|
||||
|
||||
// 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();
|
||||
service.setContext(context);
|
||||
service.setSWORDContext(sc);
|
||||
ServiceDocument doc = service.getServiceDocument();
|
||||
|
||||
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 (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.purl.sword.SWORDServer#doSWORDDeposit(org.purl.sword.server.Deposit)
|
||||
*/
|
||||
public DepositResponse doDeposit(Deposit deposit)
|
||||
throws SWORDAuthenticationException, SWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(LogManager.getHeader(context, "sword_do_deposit", ""));
|
||||
}
|
||||
|
||||
// first authenticate the request
|
||||
// note: this will build our context for us
|
||||
SWORDContext sc = this.authenticate(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
|
||||
DepositManager dm = new DepositManager();
|
||||
dm.setContext(context);
|
||||
dm.setDeposit(deposit);
|
||||
dm.setSWORDContext(sc);
|
||||
DepositResponse response = dm.deposit();
|
||||
|
||||
// if something hasn't killed it already (allowed), then complete the transaction
|
||||
if (context != null && context.isValid())
|
||||
{
|
||||
context.commit();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
catch (DSpaceSWORDException e)
|
||||
{
|
||||
log.error("caught exception:", e);
|
||||
throw new SWORDAuthenticationException("There was a problem depositing the item", e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new SWORDException("There was a problem completing the transaction", 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 (context != null && context.isValid())
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SWORDException
|
||||
*/
|
||||
private void constructContext(String ip)
|
||||
throws SWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
this.context = new Context();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new SWORDException("There was a problem with the database", e);
|
||||
}
|
||||
|
||||
// Set the session ID and IP address
|
||||
this.context.setExtraLogInfo("session_id=0:ip_addr=" + ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the incoming service document request. Calls:
|
||||
*
|
||||
* authenticatate(username, password, onBehalfOf)
|
||||
*
|
||||
* @param request
|
||||
* @return a SWORDContext object containing the relevant users
|
||||
* @throws SWORDAuthenticationException
|
||||
* @throws SWORDException
|
||||
*/
|
||||
private SWORDContext authenticate(ServiceDocumentRequest request)
|
||||
throws SWORDAuthenticationException, SWORDException
|
||||
{
|
||||
this.constructContext(request.getIPAddress());
|
||||
return this.authenticate(request.getUsername(), request.getPassword(), request.getOnBehalfOf());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(Deposit deposit)
|
||||
throws SWORDAuthenticationException, SWORDException
|
||||
{
|
||||
this.constructContext(deposit.getIPAddress());
|
||||
return this.authenticate(deposit.getUsername(), deposit.getPassword(), deposit.getOnBehalfOf());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(String un, String pw, String obo)
|
||||
throws SWORDAuthenticationException, SWORDException
|
||||
{
|
||||
// smooth out the OnBehalfOf request, so that empty strings are
|
||||
// treated as null
|
||||
if ("".equals(obo))
|
||||
{
|
||||
obo = null;
|
||||
}
|
||||
|
||||
log.info(LogManager.getHeader(context, "sword_authenticate", "username=" + un + ",on_behalf_of=" + obo));
|
||||
try
|
||||
{
|
||||
// attempt to authenticate the primary user
|
||||
SWORDContext sc = new SWORDContext();
|
||||
SWORDAuthentication auth = new SWORDAuthentication();
|
||||
EPerson ep = null;
|
||||
boolean authenticated = false;
|
||||
if (auth.authenticates(this.context, un, pw))
|
||||
{
|
||||
// if authenticated, obtain the eperson object
|
||||
ep = EPerson.findByEmail(context, un);
|
||||
|
||||
if (ep != null)
|
||||
{
|
||||
authenticated = true;
|
||||
sc.setAuthenticated(ep);
|
||||
}
|
||||
|
||||
// if there is an onBehalfOfuser, then find their eperson
|
||||
// record, and if it exists set it. If not, then the
|
||||
// authentication process fails
|
||||
if (obo != null)
|
||||
{
|
||||
EPerson epObo= EPerson.findByEmail(this.context, obo);
|
||||
if (epObo != null)
|
||||
{
|
||||
sc.setOnBehalfOf(epObo);
|
||||
}
|
||||
else
|
||||
{
|
||||
authenticated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// deal with the context or throw an authentication exception
|
||||
if (ep != null && authenticated)
|
||||
{
|
||||
this.context.setCurrentUser(ep);
|
||||
log.info(LogManager.getHeader(context, "sword_set_authenticated_user", "user_id=" + ep.getID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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
|
||||
{
|
||||
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);
|
||||
}
|
||||
catch (AuthorizeException e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new SWORDAuthenticationException("There was a problem authenticating or authorising the user", e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,277 @@
|
||||
/* DepositManager.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
|
||||
import org.purl.sword.base.Deposit;
|
||||
import org.purl.sword.base.DepositResponse;
|
||||
import org.purl.sword.base.SWORDEntry;
|
||||
|
||||
/**
|
||||
* This class is responsible for initiating the process of
|
||||
* deposit of SWORD Deposit objects into the DSpace repository
|
||||
*
|
||||
* @author Richard Jones
|
||||
*
|
||||
*/
|
||||
public class DepositManager
|
||||
{
|
||||
/** Log4j logger */
|
||||
public static Logger log = Logger.getLogger(DepositManager.class);
|
||||
|
||||
/** DSpace context object */
|
||||
private Context context;
|
||||
|
||||
/** SWORD Deposit request object */
|
||||
private Deposit deposit;
|
||||
|
||||
/** SWORD Context object */
|
||||
private SWORDContext swordContext;
|
||||
|
||||
/**
|
||||
* @param context the context to set
|
||||
*/
|
||||
public void setContext(Context context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deposit the deposit to set
|
||||
*/
|
||||
public void setDeposit(Deposit deposit)
|
||||
{
|
||||
this.deposit = deposit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sc the sword context to set
|
||||
*/
|
||||
public void setSWORDContext(SWORDContext sc)
|
||||
{
|
||||
this.swordContext = sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once this object is fully prepared, this method will execute
|
||||
* the deposit process. The returned DepositRequest can be
|
||||
* used then to assembel the SWORD response.
|
||||
*
|
||||
* @return the response to the deposit request
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
public DepositResponse deposit()
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
// start the timer, and initialise the verboseness of the request
|
||||
Date start = new Date();
|
||||
StringBuilder verbs = new StringBuilder();
|
||||
if (deposit.isVerbose())
|
||||
{
|
||||
verbs.append(start.toString() + "; \n\n");
|
||||
verbs.append("Initialising verbose deposit; \n\n");
|
||||
}
|
||||
|
||||
// FIXME: currently we don't verify, because this is done higher
|
||||
// up the stack
|
||||
// first we want to verify that the deposit is safe
|
||||
// check the checksums and all that stuff
|
||||
// This throws an exception if it can't verify the deposit
|
||||
// this.verify();
|
||||
|
||||
// find out if the supplied SWORDContext can submit to the given
|
||||
// collection
|
||||
if (!this.canSubmit())
|
||||
{
|
||||
// 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 DSpaceSWORDException("Cannot submit to the given collection with this context");
|
||||
}
|
||||
|
||||
// make a note of the authentication in the verbose string
|
||||
if (deposit.isVerbose())
|
||||
{
|
||||
verbs.append("Authenticated user " + swordContext.getAuthenticated().getEmail() + "; \n\n");
|
||||
if (swordContext.getOnBehalfOf() != null)
|
||||
{
|
||||
verbs.append("Depositing on behalf of: " + swordContext.getOnBehalfOf().getEmail() + "; \n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain the relevant ingester from the factory
|
||||
SWORDIngester si = SWORDIngesterFactory.getInstance(context, deposit);
|
||||
|
||||
// do the deposit
|
||||
DepositResult result = si.ingest(context, deposit);
|
||||
|
||||
// now construct the deposit response. The response will be
|
||||
// CREATED if the deposit is in the archive, or ACCEPTED if
|
||||
// the deposit is in the workflow. We use a separate record
|
||||
// for the handle because DSpace will not supply the Item with
|
||||
// a record of the handle straight away.
|
||||
String handle = result.getHandle();
|
||||
int state = Deposit.CREATED;
|
||||
if (handle == null || "".equals(handle))
|
||||
{
|
||||
state = Deposit.ACCEPTED;
|
||||
}
|
||||
DepositResponse response = new DepositResponse(state);
|
||||
DSpaceATOMEntry dsatom = new DSpaceATOMEntry();
|
||||
SWORDEntry entry = dsatom.getSWORDEntry(result.getItem(), handle, deposit.isNoOp());
|
||||
|
||||
// if this was a no-op, we need to remove the files we just
|
||||
// deposited, and abort the transaction
|
||||
String nooplog = "";
|
||||
if (deposit.isNoOp())
|
||||
{
|
||||
this.undoDeposit(result);
|
||||
nooplog = "NoOp Requested: Removed all traces of submission; \n\n";
|
||||
}
|
||||
|
||||
entry.setNoOp(deposit.isNoOp());
|
||||
|
||||
if (deposit.isVerbose())
|
||||
{
|
||||
Date finish = new Date();
|
||||
long delta = finish.getTime() - start.getTime();
|
||||
String timer = "Total time for deposit processing: " + delta + " ms;";
|
||||
String verboseness = result.getVerboseDescription();
|
||||
if (verboseness != null && !"".equals(verboseness))
|
||||
{
|
||||
entry.setVerboseDescription(verbs.toString() + result.getVerboseDescription() + nooplog + timer);
|
||||
}
|
||||
}
|
||||
|
||||
response.setEntry(entry);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the users contained in this object's member SWORDContext
|
||||
* make a successful submission to the selected collection
|
||||
*
|
||||
* @return true if yes, false if not
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
private boolean canSubmit()
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
String loc = deposit.getLocation();
|
||||
CollectionLocation cl = new CollectionLocation();
|
||||
Collection collection = cl.getCollection(context, loc);
|
||||
boolean submit = swordContext.canSubmitTo(context, collection);
|
||||
return submit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated verification is currently done further up the stack
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
private void verify()
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
// FIXME: please implement
|
||||
// in reality, all this is done higher up the stack, so we don't
|
||||
// need to worry!
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all traces of the deposit from DSpace. The database changes
|
||||
* are easy, as this method will call <code>context.abort()</code>,
|
||||
* rolling back the transaction. In additon, though, files which have
|
||||
* been placed on the disk are also removed.
|
||||
*
|
||||
* @param result the result of the deposit which is to be removed
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
private void undoDeposit(DepositResult result)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
// obtain the item's owning collection (there can be only one)
|
||||
// and ask it to remove the item. Although we're going to abort
|
||||
// the context, so that this nevers gets written to the db,
|
||||
// it will get rid of the files on the disk
|
||||
Item item = result.getItem();
|
||||
Collection collection = item.getOwningCollection();
|
||||
collection.removeItem(item);
|
||||
|
||||
// abort the context, so no database changes are written
|
||||
if (context != null && context.isValid())
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
catch (AuthorizeException e)
|
||||
{
|
||||
log.error("authentication problem; caught exception: ", e);
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
/* DepositResult.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
|
||||
/**
|
||||
* 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 verbose description string to be returned to the requester */
|
||||
private String verboseDescription;
|
||||
|
||||
/**
|
||||
* @return the item
|
||||
*/
|
||||
public Item getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item the item to set
|
||||
*/
|
||||
public void setItem(Item item)
|
||||
{
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handle
|
||||
*/
|
||||
public String getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param handle the item handle
|
||||
*/
|
||||
public void setHandle(String handle)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the verboseDescription
|
||||
*/
|
||||
public String getVerboseDescription()
|
||||
{
|
||||
return verboseDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param verboseDescription the verboseDescription to set
|
||||
*/
|
||||
public void setVerboseDescription(String verboseDescription)
|
||||
{
|
||||
this.verboseDescription = verboseDescription;
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* LoadDSpaceConfig.java
|
||||
*
|
||||
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
|
||||
* Institute of Technology. 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 Hewlett-Packard Company nor the name of the
|
||||
* Massachusetts Institute of Technology nor the names of their
|
||||
* 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
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
package org.dspace.sword;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* Simple servlet to load in DSpace and log4j configurations. Should always be
|
||||
* started up before other servlets (use <loadOnStartup>)
|
||||
*
|
||||
* This class has been duplicated into the DSpace SWORD module from its
|
||||
* original home in the DSpace JSPUI, but authorship and copyright
|
||||
* ownership are as dictated in this file.
|
||||
*
|
||||
* @author Robert Tansley
|
||||
*/
|
||||
public class LoadDSpaceConfig extends HttpServlet
|
||||
{
|
||||
public void init()
|
||||
{
|
||||
// Get config parameter
|
||||
String config = getServletContext().getInitParameter("dspace-config");
|
||||
|
||||
// Load in DSpace config
|
||||
ConfigurationManager.loadConfig(config);
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/* SWORDAuthentication.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.authenticate.AuthenticationManager;
|
||||
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)
|
||||
{
|
||||
int auth = AuthenticationManager.authenticate(context, un, pw, null, null);
|
||||
if (auth == AuthenticationMethod.SUCCESS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,328 @@
|
||||
/* SWORDContext.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
|
||||
/**
|
||||
* This class represents the users who are involved in the
|
||||
* deposit or service document request process. This is the
|
||||
* authenticated primary user and the potentially null
|
||||
* onBehalfOf user.
|
||||
*
|
||||
* It can then answer various authorisation questions regarding
|
||||
* those users.
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @return the authenticated user
|
||||
*/
|
||||
public EPerson getAuthenticated()
|
||||
{
|
||||
return authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authenticated the eperson to set
|
||||
*/
|
||||
public void setAuthenticated(EPerson authenticated)
|
||||
{
|
||||
this.authenticated = authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the onBehalfOf user
|
||||
*/
|
||||
public EPerson getOnBehalfOf()
|
||||
{
|
||||
return onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onBehalfOf the eperson to set
|
||||
*/
|
||||
public void setOnBehalfOf(EPerson onBehalfOf)
|
||||
{
|
||||
this.onBehalfOf = onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 eperson
|
||||
* @return true if administrator, false if not
|
||||
* @throws SQLException
|
||||
*/
|
||||
public boolean isUserAdmin(Context context)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.authenticated != null)
|
||||
{
|
||||
Group admin = Group.find(context, 1);
|
||||
return admin.isMember(this.authenticated);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (SQLException 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 eperson
|
||||
* @return true if administrator, false if not
|
||||
* @throws SQLException
|
||||
*/
|
||||
public boolean isOnBehalfOfAdmin(Context context)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.onBehalfOf != null)
|
||||
{
|
||||
Group admin = Group.find(context, 1);
|
||||
return admin.isMember(this.onBehalfOf);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the authenticated user a member of the given group
|
||||
* or one of its sub groups?
|
||||
*
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public boolean isUserInGroup(Group group)
|
||||
{
|
||||
if (this.authenticated != null)
|
||||
{
|
||||
return isInGroup(group, this.authenticated);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the onBehalfOf user a member of the given group or
|
||||
* one of its sub groups
|
||||
*
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public boolean isOnBehalfOfInGroup(Group group)
|
||||
{
|
||||
if (this.onBehalfOf != null)
|
||||
{
|
||||
return isInGroup(group, this.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)
|
||||
{
|
||||
EPerson[] eps = group.getMembers();
|
||||
Group[] groups = group.getMemberGroups();
|
||||
|
||||
// is the user in the current group
|
||||
for (int i = 0; i < eps.length; i++)
|
||||
{
|
||||
if (eperson.getID() == eps[i].getID())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// is the eperson in the sub-groups (recurse)
|
||||
if (groups != null && groups.length > 0)
|
||||
{
|
||||
for (int j = 0; j < groups.length; j++)
|
||||
{
|
||||
if (isInGroup(groups[j], eperson))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find you
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the collections that the current SWORD
|
||||
* context will allow deposit onto in the given DSpace context
|
||||
*
|
||||
* @param context
|
||||
* @return the array of allowed collections
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
public Collection[] getAllowedCollections(Context context)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
// locate the collections to which the authenticated user has ADD rights
|
||||
Collection[] cols = Collection.findAuthorized(context, null, Constants.ADD);
|
||||
|
||||
// if there is no onBehalfOf user, just return the list
|
||||
if (this.getOnBehalfOf() == null)
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
|
||||
// if the onBehalfOf user is an administrator, return the list
|
||||
if (this.isOnBehalfOfAdmin(context))
|
||||
{
|
||||
return cols;
|
||||
}
|
||||
|
||||
// if we are here, then we have to filter the list of collections
|
||||
List<Collection> colList = new ArrayList<Collection>();
|
||||
|
||||
for (int i = 0; i < cols.length; i++)
|
||||
{
|
||||
// we check each collection to see if the onBehalfOf user
|
||||
// is permitted to deposit
|
||||
|
||||
// urgh, this is so inefficient, but the authorisation API is
|
||||
// a total hellish nightmare
|
||||
Group subs = cols[i].getSubmitters();
|
||||
if (isOnBehalfOfInGroup(subs))
|
||||
{
|
||||
colList.add(cols[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// now create the new array and return that
|
||||
Collection[] newCols = new Collection[colList.size()];
|
||||
newCols = colList.toArray((Collection[]) newCols);
|
||||
return newCols;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the current SWORD Context permit deposit into the given
|
||||
* collection in the given DSpace Context
|
||||
*
|
||||
* @param context
|
||||
* @param collection
|
||||
* @return
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
public boolean canSubmitTo(Context context, Collection collection)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
Group subs = collection.getSubmitters();
|
||||
if (isUserAdmin(context))
|
||||
{
|
||||
if (this.onBehalfOf != null)
|
||||
{
|
||||
if (isOnBehalfOfAdmin(context))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return isOnBehalfOfInGroup(subs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isUserInGroup(subs))
|
||||
{
|
||||
if (this.onBehalfOf != null)
|
||||
{
|
||||
if (isOnBehalfOfAdmin(context))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return isOnBehalfOfInGroup(subs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/* SWORDIngester.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import org.purl.sword.base.Deposit;
|
||||
|
||||
/**
|
||||
* 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 context
|
||||
* @param deposit
|
||||
* @return the result of the deposit
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
DepositResult ingest(Context context, Deposit deposit) throws DSpaceSWORDException;
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
/* SWORDIngesterFactory.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import org.purl.sword.base.Deposit;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* The current implementation is capable only of returning the single
|
||||
* implementation SWORDMETSIngester.
|
||||
*
|
||||
* @param context
|
||||
* @param deposit
|
||||
* @return
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
public static SWORDIngester getInstance(Context context, Deposit deposit)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
// so there is only one implementation at the moment, and this is it
|
||||
return new SWORDMETSIngester();
|
||||
}
|
||||
}
|
@@ -0,0 +1,273 @@
|
||||
/* SWORDMETSIngester.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DCDate;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.packager.PackageIngester;
|
||||
import org.dspace.content.packager.PackageParameters;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.dspace.handle.HandleManager;
|
||||
import org.dspace.workflow.WorkflowItem;
|
||||
import org.dspace.workflow.WorkflowManager;
|
||||
|
||||
import org.purl.sword.base.Deposit;
|
||||
|
||||
public class SWORDMETSIngester implements SWORDIngester
|
||||
{
|
||||
/** Log4j logger */
|
||||
public static Logger log = Logger.getLogger(SWORDMETSIngester.class);
|
||||
|
||||
/** holder for the messages that may be delivered back to the user */
|
||||
private StringBuilder verboseDesc = new StringBuilder();
|
||||
|
||||
/** is this a verbose deposit request */
|
||||
private boolean verbose = false;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.dspace.sword.SWORDIngester#ingest(org.dspace.core.Context, org.purl.sword.base.Deposit)
|
||||
*/
|
||||
public DepositResult ingest(Context context, Deposit deposit)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
try
|
||||
{
|
||||
// set the verbosity of the response
|
||||
this.verbose = deposit.isVerbose();
|
||||
|
||||
// the DSpaceMETSIngester requires an input stream
|
||||
InputStream is = deposit.getFile();
|
||||
|
||||
// get the target collection
|
||||
String loc = deposit.getLocation();
|
||||
CollectionLocation cl = new CollectionLocation();
|
||||
Collection collection = cl.getCollection(context, loc);
|
||||
message("Performing deposit using location: " + loc + "; ");
|
||||
message("Location resolves to collection with handle: " + collection.getHandle() +
|
||||
" and name: " + collection.getMetadata("name") + "; ");
|
||||
|
||||
// load the plugin manager for the required configuration
|
||||
String cfg = ConfigurationManager.getProperty("sword.mets-ingester.package-ingester");
|
||||
if (cfg == null || "".equals(cfg))
|
||||
{
|
||||
cfg = "METS"; // default to METS
|
||||
}
|
||||
message("Using package manifest format: " + cfg);
|
||||
|
||||
PackageIngester pi = (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, cfg);
|
||||
|
||||
// the licence is either in the zip or the mets manifest. Either way
|
||||
// it's none of our business here
|
||||
String licence = null;
|
||||
|
||||
// We don't need to include any parameters
|
||||
PackageParameters params = new PackageParameters();
|
||||
|
||||
// ingest the item
|
||||
WorkspaceItem wsi = pi.ingest(context, collection, is, params, licence);
|
||||
if (wsi == null)
|
||||
{
|
||||
message("Failed to ingest the package; throwing exception");
|
||||
throw new DSpaceSWORDException("Package Ingest failed");
|
||||
}
|
||||
|
||||
// now we can inject the newly constructed item into the workflow
|
||||
WorkflowItem wfi = WorkflowManager.startWithoutNotify(context, wsi);
|
||||
|
||||
// pull the item out so that we can report on it
|
||||
Item installedItem = wfi.getItem();
|
||||
|
||||
// update the item metadata to inclue the current time as
|
||||
// the updated date
|
||||
this.setUpdatedDate(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.
|
||||
boolean ignore = context.ignoreAuthorization();
|
||||
context.setIgnoreAuthorization(true);
|
||||
installedItem.update();
|
||||
context.setIgnoreAuthorization(ignore);
|
||||
|
||||
// for some reason, DSpace will not give you the handle automatically,
|
||||
// so we have to look it up
|
||||
String handle = HandleManager.findHandle(context, installedItem);
|
||||
|
||||
message("Ingest successful; ");
|
||||
message("Item created with internal identifier: " + installedItem.getID() + "; ");
|
||||
if (handle != null)
|
||||
{
|
||||
message("Item created with external identifier: " + handle + "; ");
|
||||
}
|
||||
else
|
||||
{
|
||||
message("No external identifier available at this stage (item in workflow); ");
|
||||
}
|
||||
|
||||
DepositResult dr = new DepositResult();
|
||||
dr.setItem(installedItem);
|
||||
dr.setHandle(handle);
|
||||
dr.setVerboseDescription(verboseDesc.toString());
|
||||
|
||||
return dr;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("caught exception: ", e);
|
||||
throw new DSpaceSWORDException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 msg
|
||||
*/
|
||||
private void message(String msg)
|
||||
{
|
||||
if (this.verbose)
|
||||
{
|
||||
verboseDesc.append("\n\n");
|
||||
verboseDesc.append(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 item
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
private void setUpdatedDate(Item item)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
String field = ConfigurationManager.getProperty("sword.updated.field");
|
||||
if (field == null || "".equals(field))
|
||||
{
|
||||
throw new DSpaceSWORDException("No configuration, or configuration is invalid for: sword.updated.field");
|
||||
}
|
||||
|
||||
DCValue dc = this.configToDC(field, null);
|
||||
item.clearMetadata(dc.schema, dc.element, dc.qualifier, Item.ANY);
|
||||
DCDate date = new DCDate(new Date());
|
||||
item.addMetadata(dc.schema, dc.element, dc.qualifier, null, date.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.slug.field");
|
||||
if (field == null || "".equals(field))
|
||||
{
|
||||
throw new DSpaceSWORDException("No configuration, or configuration is invalid for: sword.slug.field");
|
||||
}
|
||||
|
||||
DCValue dc = this.configToDC(field, null);
|
||||
item.clearMetadata(dc.schema, dc.element, dc.qualifier, Item.ANY);
|
||||
item.addMetadata(dc.schema, dc.element, dc.qualifier, null, slugVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* utility method to turn given metadata fields of the form
|
||||
* schema.element.qualifier into DCValue 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 DCValue object
|
||||
*
|
||||
* @param config
|
||||
* @param def
|
||||
* @return
|
||||
*/
|
||||
private DCValue configToDC(String config, String def)
|
||||
{
|
||||
DCValue dcv = new DCValue();
|
||||
dcv.schema = def;
|
||||
dcv.element= def;
|
||||
dcv.qualifier = def;
|
||||
|
||||
StringTokenizer stz = new StringTokenizer(config, ".");
|
||||
dcv.schema = stz.nextToken();
|
||||
dcv.element = stz.nextToken();
|
||||
if (stz.hasMoreTokens())
|
||||
{
|
||||
dcv.qualifier = stz.nextToken();
|
||||
}
|
||||
|
||||
return dcv;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,278 @@
|
||||
/* SWORDService.java
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.dspace.sword;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.Group;
|
||||
|
||||
import org.purl.sword.base.Service;
|
||||
import org.purl.sword.base.ServiceDocument;
|
||||
import org.purl.sword.base.ServiceLevel;
|
||||
import org.purl.sword.base.Workspace;
|
||||
|
||||
/**
|
||||
* Represents the SWORD service provided by DSpace. This class is
|
||||
* responsible for generating the Service Document, which is the
|
||||
* primary descriptor of the SWORD service
|
||||
*
|
||||
* @author Richard Jones
|
||||
*
|
||||
*/
|
||||
public class SWORDService
|
||||
{
|
||||
/** Log4j logging instance */
|
||||
public static Logger log = Logger.getLogger(SWORDService.class);
|
||||
|
||||
/** The DSpace context under which to perform requests */
|
||||
private Context context = null;
|
||||
|
||||
/** The SWORD context of the request */
|
||||
private SWORDContext swordContext = null;
|
||||
|
||||
/**
|
||||
* Set the DSpace context to use
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void setContext(Context context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SWORD Context to use
|
||||
*
|
||||
* @param sc
|
||||
*/
|
||||
public void setSWORDContext(SWORDContext sc)
|
||||
{
|
||||
this.swordContext = sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
|
||||
if (swordContext == null)
|
||||
{
|
||||
throw new DSpaceSWORDException("The SWORD Context is null; please set it before calling getServiceDocument");
|
||||
}
|
||||
|
||||
// DSpace will support the top level service option
|
||||
ServiceLevel sl = ServiceLevel.ONE;
|
||||
|
||||
// can we dry-run requests
|
||||
boolean noOp = true;
|
||||
|
||||
// can we be verbose in our actions
|
||||
boolean verbose = true;
|
||||
|
||||
// construct a new service document
|
||||
Service service = new Service(sl, noOp, verbose);
|
||||
|
||||
// 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);
|
||||
|
||||
Collection[] cols = swordContext.getAllowedCollections(context);
|
||||
for (int i = 0; i < cols.length; i++)
|
||||
{
|
||||
org.purl.sword.base.Collection scol = this.buildSwordCollection(cols[i]);
|
||||
workspace.addCollection(scol);
|
||||
}
|
||||
|
||||
service.addWorkspace(workspace);
|
||||
|
||||
ServiceDocument sd = new ServiceDocument(service);
|
||||
return sd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the given eperson a DSpace administrator? This translates
|
||||
* as asking the question of whether the given eperson a member
|
||||
* of the special DSpace group Administrator, with id 1
|
||||
*
|
||||
* @param eperson
|
||||
* @return true if administrator, false if not
|
||||
* @throws SQLException
|
||||
*/
|
||||
private boolean isAdmin(EPerson eperson)
|
||||
throws SQLException
|
||||
{
|
||||
Group admin = Group.find(context, 1);
|
||||
return admin.isMember(eperson);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private boolean isInGroup(Group group, EPerson eperson)
|
||||
{
|
||||
EPerson[] eps = group.getMembers();
|
||||
Group[] groups = group.getMemberGroups();
|
||||
|
||||
// is the user in the current group
|
||||
for (int i = 0; i < eps.length; i++)
|
||||
{
|
||||
if (eperson.getID() == eps[i].getID())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// is the eperson in the sub-groups (recurse)
|
||||
if (groups != null && groups.length > 0)
|
||||
{
|
||||
for (int j = 0; j < groups.length; j++)
|
||||
{
|
||||
if (isInGroup(groups[j], eperson))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find you
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an instance of a SWORD collection from an instance of
|
||||
* a DSpace collection.
|
||||
*
|
||||
* Note that DSpace collections do not have an analogue of the
|
||||
* SWORD field "treatment", so this field is always blank.
|
||||
*
|
||||
* @param col
|
||||
* @return the SWORD Collection object
|
||||
* @throws DSpaceSWORDException
|
||||
*/
|
||||
private org.purl.sword.base.Collection buildSwordCollection(Collection col)
|
||||
throws DSpaceSWORDException
|
||||
{
|
||||
org.purl.sword.base.Collection scol = new org.purl.sword.base.Collection();
|
||||
|
||||
// prepare the parameters to be put in the sword collection
|
||||
CollectionLocation cl = new CollectionLocation();
|
||||
String location = cl.getLocation(col);
|
||||
|
||||
// collection title is just its name
|
||||
String title = col.getMetadata("name");
|
||||
|
||||
// the collection policy is the licence to which the collection adheres
|
||||
String collectionPolicy = col.getLicense();
|
||||
|
||||
// FIXME: what is the treatment? Doesn't seem appropriate for DSpace
|
||||
// String treatment = " ";
|
||||
|
||||
// the format namespace is only METS in this implementation
|
||||
String namespace = "http://www.loc.gov/METS";
|
||||
|
||||
// abstract is the short description of the collection
|
||||
String dcAbstract = col.getMetadata("short_description");
|
||||
|
||||
// we just do support mediation
|
||||
boolean mediation = true;
|
||||
|
||||
// the list of mime types that we accept
|
||||
// for the time being, we just take a zip, and we have to trust what's in it
|
||||
String zip = "application/zip";
|
||||
|
||||
// load up the sword collection
|
||||
scol.setLocation(location);
|
||||
|
||||
// add the title if it exists
|
||||
if (title != null && !"".equals(title))
|
||||
{
|
||||
scol.setTitle(title);
|
||||
}
|
||||
|
||||
// add the collection policy if it exists
|
||||
if (collectionPolicy != null && !"".equals(collectionPolicy))
|
||||
{
|
||||
scol.setCollectionPolicy(collectionPolicy);
|
||||
}
|
||||
|
||||
// FIXME: leave the treatment out for the time being,
|
||||
// as there is no analogue
|
||||
// scol.setTreatment(treatment);
|
||||
|
||||
// add the abstract if it exists
|
||||
if (dcAbstract != null && !"".equals(dcAbstract))
|
||||
{
|
||||
scol.setAbstract(dcAbstract);
|
||||
}
|
||||
|
||||
scol.setMediation(mediation);
|
||||
scol.addAccepts(zip);
|
||||
scol.setFormatNamespace(namespace);
|
||||
|
||||
return scol;
|
||||
}
|
||||
}
|
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Utility class that holds Checksum related methods.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class ChecksumUtils
|
||||
{
|
||||
/**
|
||||
* Generate an MD5 hash for the file that is specified in the
|
||||
* filepath. The hash is returned as a String representation.
|
||||
*
|
||||
* @param filepath The path to the file to load.
|
||||
* @return A string hash of the file.
|
||||
* @throws NoSuchAlgorithmException If the MD5 algorithm is
|
||||
* not supported by the installed virtual machine.
|
||||
*
|
||||
* @throws IOException If there is an error accessing the file.
|
||||
*/
|
||||
public static String generateMD5(String filepath)
|
||||
throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
return generateMD5(new FileInputStream(filepath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an MD5 hash for the file that is specified in the
|
||||
* filepath. The hash is returned as a String representation.
|
||||
*
|
||||
* @param md5Stream The InputStream to checksum.
|
||||
* @return A string hash of the file.
|
||||
* @throws NoSuchAlgorithmException If the MD5 algorithm is
|
||||
* not supported by the installed virtual machine.
|
||||
*
|
||||
* @throws IOException If there is an error accessing the file.
|
||||
*/
|
||||
public static String generateMD5(InputStream md5Stream)
|
||||
throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
String md5 = null;
|
||||
|
||||
try
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.reset();
|
||||
|
||||
byte[] bytes = new byte[1024];
|
||||
int count = 0;
|
||||
while( (count = md5Stream.read(bytes)) != -1 )
|
||||
{
|
||||
md.update(bytes, 0, count);
|
||||
}
|
||||
|
||||
byte[] md5Digest = md.digest();
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for( byte b : md5Digest )
|
||||
{
|
||||
// 0xFF is used to handle the issue of negative numbers in the bytes
|
||||
String hex = Integer.toHexString(b & 0xFF);
|
||||
if( hex.length() == 1 )
|
||||
{
|
||||
buffer.append("0");
|
||||
}
|
||||
buffer.append(hex);
|
||||
}
|
||||
|
||||
md5 = buffer.toString();
|
||||
}
|
||||
catch(NoSuchAlgorithmException ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeInfo("Error accessing string");
|
||||
throw ex; // rethrow
|
||||
}
|
||||
finally
|
||||
{
|
||||
if( md5Stream != null )
|
||||
{
|
||||
md5Stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
return md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an MD5 hash for the file that is specified in the
|
||||
* filepath. The hash is returned as a String representation.
|
||||
*
|
||||
* @param bytes The byte array to checksum.
|
||||
* @return A string hash of the file.
|
||||
* @throws NoSuchAlgorithmException If the MD5 algorithm is
|
||||
* not supported by the installed virtual machine.
|
||||
*
|
||||
* @throws IOException If there is an error accessing the file.
|
||||
*/
|
||||
public static String generateMD5(byte[] bytes)
|
||||
throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
String md5 = null;
|
||||
|
||||
try
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.reset();
|
||||
|
||||
md.update(bytes);
|
||||
|
||||
|
||||
byte[] md5Digest = md.digest();
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for( byte b : md5Digest )
|
||||
{
|
||||
// 0xFF is used to handle the issue of negative numbers in the bytes
|
||||
String hex = Integer.toHexString(b & 0xFF);
|
||||
if( hex.length() == 1 )
|
||||
{
|
||||
buffer.append("0");
|
||||
}
|
||||
buffer.append(hex);
|
||||
}
|
||||
|
||||
md5 = buffer.toString();
|
||||
}
|
||||
catch(NoSuchAlgorithmException ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeInfo("Error accessing string");
|
||||
throw ex; // rethrow
|
||||
}
|
||||
|
||||
return md5;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
|
||||
System.out.println(ChecksumUtils.generateMD5(args[0]));
|
||||
}
|
||||
}
|
495
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Collection.java
Executable file
495
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Collection.java
Executable file
@@ -0,0 +1,495 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:54 $
|
||||
* Revision : $Revision: 1.4 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.w3.atom.ContentType;
|
||||
import org.w3.atom.Title;
|
||||
|
||||
import nu.xom.Attribute;
|
||||
import nu.xom.Elements;
|
||||
import nu.xom.Element;
|
||||
|
||||
/**
|
||||
* A representation of a SWORD Collection.
|
||||
*
|
||||
* http://www.ukoln.ac.uk/repositories/digirep/index/SWORD_APP_Profile_0.5
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Collection extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The element name.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "collection";
|
||||
|
||||
/**
|
||||
* Collection location, expressed as a URL.
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* Holds the ATOM Title for the collection.
|
||||
*/
|
||||
private Title title;
|
||||
|
||||
/**
|
||||
* List of the APP:Accept elements.
|
||||
*/
|
||||
private List<String> accepts;
|
||||
|
||||
/**
|
||||
* Holds the SWORD Collection policy.
|
||||
*/
|
||||
private String collectionPolicy;
|
||||
|
||||
/**
|
||||
* The SWORD mediation value. Indicates if mediation is allowed.
|
||||
*/
|
||||
private boolean mediation;
|
||||
|
||||
/**
|
||||
* Internal value to track if the mediation value has been
|
||||
* set programmatically.
|
||||
*/
|
||||
private boolean mediationSet;
|
||||
|
||||
/**
|
||||
* The SWORD treatment value.
|
||||
*/
|
||||
private String treatment;
|
||||
|
||||
/**
|
||||
* The SWORD namespace.
|
||||
*/
|
||||
private String namespace;
|
||||
|
||||
/**
|
||||
* The DC Terms Abstract details.
|
||||
*/
|
||||
private String dcAbstract;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Collection()
|
||||
{
|
||||
super(null);
|
||||
accepts = new ArrayList<String>();
|
||||
mediationSet = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and set the initial location for the collection.
|
||||
*
|
||||
* @param location The initial location, expressed as a URL.
|
||||
*/
|
||||
public Collection(String location)
|
||||
{
|
||||
super(null);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array that holds all of the Accept details.
|
||||
*
|
||||
* @return An array of strings. Each string represents an
|
||||
* individual accept element. The array will have a length
|
||||
* of 0 if no accepts elements are stored in this collection.
|
||||
*/
|
||||
public String[] getAccepts()
|
||||
{
|
||||
String[] values = new String[this.accepts.size()];
|
||||
return (String[])accepts.toArray(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array that holds all of the Accept details.
|
||||
*
|
||||
* @return An array of strings. Each string represents an
|
||||
* individual accept element. The array will have a length
|
||||
* of 0 if no accepts elements are stored in this collection.
|
||||
*/
|
||||
public List<String> getAcceptsList()
|
||||
{
|
||||
return accepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an accepts entry.
|
||||
*
|
||||
* @param accepts The accepts value.
|
||||
*/
|
||||
public void addAccepts(String accepts) {
|
||||
this.accepts.add(accepts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all of the accepts associated with this Collection.
|
||||
*/
|
||||
public void clearAccepts( )
|
||||
{
|
||||
this.accepts.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection policy.
|
||||
*
|
||||
* @return The SWORD collectionPolicy.
|
||||
*/
|
||||
public String getCollectionPolicy() {
|
||||
return collectionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the collection policy.
|
||||
*
|
||||
* @param collectionPolicy The collection policy.
|
||||
*/
|
||||
public void setCollectionPolicy(String collectionPolicy) {
|
||||
this.collectionPolicy = collectionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location.
|
||||
*
|
||||
* @return TShe location
|
||||
*/
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location.
|
||||
*
|
||||
* @param location The location.
|
||||
*/
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mediation value.
|
||||
*
|
||||
* @return The mediation
|
||||
*/
|
||||
public boolean getMediation() {
|
||||
return mediation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mediation value.
|
||||
*
|
||||
* @param mediation The mediation value.
|
||||
*/
|
||||
public void setMediation(boolean mediation) {
|
||||
this.mediation = mediation;
|
||||
mediationSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* See getFormatNamespace.
|
||||
* @return the namespace
|
||||
* @deprecated Use getFormatNamespace()
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return getFormatNamespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format namespace.
|
||||
*
|
||||
* @return The format namespace.
|
||||
*/
|
||||
public String getFormatNamespace()
|
||||
{
|
||||
return namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* See setFormatNamespace.
|
||||
* @param namespace the namespace to set
|
||||
* @deprecated Use setFormatNamespace
|
||||
*/
|
||||
public void setNamespace(String namespace) {
|
||||
setFormatNamespace(namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the format namespace.
|
||||
*
|
||||
* @param namespace The namespace.
|
||||
*/
|
||||
public void setFormatNamespace(String namespace)
|
||||
{
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DC Term abstract.
|
||||
*
|
||||
* @return The abstract.
|
||||
*/
|
||||
public String getAbstract()
|
||||
{
|
||||
return dcAbstract;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the abstract.
|
||||
*
|
||||
* @param abstractString The abstract.
|
||||
*/
|
||||
public void setAbstract(String abstractString)
|
||||
{
|
||||
this.dcAbstract = abstractString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title. This will set the title type to ContentType.TEXT.
|
||||
*
|
||||
* @param title The title.
|
||||
*/
|
||||
public void setTitle( String title )
|
||||
{
|
||||
if( this.title == null)
|
||||
{
|
||||
this.title = new Title();
|
||||
}
|
||||
this.title.setContent(title);
|
||||
this.title.setType(ContentType.TEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title.
|
||||
*
|
||||
* @return The title, or <code>null</code> if no title has been set.
|
||||
*/
|
||||
public String getTitle( )
|
||||
{
|
||||
if( title == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return title.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the treatment value.
|
||||
*
|
||||
* @return The treatment.
|
||||
*/
|
||||
public String getTreatment()
|
||||
{
|
||||
return treatment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the treatment.
|
||||
*
|
||||
* @param treatment The treatment.
|
||||
*/
|
||||
public void setTreatment(String treatment)
|
||||
{
|
||||
this.treatment = treatment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string representation of this object. This is
|
||||
* equivalent to calling marshall().toString().
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
Element element = marshall();
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this object to an Element object.
|
||||
*
|
||||
* @return A XOM Element that holds the data for this Content element.
|
||||
*/
|
||||
public Element marshall( )
|
||||
{
|
||||
// convert data into XOM elements and return the 'root', i.e. the one
|
||||
// that represents the collection.
|
||||
Element collection = new Element(ELEMENT_NAME, Namespaces.NS_APP);
|
||||
Attribute href = new Attribute("href", location);
|
||||
collection.addAttribute(href);
|
||||
|
||||
//title = new Title();
|
||||
collection.appendChild(title.marshall());
|
||||
|
||||
Element acceptsElement = null;
|
||||
for( String item : accepts )
|
||||
{
|
||||
acceptsElement = new Element("accepts", Namespaces.NS_APP);
|
||||
acceptsElement.appendChild(item);
|
||||
collection.appendChild(acceptsElement);
|
||||
}
|
||||
|
||||
if( collectionPolicy != null )
|
||||
{
|
||||
Element colPolicyElement = new Element("sword:collectionPolicy", Namespaces.NS_SWORD);
|
||||
colPolicyElement.appendChild(collectionPolicy);
|
||||
collection.appendChild(colPolicyElement);
|
||||
}
|
||||
|
||||
if( dcAbstract != null )
|
||||
{
|
||||
Element dcAbstractElement = new Element("dcterms:abstract", Namespaces.NS_DC_TERMS);
|
||||
dcAbstractElement.appendChild(dcAbstract);
|
||||
collection.appendChild(dcAbstractElement);
|
||||
}
|
||||
|
||||
if( mediationSet )
|
||||
{
|
||||
Element mediationElement = new Element("sword:mediation", Namespaces.NS_SWORD);
|
||||
mediationElement.appendChild(Boolean.toString(mediation));
|
||||
collection.appendChild(mediationElement);
|
||||
}
|
||||
|
||||
// treatment
|
||||
if( treatment != null )
|
||||
{
|
||||
Element treatmentElement = new Element("sword:treatment", Namespaces.NS_SWORD);
|
||||
treatmentElement.appendChild(treatment);
|
||||
collection.appendChild(treatmentElement);
|
||||
}
|
||||
|
||||
// namespace
|
||||
if( namespace != null )
|
||||
{
|
||||
Element namespaceElement = new Element("sword:namespace", Namespaces.NS_SWORD);
|
||||
namespaceElement.appendChild(namespace);
|
||||
collection.appendChild(namespaceElement);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the content element into the data in this object.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain a
|
||||
* content element or if there are problems
|
||||
* accessing the data.
|
||||
*/
|
||||
public void unmarshall( Element collection )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(collection, "collection", Namespaces.NS_APP))
|
||||
{
|
||||
throw new UnmarshallException( "Not an app:collection element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// retrieve the attributes
|
||||
int count = collection.getAttributeCount();
|
||||
Attribute a = null;
|
||||
for( int i = 0; i < count; i++ )
|
||||
{
|
||||
a = collection.getAttribute(i);
|
||||
if( "href".equals(a.getQualifiedName()))
|
||||
{
|
||||
location = a.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
accepts.clear();
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = collection.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
// FIXME - atom assumes that it has been defined. not correct.
|
||||
if( isInstanceOf(element, "title", Namespaces.NS_ATOM ) )
|
||||
{
|
||||
title = new Title();
|
||||
title.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "accepts", Namespaces.NS_APP ))
|
||||
{
|
||||
accepts.add(unmarshallString(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "collectionPolicy", Namespaces.NS_SWORD ))
|
||||
{
|
||||
collectionPolicy = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "abstract", Namespaces.NS_DC_TERMS ))
|
||||
{
|
||||
dcAbstract = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "mediation", Namespaces.NS_SWORD ))
|
||||
{
|
||||
setMediation(unmarshallBoolean(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "treatment", Namespaces.NS_SWORD ))
|
||||
{
|
||||
treatment = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "namespace", Namespaces.NS_SWORD ))
|
||||
{
|
||||
namespace = unmarshallString(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Collection: " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse an element in Collection", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
317
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Deposit.java
Executable file
317
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Deposit.java
Executable file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Represents a deposit.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*
|
||||
*/
|
||||
public class Deposit
|
||||
{
|
||||
|
||||
/** The File deposited */
|
||||
private InputStream file;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private int contentLength;
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String onBehalfOf;
|
||||
|
||||
private String slug;
|
||||
|
||||
private String md5;
|
||||
|
||||
private boolean verbose;
|
||||
|
||||
private boolean noOp;
|
||||
|
||||
private String formatNamespace;
|
||||
|
||||
private String depositID;
|
||||
|
||||
private String IPAddress;
|
||||
|
||||
private String location;
|
||||
|
||||
private String filename;
|
||||
|
||||
/**
|
||||
* Submission created
|
||||
*/
|
||||
public static final int CREATED = HttpServletResponse.SC_CREATED;
|
||||
|
||||
/**
|
||||
* Submission accepted.
|
||||
*/
|
||||
public static final int ACCEPTED = HttpServletResponse.SC_ACCEPTED;
|
||||
|
||||
/**
|
||||
* @return the authenticatedUserName
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authenticatedUserName the authenticatedUserName to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the authenticatedUserPassword
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the contentLength
|
||||
*/
|
||||
public int getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentLength the contentLength to set
|
||||
*/
|
||||
public void setContentLength(int contentLength) {
|
||||
this.contentLength = contentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the contentType
|
||||
*/
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentType the contentType to set
|
||||
*/
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the depositID
|
||||
*/
|
||||
public String getDepositID() {
|
||||
return depositID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param depositID the depositID to set
|
||||
*/
|
||||
public void setDepositID(String depositID) {
|
||||
this.depositID = depositID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the file
|
||||
*/
|
||||
public InputStream getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file the file to set
|
||||
*/
|
||||
public void setFile(InputStream file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the formatNamespace
|
||||
*/
|
||||
public String getFormatNamespace() {
|
||||
return formatNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param formatNamespace the formatNamespace to set
|
||||
*/
|
||||
public void setFormatNamespace(String formatNamespace) {
|
||||
this.formatNamespace = formatNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the md5
|
||||
*/
|
||||
public String getMd5() {
|
||||
return md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param md5 the md5 to set
|
||||
*/
|
||||
public void setMd5(String md5) {
|
||||
this.md5 = md5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the noOp
|
||||
*/
|
||||
public boolean isNoOp() {
|
||||
return noOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param noOp the noOp to set
|
||||
*/
|
||||
public void setNoOp(boolean noOp) {
|
||||
this.noOp = noOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the onBehalfOf
|
||||
*/
|
||||
public String getOnBehalfOf() {
|
||||
return onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onBehalfOf the onBehalfOf to set
|
||||
*/
|
||||
public void setOnBehalfOf(String onBehalfOf) {
|
||||
this.onBehalfOf = onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the slug
|
||||
*/
|
||||
public String getSlug() {
|
||||
return slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param slug the slug to set
|
||||
*/
|
||||
public void setSlug(String slug) {
|
||||
this.slug = slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the verbose
|
||||
*/
|
||||
public boolean isVerbose() {
|
||||
return verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param verbose the verbose to set
|
||||
*/
|
||||
public void setVerbose(boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IP address of the user
|
||||
*
|
||||
* @return the IP address
|
||||
*/
|
||||
public String getIPAddress() {
|
||||
return IPAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IP address of the user
|
||||
*
|
||||
* @param String the IP address
|
||||
*/
|
||||
public void setIPAddress(String IPAddress) {
|
||||
this.IPAddress = IPAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the deposit
|
||||
*
|
||||
* @return the location of the deposit
|
||||
*/
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the deposit
|
||||
*
|
||||
* @param String the location
|
||||
*/
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the filename that is associated with this deposit.
|
||||
*
|
||||
* @return The filename.
|
||||
*/
|
||||
public String getFilename()
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename that is to be used for this deposit.
|
||||
*
|
||||
* @param filename The filename.
|
||||
*/
|
||||
public void setFilename(String filename)
|
||||
{
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:55 $
|
||||
* Revision : $Revision: 1.3 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import nu.xom.Builder;
|
||||
import nu.xom.Document;
|
||||
import nu.xom.Element;
|
||||
import nu.xom.ParsingException;
|
||||
import nu.xom.Serializer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public class DepositResponse
|
||||
{
|
||||
private SWORDEntry entry;
|
||||
|
||||
private int httpResponse;
|
||||
|
||||
public DepositResponse( int httpResponse )
|
||||
{
|
||||
entry = new SWORDEntry();
|
||||
this.httpResponse = httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
public void setEntry( SWORDEntry entry )
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
public SWORDEntry getEntry( )
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
|
||||
public int getHttpResponse() {
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
public void setHttpResponse(int httpResponse) {
|
||||
this.httpResponse = httpResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String marshall( )
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
Serializer serializer = new Serializer(stream, "UTF-8");
|
||||
serializer.setIndent(3);
|
||||
serializer.setMaxLength(64);
|
||||
|
||||
if( entry != null )
|
||||
{
|
||||
Document doc = new Document(entry.marshall());
|
||||
serializer.write(doc);
|
||||
System.out.println(stream.toString());
|
||||
return stream.toString();
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
System.err.println(ex);
|
||||
}
|
||||
|
||||
return null; // default return value.
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param xml
|
||||
* @throws UnmarshallException
|
||||
*/
|
||||
public void unmarshall(String xml)
|
||||
throws UnmarshallException
|
||||
{
|
||||
try
|
||||
{
|
||||
Builder builder = new Builder();
|
||||
Document doc = builder.build(xml, "http://something.com/here");
|
||||
Element root = doc.getRootElement();
|
||||
|
||||
entry = new SWORDEntry( );
|
||||
entry.unmarshall(root);
|
||||
|
||||
}
|
||||
catch( ParsingException ex )
|
||||
{
|
||||
throw new UnmarshallException("Unable to parse the XML", ex );
|
||||
}
|
||||
catch( IOException ex )
|
||||
{
|
||||
throw new UnmarshallException("Error acessing the file?", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return marshall();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Definition of the error codes that will be used in
|
||||
* the SWORD protocol (in X-Error-Code).
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public interface ErrorCodes
|
||||
{
|
||||
/**
|
||||
* ErrorContent - where the supplied format is not the same as that
|
||||
* identified in the X-Format-Namespace and/or that supported by the
|
||||
* server
|
||||
*/
|
||||
public static final String ERROR_CONTENT = "ErrorContent";
|
||||
|
||||
/**
|
||||
* ErrorChecksumMismatch - where the checksum of the file recevied does
|
||||
* not match the checksum given in the header
|
||||
*/
|
||||
public static final String ERROR_CHECKSUM_MISMATCH = "ErrorChecksumMismatch";
|
||||
|
||||
/**
|
||||
* ErrorBadRequest - where parameters are not understood
|
||||
*/
|
||||
public static final String ERROR_BAD_REQUEST = "ErrorBadRequest";
|
||||
|
||||
/**
|
||||
* TargetOwnerUnknown - where the server cannot identify the specified
|
||||
* TargetOwner
|
||||
*/
|
||||
public static final String TARGET_OWNER_UKNOWN = "TargetOwnerUnknown";
|
||||
|
||||
/**
|
||||
* MediationNotAllowed - where a client has attempted a mediated deposit,
|
||||
* but this is not supported by the server
|
||||
*/
|
||||
public static final String MEDIATION_NOT_ALLOWED = "MediationNotAllowed";
|
||||
}
|
105
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/HttpHeaders.java
Executable file
105
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/HttpHeaders.java
Executable file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Definition of the additional HTTP Header tags that will be used in
|
||||
* the SWORD protocol.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public interface HttpHeaders
|
||||
{
|
||||
/**
|
||||
* The HTTP Header label that specifies the MD5 label.
|
||||
*/
|
||||
public static final String CONTENT_MD5 = "Content-MD5";
|
||||
|
||||
/**
|
||||
* The HTTP Header label that specifies the MD5 label.
|
||||
*/
|
||||
public static final String CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
/**
|
||||
* The HTTP Header label that specifies the On Behalf Of information.
|
||||
*/
|
||||
public static final String X_ON_BEHALF_OF = "X-On-Behalf-Of";
|
||||
|
||||
/**
|
||||
* The HTTP Header label that specifies the Format Namespace information.
|
||||
*/
|
||||
public static final String X_FORMAT_NAMESPACE = "X-Format-Namespace";
|
||||
|
||||
/**
|
||||
* The HTTP Header label that specifies the desired Verbose status.
|
||||
*/
|
||||
public static final String X_VERBOSE = "X-Verbose";
|
||||
|
||||
/**
|
||||
* The HTTP Header label that specifies the desired NoOp status.
|
||||
*/
|
||||
public static final String X_NO_OP = "X-No-Op";
|
||||
|
||||
/**
|
||||
* The HTTP Header that specifies the error code information.
|
||||
*/
|
||||
public static final String X_ERROR_CODE = "X-Error-Code";
|
||||
|
||||
/**
|
||||
* The Slug header.
|
||||
*/
|
||||
public static final String SLUG = "Slug";
|
||||
|
||||
/**
|
||||
* Submission created
|
||||
*/
|
||||
public static final int CREATED = HttpServletResponse.SC_CREATED;
|
||||
|
||||
/**
|
||||
* Submission accepted.
|
||||
*/
|
||||
public static final int ACCEPTED = HttpServletResponse.SC_ACCEPTED;
|
||||
|
||||
/**
|
||||
* The HTTP Header that specifies the content disposition item. This is
|
||||
* used by the SWORD profile to identify the name for the deposit.
|
||||
*/
|
||||
public static final String CONTENT_DISPOSITION = "Content-Disposition";
|
||||
}
|
106
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/InfoLogger.java
Executable file
106
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/InfoLogger.java
Executable file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:55 $
|
||||
* Revision : $Revision: 1.3 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class InfoLogger
|
||||
{
|
||||
/**
|
||||
* Single instance of the InfoLogger that can be used by all
|
||||
* calling classes.
|
||||
*/
|
||||
private static InfoLogger logger = null;
|
||||
|
||||
/**
|
||||
* Set the default level to ERROR messages only.
|
||||
*/
|
||||
private InfoLoggerLevel level = InfoLoggerLevel.ERROR;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setLevel( InfoLoggerLevel level )
|
||||
{
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the single instance of this class. If this is the first call,
|
||||
* the logger is created on this call.
|
||||
*
|
||||
* @return The InfoLogger.
|
||||
*/
|
||||
public static InfoLogger getLogger()
|
||||
{
|
||||
if( logger == null )
|
||||
{
|
||||
logger = new InfoLogger();
|
||||
}
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void writeError(String message)
|
||||
{
|
||||
// always log errors
|
||||
System.err.println("Error: " + message );
|
||||
}
|
||||
|
||||
public void writeInfo(String message)
|
||||
{
|
||||
if( level == InfoLoggerLevel.ERROR_WARNING_INFO )
|
||||
{
|
||||
System.err.println("Info: " + message );
|
||||
}
|
||||
}
|
||||
|
||||
public void writeWarning(String message)
|
||||
{
|
||||
if( level != InfoLoggerLevel.ERROR )
|
||||
{
|
||||
System.err.println("Warning: " + message );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* This enumeration determines the logging level to be used for the InfoLogger class.
|
||||
*
|
||||
* @author Neil Taylor (nst@aber.ac.uk)
|
||||
*/
|
||||
public enum InfoLoggerLevel
|
||||
{
|
||||
ERROR,
|
||||
ERROR_WARNING,
|
||||
ERROR_WARNING_INFO
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* List of the namespaces that are used by SWORD.
|
||||
*
|
||||
* Last updated on: $Date: 2007/09/21 15:18:55 $
|
||||
*
|
||||
* @author Neil Taylor
|
||||
* @version $Revision: 1.3 $
|
||||
*
|
||||
*/
|
||||
public interface Namespaces {
|
||||
|
||||
/**
|
||||
* Atom Publishing Protocol (APP) Namespace.
|
||||
*/
|
||||
public static final String NS_APP = "http://purl.org/atom/app#";
|
||||
|
||||
/**
|
||||
* ATOM Namespace.
|
||||
*/
|
||||
public static final String NS_ATOM = "http://www.w3.org/2005/Atom";
|
||||
|
||||
/**
|
||||
* Sword Namespace.
|
||||
*/
|
||||
public static final String NS_SWORD = "http://purl.org/net/sword/";
|
||||
|
||||
/**
|
||||
* DC Terms Namespace.
|
||||
*/
|
||||
public static final String NS_DC_TERMS = "http://purl.org/dc/terms/";
|
||||
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Represents a SWORD exception to be thrown if bad authentication credentials
|
||||
* are passed to a repository.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class SWORDAuthenticationException extends Exception
|
||||
{
|
||||
/**
|
||||
* Create a new instance and store the specified message and source data.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
* @param source The original exception that lead to this exception. This
|
||||
* can be <code>null</code>.
|
||||
*/
|
||||
public SWORDAuthenticationException(String message, Exception source)
|
||||
{
|
||||
super(message, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified message.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
*/
|
||||
public SWORDAuthenticationException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Represents a SWORD exception to be thrown if a format supplied in a deposit
|
||||
* is not accepted by the repository.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class SWORDContentTypeException extends Exception
|
||||
{
|
||||
|
||||
}
|
282
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/SWORDEntry.java
Executable file
282
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/SWORDEntry.java
Executable file
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.w3.atom.Entry;
|
||||
|
||||
/**
|
||||
* Extension of the ATOM Entry class. This adds support for the additional
|
||||
* SWORD elements. These elements reside inside the ATOM Entry object,
|
||||
* created in org.w3.atom.Entry class.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class SWORDEntry extends Entry
|
||||
{
|
||||
/**
|
||||
* Specifies whether the document was run in noOp mode, i.e.
|
||||
* if the document records that no operation was taken for the
|
||||
* deposit other than to generate a response.
|
||||
*/
|
||||
private boolean noOp;
|
||||
|
||||
/**
|
||||
* Use to supply a verbose description.
|
||||
*/
|
||||
private String verboseDescription;
|
||||
|
||||
/**
|
||||
* Used for a human readable statement about what treatment
|
||||
* the deposited resource has received. Include either a
|
||||
* text description or a URI.
|
||||
*/
|
||||
private String treatment;
|
||||
|
||||
/**
|
||||
* Used to record the format namespace.
|
||||
*/
|
||||
private String formatNamespace;
|
||||
|
||||
/**
|
||||
* Used to determine if the noOp value has been set.
|
||||
*/
|
||||
private boolean noOpSet;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the class.
|
||||
*/
|
||||
public SWORDEntry()
|
||||
{
|
||||
// NO BODY
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value of NoOp.
|
||||
*
|
||||
* @return True if the value is set, false otherwise.
|
||||
*/
|
||||
public boolean isNoOp()
|
||||
{
|
||||
return noOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method to set noOp. It should be called even by internal
|
||||
* methods so that the object can determine if the value has been set
|
||||
* or whether it just holds the default value.
|
||||
*
|
||||
* @param noOp
|
||||
*/
|
||||
public void setNoOp(boolean noOp)
|
||||
{
|
||||
this.noOp = noOp;
|
||||
this.noOpSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the noOp value has been set. This should be called
|
||||
* if you want to know whether false for noOp means that it is the
|
||||
* default value (i.e. no code has set it) or it is a value that
|
||||
* has been actively set.
|
||||
*
|
||||
* @return True if the value has been set. Otherwise, false.
|
||||
*/
|
||||
public boolean isNoOpSet()
|
||||
{
|
||||
return noOpSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Verbose Description for this entry.
|
||||
*
|
||||
* @return The description.
|
||||
*/
|
||||
public String getVerboseDescription()
|
||||
{
|
||||
return verboseDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the verbose description.
|
||||
*
|
||||
* @param verboseDescription The description.
|
||||
*/
|
||||
public void setVerboseDescription(String verboseDescription)
|
||||
{
|
||||
this.verboseDescription = verboseDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the treatment value.
|
||||
*
|
||||
* @return The treatment.
|
||||
*/
|
||||
public String getTreatment()
|
||||
{
|
||||
return treatment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the treatment value.
|
||||
*
|
||||
* @param treatment The treatment.
|
||||
*/
|
||||
public void setTreatment(String treatment)
|
||||
{
|
||||
this.treatment = treatment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the marshall method in the parent Entry. This will
|
||||
* call the parent marshall method and then add the additional
|
||||
* elements that have been added in this subclass.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element entry = super.marshall();
|
||||
|
||||
if( treatment != null )
|
||||
{
|
||||
Element treatmentElement = new Element("sword:treatment", Namespaces.NS_SWORD);
|
||||
treatmentElement.appendChild(treatment);
|
||||
entry.appendChild(treatmentElement);
|
||||
}
|
||||
|
||||
if( formatNamespace != null )
|
||||
{
|
||||
Element formatNamespaceElement = new Element("sword:formatNamespace", Namespaces.NS_SWORD);
|
||||
formatNamespaceElement.appendChild(formatNamespace);
|
||||
entry.appendChild(formatNamespaceElement);
|
||||
}
|
||||
|
||||
if( verboseDescription != null )
|
||||
{
|
||||
Element verboseDescriptionElement = new Element("sword:verboseDescription", Namespaces.NS_SWORD);
|
||||
verboseDescriptionElement.appendChild(verboseDescription);
|
||||
entry.appendChild(verboseDescriptionElement);
|
||||
}
|
||||
|
||||
if( noOpSet )
|
||||
{
|
||||
Element noOpElement = new Element("sword:noOp", Namespaces.NS_SWORD);
|
||||
noOpElement.appendChild(Boolean.toString(noOp));
|
||||
entry.appendChild(noOpElement);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the unmarshall method in the parent Entry. This will
|
||||
* call the parent method to parse the general Atom elements and
|
||||
* attributes. This method will then parse the remaining sword
|
||||
* extensions that exist in the element.
|
||||
*
|
||||
* @param entry The entry to parse.
|
||||
*
|
||||
* @throws UnmarshallException If the entry is not an atom:entry
|
||||
* or if there is an exception extracting the data.
|
||||
*/
|
||||
public void unmarshall(Element entry)
|
||||
throws UnmarshallException
|
||||
{
|
||||
super.unmarshall(entry);
|
||||
|
||||
try
|
||||
{
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = entry.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
|
||||
if( isInstanceOf(element, "treatment", Namespaces.NS_SWORD ))
|
||||
{
|
||||
treatment = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "formatNamespace", Namespaces.NS_SWORD ))
|
||||
{
|
||||
formatNamespace = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "noOp", Namespaces.NS_SWORD ))
|
||||
{
|
||||
setNoOp(unmarshallBoolean(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "verboseDescription", Namespaces.NS_SWORD ))
|
||||
{
|
||||
verboseDescription = unmarshallString(element);
|
||||
}
|
||||
} // for
|
||||
|
||||
}
|
||||
catch (UnmarshallException ex)
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Error parsing SWORDEntry. " + ex.getMessage());
|
||||
throw new UnmarshallException("Error parsing SWORD Entry", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format namespace.
|
||||
*
|
||||
* @return The format namespace.
|
||||
*/
|
||||
public String getFormatNamespace()
|
||||
{
|
||||
return formatNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the format namespace.
|
||||
*
|
||||
* @param formatNamespace The format namespace.
|
||||
*/
|
||||
public void setFormatNamespace(String formatNamespace)
|
||||
{
|
||||
this.formatNamespace = formatNamespace;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Represents a generic SWORD exception. If this thrown by a repository,
|
||||
* it would result in a HTTP 500 message being returned to the user.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class SWORDException extends Exception
|
||||
{
|
||||
private String errorCode;
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified message and source data.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
* @param source The original exception that lead to this exception. This
|
||||
* can be <code>null</code>.
|
||||
*/
|
||||
public SWORDException(String message, Exception source)
|
||||
{
|
||||
super(message, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified message and source data.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
* @param source The original exception that lead to this exception. This
|
||||
* can be <code>null</code>.
|
||||
* @param errorCode The error code to sed back with the request
|
||||
*/
|
||||
public SWORDException(String message, Exception source, String errorCode)
|
||||
{
|
||||
super(message, source);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified message.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
*/
|
||||
public SWORDException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error code
|
||||
*
|
||||
* @return The error code
|
||||
*/
|
||||
public String getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
396
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Service.java
Executable file
396
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Service.java
Executable file
@@ -0,0 +1,396 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:54 $
|
||||
* Revision : $Revision: 1.4 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.purl.sword.base.Namespaces;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
/**
|
||||
* Represents an Atom Publishing Protocol Service element, with
|
||||
* SWORD extensions.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Service extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The local name for the element.
|
||||
*/
|
||||
private static final String ELEMENT_NAME = "service";
|
||||
|
||||
/**
|
||||
* The service compliance level.
|
||||
*/
|
||||
private ServiceLevel complianceLevel;
|
||||
|
||||
/**
|
||||
* The noOp value.
|
||||
*/
|
||||
private boolean noOp;
|
||||
|
||||
/**
|
||||
* Flag to record if the noOp value has been set by a user of the class.
|
||||
*/
|
||||
private boolean isNoOp;
|
||||
|
||||
/**
|
||||
* The verbose value.
|
||||
*/
|
||||
private boolean verbose;
|
||||
|
||||
/**
|
||||
* Flag to record if the verbose value has been set by a user of the class.
|
||||
*/
|
||||
private boolean isVerbose;
|
||||
|
||||
/**
|
||||
* List of Workspaces.
|
||||
*/
|
||||
private List<Workspace> workspaces;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public Service()
|
||||
{
|
||||
super("app");
|
||||
|
||||
isVerbose = false;
|
||||
isNoOp = false;
|
||||
workspaces = new ArrayList<Workspace>();
|
||||
complianceLevel = ServiceLevel.UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param complianceLevel The service compliance level.
|
||||
*/
|
||||
public Service( ServiceLevel complianceLevel)
|
||||
{
|
||||
this();
|
||||
this.complianceLevel = complianceLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance with the specified compliance level, noOp and
|
||||
* verbose values.
|
||||
*
|
||||
* @param complianceLevel The service compliance level.
|
||||
* @param noOp The noOp.
|
||||
* @param verbose The verbose element.
|
||||
*/
|
||||
public Service( ServiceLevel complianceLevel, boolean noOp, boolean verbose )
|
||||
{
|
||||
this();
|
||||
this.complianceLevel = complianceLevel;
|
||||
setNoOp(noOp);
|
||||
setVerbose(verbose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service compliance level.
|
||||
*
|
||||
* @return The compliance level.
|
||||
*/
|
||||
public ServiceLevel getComplianceLevel()
|
||||
{
|
||||
return complianceLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the service compliance level.
|
||||
*
|
||||
* @param The compliance level.
|
||||
*/
|
||||
public void setComplianceLevel(ServiceLevel complianceLevel)
|
||||
{
|
||||
this.complianceLevel = complianceLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NoOp value.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
public boolean isNoOp()
|
||||
{
|
||||
return noOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NoOp value.
|
||||
*
|
||||
* @param noOp The value.
|
||||
*/
|
||||
public void setNoOp(boolean noOp)
|
||||
{
|
||||
this.noOp = noOp;
|
||||
isNoOp = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the NoOp value has been set. This should be called to
|
||||
* check if an item has been programatically set and does not have a
|
||||
* default value.
|
||||
*
|
||||
* @return True if it has been set programmatically. Otherwise, false.
|
||||
*/
|
||||
public boolean isNoOpSet()
|
||||
{
|
||||
return isNoOp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Verbose setting.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
public boolean isVerbose()
|
||||
{
|
||||
return verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Verbose value.
|
||||
*
|
||||
* @param verbose The value.
|
||||
*/
|
||||
public void setVerbose(boolean verbose)
|
||||
{
|
||||
this.verbose = verbose;
|
||||
isVerbose = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the Verbose value has been set. This should be called to
|
||||
* check if an item has been programatically set and does not have a
|
||||
* default value.
|
||||
*
|
||||
* @return True if it has been set programmatically. Otherwise, false.
|
||||
*/
|
||||
public boolean isVerboseSet()
|
||||
{
|
||||
return isVerbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Iterator over the workspaces.
|
||||
*
|
||||
* @return The workspace.
|
||||
*/
|
||||
public Iterator<Workspace> getWorkspaces()
|
||||
{
|
||||
return workspaces.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of workspaces
|
||||
*
|
||||
* @return The workspaces in a List
|
||||
*/
|
||||
public List<Workspace> getWorkspacesList()
|
||||
{
|
||||
return workspaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a workspace.
|
||||
*
|
||||
* @param workspace The workspace.
|
||||
*/
|
||||
public void addWorkspace(Workspace workspace)
|
||||
{
|
||||
this.workspaces.add(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of workspaces.
|
||||
*/
|
||||
public void clearWorkspaces()
|
||||
{
|
||||
this.workspaces.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this object to an Element object.
|
||||
*
|
||||
* @return A XOM Element that holds the data for this Content element.
|
||||
*/
|
||||
public Element marshall( )
|
||||
{
|
||||
Element service = new Element(ELEMENT_NAME, Namespaces.NS_APP);
|
||||
service.addNamespaceDeclaration("atom", Namespaces.NS_ATOM);
|
||||
service.addNamespaceDeclaration("dcterms", Namespaces.NS_DC_TERMS);
|
||||
service.addNamespaceDeclaration("sword", Namespaces.NS_SWORD);
|
||||
|
||||
|
||||
if( complianceLevel != ServiceLevel.UNDEFINED )
|
||||
{
|
||||
//System.out.println("The compliance level is: " + complianceLevel );
|
||||
Element compliance = new Element("sword:level", Namespaces.NS_SWORD);
|
||||
compliance.appendChild(Integer.toString(complianceLevel.number()));
|
||||
service.appendChild(compliance);
|
||||
}
|
||||
|
||||
if( isVerboseSet() )
|
||||
{
|
||||
Element verboseElement = new Element("sword:verbose", Namespaces.NS_SWORD);
|
||||
verboseElement.appendChild(Boolean.toString(verbose));
|
||||
service.appendChild(verboseElement);
|
||||
}
|
||||
|
||||
if( isNoOpSet() )
|
||||
{
|
||||
Element noOpElement = new Element("sword:noOp", Namespaces.NS_SWORD);
|
||||
noOpElement.appendChild(Boolean.toString(noOp));
|
||||
service.appendChild(noOpElement);
|
||||
}
|
||||
|
||||
for( Workspace item : workspaces )
|
||||
{
|
||||
service.appendChild(item.marshall());
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a service level that corresponds to the specified value. Used
|
||||
* during the unmarshall process.
|
||||
*
|
||||
* @param level The integer version of a service level.
|
||||
*
|
||||
* @return If the parameter matches one of the defined levels,
|
||||
* a ServiceLevel of ONE or ZERO is returned. Otherwise,
|
||||
* ServiceLevel.UNDEFINED is returned.
|
||||
*/
|
||||
private ServiceLevel getServiceLevel( int level )
|
||||
{
|
||||
ServiceLevel theLevel = ServiceLevel.UNDEFINED;
|
||||
|
||||
switch( level )
|
||||
{
|
||||
case 0:
|
||||
theLevel = ServiceLevel.ZERO;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
theLevel = ServiceLevel.ONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
// FIXME - should this default to ZERO instead?
|
||||
theLevel = ServiceLevel.UNDEFINED;
|
||||
InfoLogger.getLogger().writeError("Invalid value for sword:level");
|
||||
break;
|
||||
}
|
||||
|
||||
return theLevel;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the content element into the data in this object.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain a
|
||||
* content element or if there are problems
|
||||
* accessing the data.
|
||||
*/
|
||||
public void unmarshall( Element service )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(service, "service", Namespaces.NS_APP))
|
||||
{
|
||||
throw new UnmarshallException( "Not an app:service element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
workspaces.clear();
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = service.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
|
||||
if( isInstanceOf(element, "level", Namespaces.NS_SWORD ) )
|
||||
{
|
||||
int level = unmarshallInteger(element);
|
||||
complianceLevel = getServiceLevel(level);
|
||||
}
|
||||
else if( isInstanceOf(element, "verbose", Namespaces.NS_SWORD))
|
||||
{
|
||||
setVerbose(unmarshallBoolean(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "noOp", Namespaces.NS_SWORD))
|
||||
{
|
||||
setNoOp(unmarshallBoolean(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "workspace", Namespaces.NS_APP ))
|
||||
{
|
||||
Workspace workspace = new Workspace( );
|
||||
workspace.unmarshall(element);
|
||||
workspaces.add(workspace);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Service: " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse element in Service", ex);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,308 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:55 $
|
||||
* Revision : $Revision: 1.2 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import nu.xom.Builder;
|
||||
import nu.xom.Document;
|
||||
import nu.xom.Element;
|
||||
import nu.xom.ParsingException;
|
||||
import nu.xom.Serializer;
|
||||
|
||||
|
||||
/**
|
||||
* A representation of a SWORD Service Document.
|
||||
*
|
||||
* http://www.ukoln.ac.uk/repositories/digirep/index/SWORD_APP_Profile_0.5
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class ServiceDocument
|
||||
{
|
||||
/**
|
||||
* The Service object that is held by this object.
|
||||
*/
|
||||
private Service service;
|
||||
|
||||
/**
|
||||
* Create a new instance and set the initial service level to Zero.
|
||||
*/
|
||||
public ServiceDocument()
|
||||
{
|
||||
this(ServiceLevel.ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and set the specified service level.
|
||||
*
|
||||
* @param complianceLevel The service compliance level.
|
||||
*/
|
||||
public ServiceDocument(ServiceLevel complianceLevel)
|
||||
{
|
||||
service = new Service(complianceLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified Service document.
|
||||
*
|
||||
* @param service The Service object.
|
||||
*/
|
||||
public ServiceDocument(Service service)
|
||||
{
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a ServiceDocument
|
||||
*
|
||||
* @param complianceLevel The compliance level of this implementation
|
||||
* @param noOp Whether or not the NOOP option is available
|
||||
* @param verbose Whether or not the verbose option is available
|
||||
* @param workspaceTitle The name of the workspace title
|
||||
* @param workspaceCollections A Collection of workspaces
|
||||
*
|
||||
* @deprecated Please use the other constructors.
|
||||
*/
|
||||
public ServiceDocument(ServiceLevel complianceLevel,
|
||||
boolean noOp,
|
||||
boolean verbose,
|
||||
String workspaceTitle,
|
||||
Collection workspaceCollections) {
|
||||
|
||||
service = new Service( complianceLevel, noOp, verbose );
|
||||
Workspace workspace = new Workspace( workspaceTitle );
|
||||
workspace.addCollection(workspaceCollections); // FIXME - not quite right?
|
||||
service.addWorkspace(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compliance level from this Service Document
|
||||
*
|
||||
* @return The compliance level
|
||||
*
|
||||
* @deprecated Please access the compliance level directly from the service.
|
||||
*/
|
||||
public ServiceLevel getComplianceLevel() {
|
||||
// Return the compliance level
|
||||
return service.getComplianceLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean depending on whether or not the Service Document
|
||||
* says the server supports the NOOP option
|
||||
*
|
||||
* @return The NOOP option status
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public boolean supportsNoOp() {
|
||||
// Return the NOOP option status
|
||||
return service.isNoOp();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param noOp
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public void setNoOp(boolean noOp)
|
||||
{
|
||||
service.setNoOp(noOp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean depending on whether or not the Service Document
|
||||
* says the server supports the verbose option
|
||||
*
|
||||
* @return The verbose option status
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public boolean supportsVerbose() {
|
||||
// Return the verbose option status
|
||||
return service.isVerbose();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param verbose
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public void setVerbose(boolean verbose)
|
||||
{
|
||||
service.setVerbose(verbose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Collectinos in the workspace described by the Service Document
|
||||
*
|
||||
* @return The workspaces
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public Iterator<Collection> getWorkspaceCollections() {
|
||||
// Return the collections
|
||||
return null; // FIXME service.getWorkspaces().collectionIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public Iterator<Workspace> getWorkspaces()
|
||||
{
|
||||
return service.getWorkspaces();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param workspace
|
||||
*
|
||||
* @deprecated Please access the value directly from the service.
|
||||
*/
|
||||
public void addWorkspace(Workspace workspace)
|
||||
{
|
||||
service.addWorkspace(workspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the service object associated with this document.
|
||||
*
|
||||
* @param service The new Service object.
|
||||
*/
|
||||
public void setService(Service service)
|
||||
{
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Service object associated with this document.
|
||||
*
|
||||
* @return The Service object.
|
||||
*/
|
||||
public Service getService()
|
||||
{
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Service Document in it's XML form.
|
||||
*
|
||||
* @return The ServiceDocument
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return marshall();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in the Service element and generate a String representation.
|
||||
* The returned string is UTF-8 format.
|
||||
*
|
||||
* @return A string of XML, or <code>null</code> if there was an error
|
||||
* marshalling the data.
|
||||
*/
|
||||
public String marshall( )
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
Serializer serializer = new Serializer(stream, "UTF-8");
|
||||
serializer.setIndent(3);
|
||||
serializer.setMaxLength(64);
|
||||
|
||||
Document doc = new Document(service.marshall());
|
||||
serializer.write(doc);
|
||||
|
||||
return stream.toString();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
System.err.println(ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the specified XML string into a set of objects
|
||||
* used within the service. A new Service object will be
|
||||
* created and stored. This will dispose of any previous
|
||||
* Service object associated with this object.
|
||||
*
|
||||
* @param xml The XML string.
|
||||
* @throws UnmarshallException If there was a problem unmarshalling the
|
||||
* data. This might be as a result of an
|
||||
* error in parsing the XML string,
|
||||
* extracting information.
|
||||
*/
|
||||
public void unmarshall( String xml )
|
||||
throws UnmarshallException
|
||||
{
|
||||
//
|
||||
try
|
||||
{
|
||||
Builder builder = new Builder();
|
||||
Document doc = builder.build(xml, "http://something.com/here");
|
||||
Element root = doc.getRootElement();
|
||||
|
||||
service = new Service( );
|
||||
service.unmarshall(root);
|
||||
|
||||
}
|
||||
catch( ParsingException ex )
|
||||
{
|
||||
throw new UnmarshallException("Unable to parse the XML", ex );
|
||||
}
|
||||
catch( IOException ex )
|
||||
{
|
||||
throw new UnmarshallException("Error acessing the file?", ex);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Represents a ServiceDocumentRequest.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*
|
||||
*/
|
||||
public class ServiceDocumentRequest
|
||||
{
|
||||
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String onBehalfOf;
|
||||
|
||||
private String IPAddress;
|
||||
|
||||
/**
|
||||
* @return the authenticatedUserName
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param authenticatedUserName the authenticatedUserName to set
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the authenticatedUserPassword
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param password the password to set
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the onBehalfOf
|
||||
*/
|
||||
public String getOnBehalfOf() {
|
||||
return onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param onBehalfOf the onBehalfOf to set
|
||||
*/
|
||||
public void setOnBehalfOf(String onBehalfOf) {
|
||||
this.onBehalfOf = onBehalfOf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IP address of the user
|
||||
*
|
||||
* @return the the IP address
|
||||
*/
|
||||
public String getIPAddress() {
|
||||
return IPAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IP address of the user
|
||||
*
|
||||
* @param String the IP address
|
||||
*/
|
||||
public void setIPAddress(String IPAddress) {
|
||||
this.IPAddress = IPAddress;
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:53 $
|
||||
* Revision : $Revision: 1.2 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the SWORD Service Level.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public enum ServiceLevel
|
||||
{
|
||||
ZERO (0),
|
||||
ONE (1),
|
||||
UNDEFINED (-1);
|
||||
|
||||
/**
|
||||
* Holds the number associated with the ServiceLevel object.
|
||||
*/
|
||||
private final int number;
|
||||
|
||||
/**
|
||||
* Create a new ServiceLevel with the specified number.
|
||||
*
|
||||
* @param num The number to be associated with the service level.
|
||||
*/
|
||||
private ServiceLevel(int num)
|
||||
{
|
||||
this.number = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number for the ServiceLevel object.
|
||||
*
|
||||
* @return The number.
|
||||
*/
|
||||
public int number() { return this.number; }
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:53 $
|
||||
* Revision : $Revision: 1.2 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import nu.xom.Element;
|
||||
|
||||
/**
|
||||
* Common methods that should be supported by all classes that
|
||||
* represent data in the SWORD api.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public interface SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* Marshall the data in the object to the XOM Element.
|
||||
*
|
||||
* @return The Element.
|
||||
*/
|
||||
public Element marshall( );
|
||||
|
||||
/**
|
||||
* Unmarshall the data in the specified element and store it
|
||||
* in the object.
|
||||
*
|
||||
* @param element The data to unmarshall.
|
||||
* @throws UnmarshallException If the element is not of the
|
||||
* correct type, or if there is an error unmarshalling the data.
|
||||
*/
|
||||
public void unmarshall( Element element )
|
||||
throws UnmarshallException;
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:56 $
|
||||
* Revision : $Revision: 1.2 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents information about an exception that is generated during
|
||||
* the Unmarshall process.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class UnmarshallException extends Exception
|
||||
{
|
||||
/**
|
||||
* Create a new instance and store the specified message and source data.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
* @param source The original exception that lead to this exception. This
|
||||
* can be <code>null</code>.
|
||||
*/
|
||||
public UnmarshallException(String message, Exception source)
|
||||
{
|
||||
super(message, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and store the specified message.
|
||||
*
|
||||
* @param message The message for the exception.
|
||||
*/
|
||||
public UnmarshallException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
230
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Workspace.java
Executable file
230
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/Workspace.java
Executable file
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:53 $
|
||||
* Revision : $Revision: 1.4 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.w3.atom.ContentType;
|
||||
import org.w3.atom.Title;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
/**
|
||||
* Represents an Atom Publishing Protocol Workspace element.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Workspace extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The element name that is used in the textual representatin of the XML data.
|
||||
*/
|
||||
public static final String ELEMENT_NAME = "workspace";
|
||||
|
||||
/**
|
||||
* The title for the workspace.
|
||||
*/
|
||||
private Title title;
|
||||
|
||||
/**
|
||||
* A list of collections associated with this workspace.
|
||||
*/
|
||||
private List<Collection> collections;
|
||||
|
||||
/**
|
||||
* Create a new instance of the workspace, with no title.
|
||||
*/
|
||||
public Workspace( )
|
||||
{
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the workspace with the specified title.
|
||||
*
|
||||
* @param title The title.
|
||||
*/
|
||||
public Workspace( String title )
|
||||
{
|
||||
super("app", ELEMENT_NAME);
|
||||
setTitle(title);
|
||||
collections = new ArrayList<Collection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title. The type for the title will be set to
|
||||
* <code>ContentType.TEXT</code>
|
||||
*
|
||||
* @param title The title.
|
||||
*/
|
||||
public void setTitle( String title )
|
||||
{
|
||||
if( this.title == null)
|
||||
{
|
||||
this.title = new Title();
|
||||
}
|
||||
this.title.setContent(title);
|
||||
this.title.setType(ContentType.TEXT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the Title element.
|
||||
*
|
||||
* @return The title.
|
||||
*/
|
||||
public String getTitle( )
|
||||
{
|
||||
if( title == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return title.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collection to the Workspace.
|
||||
*
|
||||
* @param collection The collection.
|
||||
*/
|
||||
public void addCollection( Collection collection )
|
||||
{
|
||||
collections.add(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Iterator over the collections.
|
||||
*
|
||||
* @return An iterator.
|
||||
*/
|
||||
public Iterator<Collection> collectionIterator( )
|
||||
{
|
||||
return collections.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the collections
|
||||
*
|
||||
* @ return A list.
|
||||
*/
|
||||
public List<Collection> getCollections( )
|
||||
{
|
||||
return collections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this element to an Element.
|
||||
*
|
||||
* @return An element that contains the data in this object.
|
||||
*/
|
||||
public Element marshall( )
|
||||
{
|
||||
// convert data into XOM elements and return the 'root', i.e. the one
|
||||
// that represents the collection.
|
||||
Element workspace = new Element(ELEMENT_NAME, Namespaces.NS_APP);
|
||||
|
||||
workspace.appendChild(title.marshall());
|
||||
|
||||
for( Collection item : collections )
|
||||
{
|
||||
workspace.appendChild(item.marshall());
|
||||
}
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the workspace element into the data in this object.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain a
|
||||
* workspace element or if there are problems
|
||||
* accessing the data.
|
||||
*/
|
||||
public void unmarshall( Element workspace )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(workspace, ELEMENT_NAME, Namespaces.NS_APP))
|
||||
{
|
||||
throw new UnmarshallException( "Not an app:workspace element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
collections.clear();
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = workspace.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
// FIXME - atom assumes that it has been defined. WHAT DID I MEAN???
|
||||
if( isInstanceOf(element, "title", Namespaces.NS_ATOM ) )
|
||||
{
|
||||
title = new Title();
|
||||
title.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "collection", Namespaces.NS_APP ))
|
||||
{
|
||||
Collection collection = new Collection( );
|
||||
collection.unmarshall(element);
|
||||
collections.add(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in workspace: " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse element in workspace.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
309
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/XmlElement.java
Executable file
309
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/base/XmlElement.java
Executable file
@@ -0,0 +1,309 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.base;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:55 $
|
||||
* Revision : $Revision: 1.3 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Node;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* Parent class for all classes that represent an XML element. This provides
|
||||
* some common utility methods that are useful for marshalling and
|
||||
* unmarshalling data.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class XmlElement
|
||||
{
|
||||
/**
|
||||
* The name to use for the prefix.
|
||||
*/
|
||||
protected String prefix;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected String localName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param localName
|
||||
*/
|
||||
public XmlElement(String localName)
|
||||
{
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*/
|
||||
public XmlElement(String prefix, String localName)
|
||||
{
|
||||
this.prefix = prefix;
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Date format that is used to parse dates to and from the ISO format
|
||||
* in the XML data.
|
||||
*/
|
||||
protected static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
|
||||
/**
|
||||
* Extract a boolean value from the specified element. The boolean value
|
||||
* is represented as the string 'true' or 'false' as the only child
|
||||
* of the specified element.
|
||||
*
|
||||
* @param element The element that contains the boolean value.
|
||||
* @return True or false, based on the string in the element's content.
|
||||
* @throws UnmarshallException If the element does not contain a single child, or if
|
||||
* the child does not contain the value 'true' or 'false'.
|
||||
*/
|
||||
protected boolean unmarshallBoolean( Element element )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( element.getChildCount() != 1 )
|
||||
{
|
||||
throw new UnmarshallException("Missing Boolean Value", null);
|
||||
}
|
||||
|
||||
// ok to get the single child element. This should be a text element.
|
||||
try
|
||||
{
|
||||
Node child = element.getChild(0);
|
||||
String value = child.getValue();
|
||||
if( "true".equals(value) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( "false".equals(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnmarshallException("Illegal Value");
|
||||
}
|
||||
}
|
||||
catch( IndexOutOfBoundsException ex )
|
||||
{
|
||||
throw new UnmarshallException("Error accessing Boolean element", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a string value from the specified element. The value
|
||||
* is the only child of the specified element.
|
||||
*
|
||||
* @param element The element that contains the string value.
|
||||
* @return The string.
|
||||
* @throws UnmarshallException If the element does not contain a single child.
|
||||
*/
|
||||
protected String unmarshallString( Element element )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( element.getChildCount() != 1 )
|
||||
{
|
||||
throw new UnmarshallException("Missing String Value", null);
|
||||
}
|
||||
|
||||
// ok to get the single child element. This should be a text element.
|
||||
try
|
||||
{
|
||||
Node child = element.getChild(0);
|
||||
return child.getValue();
|
||||
}
|
||||
catch( IndexOutOfBoundsException ex )
|
||||
{
|
||||
throw new UnmarshallException("Error accessing Boolean element", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract an integer value from the specified element. The integer value
|
||||
* is represented as a string in the only child
|
||||
* of the specified element.
|
||||
*
|
||||
* @param element The element that contains the integer.
|
||||
* @return The integer.
|
||||
* @throws UnmarshallException If the element does not contain a single child, or if
|
||||
* the child does not contain the valid integer.
|
||||
*/
|
||||
protected int unmarshallInteger( Element element )
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( element.getChildCount() != 1 )
|
||||
{
|
||||
throw new UnmarshallException("Missing Integer Value", null);
|
||||
}
|
||||
|
||||
// ok to get the single child element. This should be a text element.
|
||||
try
|
||||
{
|
||||
Node child = element.getChild(0);
|
||||
return Integer.parseInt( child.getValue() );
|
||||
}
|
||||
catch( IndexOutOfBoundsException ex )
|
||||
{
|
||||
throw new UnmarshallException("Error accessing Boolean element", ex);
|
||||
}
|
||||
catch( NumberFormatException nfex )
|
||||
{
|
||||
throw new UnmarshallException("Error fomratting the number", nfex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract an date value from the specified element. The date value
|
||||
* is represented as a string in the only child of the element.
|
||||
*
|
||||
* @param element The element that contains the date.
|
||||
* @return The date.
|
||||
* @throws UnmarshallException If the element does not contain a single child, or if
|
||||
* the child does not contain the valid date.
|
||||
*/
|
||||
protected Date unmarshallDate(Element element)
|
||||
throws UnmarshallException
|
||||
{
|
||||
try
|
||||
{
|
||||
String content = unmarshallString(element);
|
||||
return stringToDate(content);
|
||||
}
|
||||
catch( UnmarshallException ue )
|
||||
{
|
||||
throw new UnmarshallException("Error accessing the date.", ue);
|
||||
}
|
||||
catch (ParseException pe)
|
||||
{
|
||||
throw new UnmarshallException("Error accessing the date.", pe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the date to a string. If the date is null,
|
||||
* the result will result to a default date of 1st January 1970.
|
||||
* FIXME - is this sensible?
|
||||
*
|
||||
* @param date The Date object.
|
||||
* @return The Date, expressed as a string in the format
|
||||
* yyyy-MM-ddTHH:mm:ssZ.
|
||||
*/
|
||||
protected String dateToString(Date date)
|
||||
{
|
||||
if( date == null )
|
||||
{
|
||||
GregorianCalendar cal = new GregorianCalendar(1970, 0, 1, 0, 0, 0);
|
||||
date = cal.getTime();
|
||||
}
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the string into a Date object.
|
||||
*
|
||||
* @param date The date, represented as a string.
|
||||
* @return A Date.
|
||||
* @throws ParseException If the string does not match the format
|
||||
* of yyyy-MM-ddTHH:mm:ssZ.
|
||||
*/
|
||||
protected Date stringToDate(String date)
|
||||
throws ParseException
|
||||
{
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
|
||||
return formatter.parse(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the specified element is an instance of the element name. If
|
||||
* you are checking the name title in the ATOM namespace, then the local name
|
||||
* should be 'title' and the namespaceURI is the URI for the ATOM namespace.
|
||||
*
|
||||
* @param element The specified element.
|
||||
* @param localName The local name for the element.
|
||||
* @param namespaceURI The namespace for the element.
|
||||
* @return True if the element matches the localname and namespace. Otherwise, false.
|
||||
*/
|
||||
protected boolean isInstanceOf(Element element, String localName, String namespaceURI )
|
||||
{
|
||||
return (localName.equals(element.getLocalName()) &&
|
||||
namespaceURI.equals(element.getNamespaceURI()) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the qualified name for this object. This uses the
|
||||
* prefix and local name stored in this object.
|
||||
*
|
||||
* @return A string of the format 'prefix:localName'
|
||||
*/
|
||||
public String getQualifiedName()
|
||||
{
|
||||
return getQualifiedName(localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the qualified name. The prefix for this object is prepended
|
||||
* onto the specified local name.
|
||||
*
|
||||
* @param name the specified local name.
|
||||
* @return A string of the format 'prefix:name'
|
||||
*/
|
||||
public String getQualifiedName(String name)
|
||||
{
|
||||
String p = prefix;
|
||||
if( p != null )
|
||||
{
|
||||
p += ":";
|
||||
}
|
||||
return p + name;
|
||||
}
|
||||
}
|
@@ -0,0 +1,283 @@
|
||||
package org.purl.sword.server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.purl.sword.base.ChecksumUtils;
|
||||
import org.purl.sword.base.Deposit;
|
||||
import org.purl.sword.base.DepositResponse;
|
||||
import org.purl.sword.base.HttpHeaders;
|
||||
import org.purl.sword.base.SWORDAuthenticationException;
|
||||
import org.purl.sword.base.SWORDContentTypeException;
|
||||
import org.purl.sword.base.SWORDException;
|
||||
|
||||
public class DepositServlet extends HttpServlet {
|
||||
|
||||
private SWORDServer myRepository;
|
||||
|
||||
private String authN;
|
||||
|
||||
private String tempDirectory;
|
||||
|
||||
private static int counter = 0;
|
||||
|
||||
private static Logger log = Logger.getLogger(DepositServlet.class);
|
||||
|
||||
public void init() {
|
||||
// Instantiate the correct SWORD Server class
|
||||
String className = getServletContext().getInitParameter("server-class");
|
||||
if (className == null) {
|
||||
log.fatal("Unable to read value of 'sword-server-class' from Servlet context");
|
||||
} else {
|
||||
try {
|
||||
myRepository = (SWORDServer)Class.forName(className).newInstance();
|
||||
log.info("Using " + className + " as the SWORDServer");
|
||||
} catch (Exception e) {
|
||||
log.fatal("Unable to instantiate class from 'sword-server-class': " + className);
|
||||
}
|
||||
}
|
||||
|
||||
authN = getServletContext().getInitParameter("authentication-method");
|
||||
if ((authN == null) || (authN.equals(""))) {
|
||||
authN = "None";
|
||||
}
|
||||
log.info("Authentication type set to: " + authN);
|
||||
|
||||
tempDirectory = getServletContext().getInitParameter("upload-temp-directory");
|
||||
if ((tempDirectory == null) || (tempDirectory.equals(""))) {
|
||||
tempDirectory = System.getProperty("java.io.tmpdir");
|
||||
}
|
||||
File tempDir = new File(tempDirectory);
|
||||
log.info("Upload temporary directory set to: " + tempDir);
|
||||
if (!tempDir.isDirectory()) {
|
||||
log.fatal("Upload temporary directory is not a directory: " + tempDir);
|
||||
}
|
||||
if (!tempDir.canWrite()) {
|
||||
log.fatal("Upload temporary directory cannot be written to: " + tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doGet(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Send a '501 Not Implemented'
|
||||
response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
protected void doPost(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Create the Deposit request
|
||||
Deposit d = new Deposit();
|
||||
Date date = new Date();
|
||||
log.debug("Starting deposit processing at " + date.toString() + " by " + request.getRemoteAddr());
|
||||
|
||||
// Are there any authentication details?
|
||||
String usernamePassword = getUsernamePassword(request);
|
||||
if ((usernamePassword != null) && (!usernamePassword.equals(""))) {
|
||||
int p = usernamePassword.indexOf(":");
|
||||
if (p != -1) {
|
||||
d.setUsername(usernamePassword.substring(0, p));
|
||||
d.setPassword(usernamePassword.substring(p+1));
|
||||
}
|
||||
} else if (authenticateWithBasic()) {
|
||||
String s = "Basic realm=\"SWORD\"";
|
||||
response.setHeader("WWW-Authenticate", s);
|
||||
response.setStatus(401);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do the processing
|
||||
try {
|
||||
// Write the file to the temp directory
|
||||
// TODO: Improve the filename creation
|
||||
String filename = tempDirectory + "SWORD-" +
|
||||
request.getRemoteAddr() + "-" + counter++;
|
||||
InputStream inputStream = request.getInputStream();
|
||||
OutputStream outputStream = new FileOutputStream(filename);
|
||||
int data;
|
||||
while((data = inputStream.read()) != -1)
|
||||
{
|
||||
outputStream.write(data);
|
||||
}
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
|
||||
// Check the MD5 hash
|
||||
String receivedMD5 = ChecksumUtils.generateMD5(filename);
|
||||
log.debug("Received filechecksum: " + receivedMD5);
|
||||
d.setMd5(receivedMD5);
|
||||
String md5 = request.getHeader("Content-MD5");
|
||||
log.debug("Received file checksum header: " + md5);
|
||||
if ((md5 != null) && (!md5.equals(receivedMD5))) {
|
||||
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
|
||||
response.setHeader(HttpHeaders.X_ERROR_CODE, "ErrorChecksumMismatch");
|
||||
log.debug("Bad MD5 for file. Aborting with appropriate error message");
|
||||
} else {
|
||||
// Set the file
|
||||
File f = new File(filename);
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
d.setFile(fis);
|
||||
|
||||
// Set the X-On-Behalf-Of header
|
||||
d.setOnBehalfOf(request.getHeader(HttpHeaders.X_ON_BEHALF_OF.toString()));
|
||||
|
||||
// Set the X-Format-Namespace header
|
||||
d.setFormatNamespace(request.getHeader(HttpHeaders.X_FORMAT_NAMESPACE));
|
||||
|
||||
// Set the X-No-Op header
|
||||
String noop = request.getHeader(HttpHeaders.X_NO_OP);
|
||||
if ((noop != null) && (noop.equals("true"))) {
|
||||
d.setNoOp(true);
|
||||
} else {
|
||||
d.setNoOp(false);
|
||||
}
|
||||
|
||||
// Set the X-Verbose header
|
||||
String verbose = request.getHeader(HttpHeaders.X_VERBOSE);
|
||||
if ((verbose != null) && (verbose.equals("true"))) {
|
||||
d.setVerbose(true);
|
||||
} else {
|
||||
d.setVerbose(false);
|
||||
}
|
||||
|
||||
// Set the slug
|
||||
String slug = request.getHeader(HttpHeaders.SLUG);
|
||||
if (slug != null) {
|
||||
d.setSlug(slug);
|
||||
}
|
||||
|
||||
// Set the content disposition
|
||||
d.setFilename(request.getHeader(HttpHeaders.CONTENT_DISPOSITION));
|
||||
|
||||
// Set the IP address
|
||||
d.setIPAddress(request.getRemoteAddr());
|
||||
|
||||
// Set the deposit location
|
||||
d.setLocation(getUrl(request));
|
||||
|
||||
// Set the content type
|
||||
d.setContentType(request.getContentType());
|
||||
|
||||
// Set the content length
|
||||
String cl = request.getHeader(HttpHeaders.CONTENT_LENGTH);
|
||||
if ((cl != null) && (!cl.equals(""))) {
|
||||
d.setContentLength(Integer.parseInt(cl));
|
||||
}
|
||||
|
||||
// Get the DepositResponse
|
||||
DepositResponse dr = myRepository.doDeposit(d);
|
||||
|
||||
// Print out the Deposit Response
|
||||
response.setStatus(dr.getHttpResponse());
|
||||
// response.setContentType("application/atomserv+xml");
|
||||
response.setContentType("application/xml");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.write(dr.marshall());
|
||||
out.flush();
|
||||
|
||||
// Close the input stream if it still open
|
||||
fis.close();
|
||||
|
||||
// Try deleting the temp file
|
||||
f = new File(filename);
|
||||
f.delete();
|
||||
}
|
||||
} catch (SWORDAuthenticationException sae) {
|
||||
// Ask for credentials
|
||||
if (authN.equals("Basic")) {
|
||||
String s = "Basic realm=\"SWORD\"";
|
||||
response.setHeader("WWW-Authenticate", s);
|
||||
response.setStatus(401);
|
||||
}
|
||||
} catch (SWORDContentTypeException scte) {
|
||||
// Throw a 415
|
||||
response.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
|
||||
} catch (SWORDException se) {
|
||||
// Throw a HTTP 500
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
|
||||
// Is there an appropriate error header to return?
|
||||
if (se.getErrorCode() != null) {
|
||||
response.setHeader(HttpHeaders.X_ERROR_CODE, se.getErrorCode());
|
||||
}
|
||||
System.out.println(se.toString());
|
||||
log.error(se.toString());
|
||||
} catch (IOException ioe) {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
log.error(ioe.toString());
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
log.error(nsae.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utiliy method to return the username and password (separated by a colon ':')
|
||||
*
|
||||
* @param request
|
||||
* @return The username and password combination
|
||||
*/
|
||||
private String getUsernamePassword(HttpServletRequest request) {
|
||||
try {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null) {
|
||||
StringTokenizer st = new StringTokenizer(authHeader);
|
||||
if (st.hasMoreTokens()) {
|
||||
String basic = st.nextToken();
|
||||
if (basic.equalsIgnoreCase("Basic")) {
|
||||
String credentials = st.nextToken();
|
||||
String userPass = new String(Base64.decodeBase64(credentials.getBytes()));
|
||||
return userPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to deicde if we are using HTTP Basic authentication
|
||||
*
|
||||
* @return if HTTP Basic authentication is in use or not
|
||||
*/
|
||||
private boolean authenticateWithBasic() {
|
||||
if (authN.equalsIgnoreCase("Basic")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to construct the URL called for this Servlet
|
||||
*
|
||||
* @param req The request object
|
||||
* @return The URL
|
||||
*/
|
||||
private static String getUrl(HttpServletRequest req) {
|
||||
String reqUrl = req.getRequestURL().toString();
|
||||
String queryString = req.getQueryString(); // d=789
|
||||
if (queryString != null) {
|
||||
reqUrl += "?"+queryString;
|
||||
}
|
||||
return reqUrl;
|
||||
}
|
||||
}
|
@@ -0,0 +1,236 @@
|
||||
package org.purl.sword.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
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.SWORDException;
|
||||
import org.purl.sword.base.Service;
|
||||
import org.purl.sword.base.ServiceDocument;
|
||||
import org.purl.sword.base.ServiceDocumentRequest;
|
||||
import org.purl.sword.base.ServiceLevel;
|
||||
import org.purl.sword.base.Workspace;
|
||||
import org.w3.atom.Author;
|
||||
import org.w3.atom.Content;
|
||||
import org.w3.atom.Contributor;
|
||||
import org.w3.atom.Generator;
|
||||
import org.w3.atom.InvalidMediaTypeException;
|
||||
import org.w3.atom.Link;
|
||||
import org.w3.atom.Source;
|
||||
import org.w3.atom.Summary;
|
||||
import org.w3.atom.Title;
|
||||
|
||||
/**
|
||||
* 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 deposito can increment */
|
||||
private static int counter = 0;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public ServiceDocument doServiceDocument(ServiceDocumentRequest sdr) throws SWORDAuthenticationException {
|
||||
// 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");
|
||||
}
|
||||
|
||||
// Create and return a dummy ServiceDocument
|
||||
ServiceDocument document = new ServiceDocument();
|
||||
Service service = new Service(ServiceLevel.ZERO, true, true);
|
||||
document.setService(service);
|
||||
|
||||
Workspace workspace = new Workspace();
|
||||
workspace.setTitle("Anonymous submitters workspace");
|
||||
Collection collection = new Collection();
|
||||
collection.setTitle("Anonymous submitters collection");
|
||||
collection.setLocation("http://sword.aber.ac.uk/sword/deposit?user=anon");
|
||||
workspace.addCollection(collection);
|
||||
collection = new Collection();
|
||||
collection.setTitle("Anonymous submitters other collection");
|
||||
collection.setLocation("http://sword.aber.ac.uk/sword/deposit?user=anonymous");
|
||||
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("http://sword.aber.ac.uk/sword/deposit?user=" + username);
|
||||
workspace.addCollection(collection);
|
||||
collection = new Collection();
|
||||
collection.setTitle("Second authenticated collection for " + username);
|
||||
collection.setLocation("http://sword.aber.ac.uk/sword/deposit?user=" + username + "-2");
|
||||
workspace.addCollection(collection);
|
||||
service.addWorkspace(workspace);
|
||||
}
|
||||
|
||||
String onBehalfOf = sdr.getOnBehalfOf();
|
||||
if ((onBehalfOf != null) && (!onBehalfOf.equals(""))) {
|
||||
workspace = new Workspace();
|
||||
workspace.setTitle("Personal workspace for " + onBehalfOf);
|
||||
collection = new Collection();
|
||||
collection.setTitle("Personal collection for " + onBehalfOf);
|
||||
collection.setLocation("http://sword.aber.ac.uk/sword/deposit?user=" + onBehalfOf);
|
||||
collection.addAccepts("application/zip");
|
||||
collection.addAccepts("application/xml");
|
||||
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, 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");
|
||||
}
|
||||
|
||||
// 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.ACCEPTED);
|
||||
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());
|
||||
try {
|
||||
se.setUpdated(milliFormat);
|
||||
} catch (ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Source source = new Source();
|
||||
Generator generator = new Generator();
|
||||
generator.setContent("org.purl.sword.server.DummyServer");
|
||||
source.setGenerator(generator);
|
||||
se.setSource(source);
|
||||
|
||||
Content content = new Content();
|
||||
try {
|
||||
content.setType("application/zip");
|
||||
} catch (InvalidMediaTypeException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.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());
|
||||
|
||||
se.setFormatNamespace("http://www.standards-body.com/standardXYZ/v1/");
|
||||
|
||||
dr.setEntry(se);
|
||||
|
||||
return dr;
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package org.purl.sword.server;
|
||||
|
||||
import org.purl.sword.base.Deposit;
|
||||
import org.purl.sword.base.DepositResponse;
|
||||
import org.purl.sword.base.SWORDAuthenticationException;
|
||||
import org.purl.sword.base.SWORDContentTypeException;
|
||||
import org.purl.sword.base.SWORDException;
|
||||
import org.purl.sword.base.ServiceDocument;
|
||||
import org.purl.sword.base.ServiceDocumentRequest;
|
||||
|
||||
/**
|
||||
* An abstract interface to be implemnted by repositories wishing to provide
|
||||
* a SWORD compliant service.
|
||||
*
|
||||
* http://www.ukoln.ac.uk/repositories/digirep/index/SWORD_APP_Profile_0.5
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public interface SWORDServer {
|
||||
|
||||
/**
|
||||
* Answer a Service Document request sent on behalf of a user
|
||||
*
|
||||
* @param sdr The Service Document Request object
|
||||
*
|
||||
* @exception SWORDAuthenticationException Thrown if the authentication fails
|
||||
* @exception SWORDException Thrown in an un-handalable Exception occurs.
|
||||
* This will be dealt with by sending a HTTP 500 Server Exception
|
||||
*
|
||||
* @return The ServiceDocument representing the service document
|
||||
*/
|
||||
public ServiceDocument doServiceDocument(ServiceDocumentRequest sdr)
|
||||
throws SWORDAuthenticationException, SWORDException;
|
||||
|
||||
/**
|
||||
* Answer a SWORD deposit
|
||||
*
|
||||
* @param deposit The Deposit object
|
||||
*
|
||||
* @exception SWORDAuthenticationException Thrown if the authentication fails
|
||||
* @exception SWORDException Thrown in an un-handalable Exception occurs.
|
||||
* This will be dealt with by sending a HTTP 500 Server Exception
|
||||
*
|
||||
* @return The response to the deposit
|
||||
*/
|
||||
public DepositResponse doDeposit(Deposit deposit)
|
||||
throws SWORDAuthenticationException, SWORDContentTypeException, SWORDException;
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
package org.purl.sword.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.purl.sword.base.HttpHeaders;
|
||||
import org.purl.sword.base.SWORDAuthenticationException;
|
||||
import org.purl.sword.base.SWORDException;
|
||||
import org.purl.sword.server.SWORDServer;
|
||||
import org.purl.sword.base.ServiceDocument;
|
||||
import org.purl.sword.base.ServiceDocumentRequest;
|
||||
|
||||
public class ServiceDocumentServlet extends HttpServlet {
|
||||
|
||||
private SWORDServer myRepository;
|
||||
|
||||
private String authN;
|
||||
|
||||
private static Logger log = Logger.getLogger(ServiceDocumentServlet.class);
|
||||
|
||||
public void init() {
|
||||
// Instantiate the correct SWORD Server class
|
||||
String className = getServletContext().getInitParameter("server-class");
|
||||
if (className == null) {
|
||||
log.fatal("Unable to read value of 'sword-server-class' from Servlet context");
|
||||
} else {
|
||||
try {
|
||||
myRepository = (SWORDServer)Class.forName(className).newInstance();
|
||||
log.info("Using " + className + " as the SWORDServer");
|
||||
} catch (Exception e) {
|
||||
log.fatal("Unable to instantiate class from 'sword-server-class': " + className);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the authentication method
|
||||
authN = getServletContext().getInitParameter("authentication-method");
|
||||
if ((authN == null) || (authN == "")) {
|
||||
authN = "None";
|
||||
}
|
||||
log.info("Authentication type set to: " + authN);
|
||||
}
|
||||
|
||||
protected void doGet(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Create the ServiceDocumentRequest
|
||||
ServiceDocumentRequest sdr = new ServiceDocumentRequest();
|
||||
|
||||
// Are there any authentication details?
|
||||
String usernamePassword = getUsernamePassword(request);
|
||||
if ((usernamePassword != null) && (!usernamePassword.equals(""))) {
|
||||
int p = usernamePassword.indexOf(":");
|
||||
if (p != -1) {
|
||||
sdr.setUsername(usernamePassword.substring(0, p));
|
||||
sdr.setPassword(usernamePassword.substring(p+1));
|
||||
}
|
||||
} else if (authenticateWithBasic()) {
|
||||
String s = "Basic realm=\"SWORD\"";
|
||||
response.setHeader("WWW-Authenticate", s);
|
||||
response.setStatus(401);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the x-on-behalf-of header
|
||||
sdr.setOnBehalfOf(request.getHeader(HttpHeaders.X_ON_BEHALF_OF.toString()));
|
||||
|
||||
// Set the IP address
|
||||
sdr.setIPAddress(request.getRemoteAddr());
|
||||
|
||||
// Get the ServiceDocument
|
||||
try {
|
||||
ServiceDocument sd = myRepository.doServiceDocument(sdr);
|
||||
|
||||
// Print out the Service Document
|
||||
// response.setContentType("application/atomserv+xml");
|
||||
response.setContentType("application/xml");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.write(sd.marshall());
|
||||
out.flush();
|
||||
} catch (SWORDAuthenticationException sae) {
|
||||
if (authN.equals("Basic")) {
|
||||
String s = "Basic realm=\"SWORD\"";
|
||||
response.setHeader("WWW-Authenticate", s);
|
||||
response.setStatus(401);
|
||||
}
|
||||
} catch (SWORDException se) {
|
||||
// Throw a HTTP 500
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doPost(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Send a '501 Not Implemented'
|
||||
response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utiliy method to return the username and password (separated by a colon ':')
|
||||
*
|
||||
* @param request
|
||||
* @return The username and password combination
|
||||
*/
|
||||
private String getUsernamePassword(HttpServletRequest request) {
|
||||
try {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null) {
|
||||
StringTokenizer st = new StringTokenizer(authHeader);
|
||||
if (st.hasMoreTokens()) {
|
||||
String basic = st.nextToken();
|
||||
if (basic.equalsIgnoreCase("Basic")) {
|
||||
String credentials = st.nextToken();
|
||||
String userPass = new String(Base64.decodeBase64(credentials.getBytes()));
|
||||
return userPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug(e.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to deicde if we are using HTTP Basic authentication
|
||||
*
|
||||
* @return if HTTP Basic authentication is in use or not
|
||||
*/
|
||||
private boolean authenticateWithBasic() {
|
||||
if (authN.equalsIgnoreCase("Basic")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package org.purl.sword.test;
|
||||
|
||||
import org.purl.sword.server.SWORDServer;
|
||||
import org.purl.sword.server.DummyServer;
|
||||
|
||||
public class DummyServerTest {
|
||||
|
||||
/**
|
||||
* A main method to test the dummy SWORD server.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
//Instantiate the dummy server
|
||||
SWORDServer ss = new DummyServer();
|
||||
|
||||
// Test the normal service document
|
||||
System.out.println("Testing doServiceDocument():");
|
||||
System.out.println("============================");
|
||||
//System.out.println(ss.doServiceDocument(null));
|
||||
|
||||
// Test the normal service document authenticated as 'sdl'
|
||||
System.out.println("Testing doServiceDocument(sdl):");
|
||||
System.out.println("============================");
|
||||
//System.out.println(ss.doServiceDocument("sdl"));
|
||||
|
||||
// Test the 'on behalf of' service document
|
||||
System.out.println("Testing doServiceDocument(onBehalfOf):");
|
||||
System.out.println("======================================");
|
||||
//System.out.println(ss.doServiceDocument(null, "Stuart Lewis"));
|
||||
|
||||
// Test the 'on behalf of' service document authenticated as 'sdl'
|
||||
System.out.println("Testing doServiceDocument(sdl, onBehalfOf):");
|
||||
System.out.println("======================================");
|
||||
//System.out.println(ss.doServiceDocument("sdl", "Stuart Lewis"));
|
||||
}
|
||||
|
||||
}
|
242
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/test/SwordTest.java
Executable file
242
dspace-sword/dspace-sword-api/src/main/java/org/purl/sword/test/SwordTest.java
Executable file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.purl.sword.test;
|
||||
|
||||
/**
|
||||
* Author : $Author: nst $
|
||||
* Date : $Date: 2007/09/21 15:18:57 $
|
||||
* Revision : $Revision: 1.3 $
|
||||
* Name : $Name: $
|
||||
*/
|
||||
|
||||
import org.purl.sword.base.*;
|
||||
|
||||
import org.w3.atom.*;
|
||||
|
||||
/**
|
||||
* Simple test class for the ServiceDocument and DepositResponse
|
||||
* classes in the SWORD common classes.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class SwordTest
|
||||
{
|
||||
/**
|
||||
* Start the test of the ServiceDocument followed by the
|
||||
* DepositResponse.
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SwordTest test = new SwordTest();
|
||||
test.serviceDocumentTest();
|
||||
|
||||
test.depositResponseTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test ServiceDocument class. Marshall and Unmarshall the
|
||||
* data to ensure that it is preserved when transformed to and
|
||||
* from an XML string.
|
||||
*/
|
||||
public void serviceDocumentTest()
|
||||
{
|
||||
// create a new service document
|
||||
Service service = new Service(ServiceLevel.ZERO);
|
||||
service.setVerbose(true);
|
||||
service.setNoOp(false);
|
||||
|
||||
// add some workspace/collections
|
||||
Workspace workspace = new Workspace();
|
||||
workspace.setTitle("This is a test");
|
||||
|
||||
Collection collection = new Collection();
|
||||
collection.setTitle("The first collection");
|
||||
collection.setLocation("http://www.somewhere.com/here");
|
||||
|
||||
workspace.addCollection(collection);
|
||||
|
||||
service.addWorkspace(workspace);
|
||||
|
||||
workspace = new Workspace();
|
||||
workspace.setTitle("This is a second test");
|
||||
|
||||
collection = new Collection();
|
||||
collection.setTitle("The second collection");
|
||||
collection.setLocation("http://www.somewhere.com/here/something");
|
||||
collection.addAccepts("application/zip");
|
||||
collection.addAccepts("application/xml");
|
||||
collection.setAbstract("An abstract goes in here");
|
||||
collection.setCollectionPolicy("A collection policy");
|
||||
collection.setMediation(true);
|
||||
collection.setFormatNamespace("a namespace in here");
|
||||
collection.setTreatment("treatment in here too");
|
||||
|
||||
workspace.addCollection(collection);
|
||||
|
||||
service.addWorkspace(workspace);
|
||||
|
||||
// create the service document, marshall, unmarshall and marshall again.
|
||||
ServiceDocument document = new ServiceDocument(service);
|
||||
|
||||
// display the XML document that has been constructed
|
||||
String doc = document.marshall();
|
||||
System.out.println(doc);
|
||||
|
||||
try
|
||||
{
|
||||
ServiceDocument unmarshalledDocument = new ServiceDocument();
|
||||
unmarshalledDocument.unmarshall(doc);
|
||||
|
||||
System.out.println(unmarshalledDocument.marshall());
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test DepositResponse class. Marshall and Unmarshall the
|
||||
* data to ensure that it is preserved when transformed to and
|
||||
* from an XML string.
|
||||
*/
|
||||
public void depositResponseTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
DepositResponse response = new DepositResponse(HttpHeaders.ACCEPTED);
|
||||
SWORDEntry entry = new SWORDEntry();
|
||||
entry.setId("atom:com.intrallect.atomTest3p0:60");
|
||||
Title title = new Title();
|
||||
title.setContent("Burning Stubble");
|
||||
title.setType(ContentType.TEXT);
|
||||
entry.setTitle(title);
|
||||
|
||||
// add authors
|
||||
Author author = new Author();
|
||||
author.setName("Sword Tester");
|
||||
author.setEmail("sword@ukoln.ac.uk");
|
||||
author.setUri("http://www.ukoln.ac.uk/repositories/digirep/index/SWORD");
|
||||
entry.addAuthors(author);
|
||||
|
||||
author = new Author();
|
||||
author.setName("CASIS Tester");
|
||||
author.setEmail("nst@aber.ac.uk");
|
||||
author.setUri("http://www.aber.ac.uk/casis/");
|
||||
entry.addAuthors(author);
|
||||
|
||||
// add links
|
||||
Link link = new Link();
|
||||
link.setRel("edit-media");
|
||||
link.setHref("http://bagel.intrallect.com:5555/intralibrary3p0/IntraLibrary-Deposit/edit-media/learning_object_id60");
|
||||
link.setHreflang("en");
|
||||
link.setTitle("Edit Media Title");
|
||||
link.setType("edit media type");
|
||||
link.setContent("some content in here");
|
||||
|
||||
entry.addLink(link);
|
||||
|
||||
link = new Link();
|
||||
link.setRel("edit");
|
||||
link.setHref("http://bagel.intrallect.com:5555/intralibrary3p0/IntraLibrary-Deposit/edit/learning_object_id60");
|
||||
link.setHreflang("en");
|
||||
link.setTitle("Edit Title");
|
||||
link.setType("edit type");
|
||||
link.setContent("some content in here");
|
||||
|
||||
entry.addLink(link);
|
||||
|
||||
entry.addCategory("test category");
|
||||
entry.addCategory("second test category");
|
||||
|
||||
Contributor contributor = new Contributor();
|
||||
contributor.setName("Neil Taylor");
|
||||
contributor.setEmail("nst@aber.ac.uk");
|
||||
contributor.setUri("http://www.aber.ac.uk/casis/");
|
||||
|
||||
entry.addContributor(contributor);
|
||||
|
||||
Rights rights = new Rights();
|
||||
rights.setType(ContentType.TEXT);
|
||||
rights.setContent("Rights declaration.");
|
||||
entry.setRights(rights);
|
||||
|
||||
Content content = new Content();
|
||||
content.setSource("http://bagel.intrallect.com:5555/intralibrary3p0/IntraLibrary?command=open-preview&learning_object_key=i189n4207t");
|
||||
content.setType("application/zip");
|
||||
entry.setContent(content);
|
||||
|
||||
Generator generator = new Generator();
|
||||
generator.setContent("Test Generator ID");
|
||||
generator.setUri("http://www.somewhere.com/");
|
||||
generator.setVersion("1.1");
|
||||
|
||||
Source source = new Source();
|
||||
source.setGenerator(generator);
|
||||
entry.setSource(source);
|
||||
|
||||
entry.setPublished("2007-08-02T10:13:14Z");
|
||||
entry.setUpdated("2007-08-02T10:22:17Z");
|
||||
|
||||
|
||||
entry.setFormatNamespace("Test format namespace");
|
||||
entry.setTreatment("Treatment description");
|
||||
entry.setNoOp(true);
|
||||
entry.setVerboseDescription("A Verbose Description.");
|
||||
|
||||
|
||||
response.setEntry( entry );
|
||||
|
||||
String test = response.marshall();
|
||||
System.out.println(test);
|
||||
System.out.println("=================");
|
||||
|
||||
DepositResponse unmarshalledDocument = new DepositResponse(HttpHeaders.CREATED);
|
||||
unmarshalledDocument.unmarshall(test);
|
||||
System.out.println(unmarshalledDocument.marshall());
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
240
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Author.java
Executable file
240
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Author.java
Executable file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an Author type, as used in ATOM. This class is used as the
|
||||
* base class for the different areas of ATOM that represent information
|
||||
* about people. This includes the atom:author and atom:contributor
|
||||
* elements.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Author extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The author's name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The author's URI.
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* The author's email.
|
||||
*/
|
||||
private String email;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'author'.
|
||||
*/
|
||||
public Author()
|
||||
{
|
||||
this("atom", "author");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance and set the element name.
|
||||
*
|
||||
* @param prefix The prefix to use when marshalling the data.
|
||||
* @param localName The localName to use when marshalling the data.
|
||||
*/
|
||||
public Author(String prefix, String localName )
|
||||
{
|
||||
super(prefix, localName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this object to a XOM Element. The element
|
||||
* will have the full name that is specified in the constructor.
|
||||
*
|
||||
* @return A XOM Element.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element element = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
|
||||
if( name != null )
|
||||
{
|
||||
Element nameElement = new Element(getQualifiedName("name"), Namespaces.NS_ATOM);
|
||||
nameElement.appendChild(name);
|
||||
element.appendChild(nameElement);
|
||||
}
|
||||
|
||||
if( uri != null )
|
||||
{
|
||||
Element uriElement = new Element(getQualifiedName("uri"), Namespaces.NS_ATOM);
|
||||
uriElement.appendChild(uri);
|
||||
element.appendChild(uriElement);
|
||||
}
|
||||
|
||||
if( email != null )
|
||||
{
|
||||
Element emailElement = new Element(getQualifiedName("email"), Namespaces.NS_ATOM);
|
||||
emailElement.appendChild(email);
|
||||
element.appendChild(emailElement);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unmarshall the author details from the specified element. The element
|
||||
* is a XOM element.
|
||||
*
|
||||
*/
|
||||
public void unmarshall(Element author)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf( author, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException("Element is not of the correct type");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = author.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
|
||||
if( isInstanceOf(element, "name", Namespaces.NS_ATOM ))
|
||||
{
|
||||
name = unmarshallString(element);
|
||||
}
|
||||
if( isInstanceOf(element, "uri", Namespaces.NS_ATOM ))
|
||||
{
|
||||
uri = unmarshallString(element);
|
||||
}
|
||||
if( isInstanceOf(element, "email", Namespaces.NS_ATOM ))
|
||||
{
|
||||
email = unmarshallString(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown element type
|
||||
//counter.other++;
|
||||
}
|
||||
} // for
|
||||
}
|
||||
catch( UnmarshallException ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in " + getQualifiedName() + ": " + ex.getMessage());
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the author name.
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the author name.
|
||||
*
|
||||
* @param name The name.
|
||||
*/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author URI.
|
||||
*
|
||||
* @return The URI.
|
||||
*/
|
||||
public String getUri()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the author URI.
|
||||
*
|
||||
* @param uri the URI.
|
||||
*/
|
||||
public void setUri(String uri)
|
||||
{
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author email.
|
||||
*
|
||||
* @return The email.
|
||||
*/
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the author email.
|
||||
*
|
||||
* @param email The email.
|
||||
*/
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
}
|
203
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Content.java
Executable file
203
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Content.java
Executable file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Attribute;
|
||||
import nu.xom.Element;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Content element.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public class Content extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The identifier for the src attribute.
|
||||
*/
|
||||
public static final String ATTR_SRC = "src";
|
||||
|
||||
/**
|
||||
* The identifier for the type attribute.
|
||||
*/
|
||||
public static final String ATTR_TYPE = "type";
|
||||
|
||||
/**
|
||||
* The data for the type attribute.
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* The data for the source attribute.
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'content'.
|
||||
*/
|
||||
public Content()
|
||||
{
|
||||
super("atom", "content");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Source.
|
||||
*
|
||||
* @return The Source.
|
||||
*/
|
||||
public String getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Source.
|
||||
*
|
||||
* @param source The source.
|
||||
*/
|
||||
public void setSource(String source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type for the content. This should match the pattern
|
||||
* ".* /.*" [Note, there is no space before the /, this has been added
|
||||
* to allow this text to be written in a Java comment.].
|
||||
*
|
||||
* An example of the type is <code>application/zip</code>.
|
||||
*
|
||||
* @param type The specified type.
|
||||
* @throws InvalidMediaTypeException If the specified type is null or
|
||||
* it does not match the specified pattern.
|
||||
*/
|
||||
public void setType(String type)
|
||||
throws InvalidMediaTypeException
|
||||
{
|
||||
if( type == null || ! type.matches(".*/.*") )
|
||||
{
|
||||
throw new InvalidMediaTypeException("Type: '" + type + "' does not match .*/.*");
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this object to an Element object.
|
||||
*
|
||||
* @return A XOM Element that holds the data for this Content element.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element content = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
|
||||
if( type != null )
|
||||
{
|
||||
Attribute typeAttribute = new Attribute(ATTR_TYPE, type);
|
||||
content.addAttribute(typeAttribute);
|
||||
}
|
||||
|
||||
if( source != null )
|
||||
{
|
||||
Attribute typeAttribute = new Attribute(ATTR_SRC, source);
|
||||
content.addAttribute(typeAttribute);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the content element into the data in this object.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain a
|
||||
* content element or if there are problems
|
||||
* accessing the data.
|
||||
*/
|
||||
public void unmarshall(Element content)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf( content, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException("Element is not of the correct type");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// get the attributes
|
||||
int attributeCount = content.getAttributeCount();
|
||||
Attribute attribute = null;
|
||||
for( int i = 0; i < attributeCount; i++ )
|
||||
{
|
||||
attribute = content.getAttribute(i);
|
||||
String name = attribute.getQualifiedName();
|
||||
if( ATTR_TYPE.equals(name))
|
||||
{
|
||||
type = attribute.getValue();
|
||||
}
|
||||
|
||||
if( ATTR_SRC.equals(name) )
|
||||
{
|
||||
source = attribute.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Content: " + ex.getMessage());
|
||||
throw new UnmarshallException("Error parsing Content", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
72
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/ContentType.java
Executable file
72
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/ContentType.java
Executable file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public enum ContentType
|
||||
{
|
||||
TEXT ("text"),
|
||||
HTML ("html"),
|
||||
XHTML ("xhtml");
|
||||
|
||||
/**
|
||||
* String representation of the type.
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
/**
|
||||
* Create a new instance and set the string
|
||||
* representation of the type.
|
||||
*
|
||||
* @param type The type, expressed as a string.
|
||||
*/
|
||||
private ContentType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a string representation of this object.
|
||||
*
|
||||
* @return A string.
|
||||
*/
|
||||
public String toString() { return this.type; }
|
||||
}
|
56
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Contributor.java
Executable file
56
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Contributor.java
Executable file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import org.w3.atom.Author;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Contributor.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Contributor extends Author
|
||||
{
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'contributor'.
|
||||
*/
|
||||
public Contributor()
|
||||
{
|
||||
super("atom", "contributor");
|
||||
}
|
||||
}
|
598
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Entry.java
Executable file
598
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Entry.java
Executable file
@@ -0,0 +1,598 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an ATOM entry.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*
|
||||
*/
|
||||
public class Entry extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* A list of authors associated with this entry. There can be 0
|
||||
* or more of these elements.
|
||||
*/
|
||||
private List<Author> authors;
|
||||
|
||||
/**
|
||||
* The atom:category data. There can be 0 or more of these elements.
|
||||
* FIXME - this does not accommodate the idea of 'anyForeignElement'
|
||||
*/
|
||||
private List<String> categories; // FIXME - needed?
|
||||
|
||||
/**
|
||||
* A single content element for the Entry.
|
||||
*/
|
||||
private Content content;
|
||||
|
||||
/**
|
||||
* A list of contributors associated with this entry. There can be 0 or
|
||||
* more of these elements.
|
||||
*/
|
||||
private List<Contributor> contributors;
|
||||
|
||||
/**
|
||||
* This is a simplified version. The ID can also have atomCommonAttributes,
|
||||
* but these have not been modelled in this version. The content of
|
||||
* ID is an unconstrained string, which is intended to represent a URI.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* A list of link elements. This can contain 0 or more entries.
|
||||
*/
|
||||
private List<Link> links;
|
||||
|
||||
/**
|
||||
* Simplified version of the atom:published element. This implementation
|
||||
* does not record the general atomCommonAttributes. The date is
|
||||
* taken from an xsd:dateTime value.
|
||||
*
|
||||
* This item is optional.
|
||||
*/
|
||||
private Date published;
|
||||
|
||||
/**
|
||||
* A single, optional, content element for the Entry.
|
||||
* FIXME - this does not cater for the different content types.
|
||||
*/
|
||||
private Rights rights;
|
||||
|
||||
/**
|
||||
* A single, optional, content element for the Entry.
|
||||
*/
|
||||
private Source source;
|
||||
|
||||
/**
|
||||
* A single, optional, summary element for the Entry.
|
||||
* FIXME - this does not cater for the different content types.
|
||||
*/
|
||||
private Summary summary;
|
||||
|
||||
/**
|
||||
* A required title element for the entry.
|
||||
* FIXME - this does not cater for the different content types.
|
||||
*/
|
||||
private Title title;
|
||||
|
||||
/**
|
||||
* The date on which the entry was last updated.
|
||||
*/
|
||||
private Date updated;
|
||||
|
||||
/**
|
||||
* Create a new instance of the class and initialise it.
|
||||
* Also, set the prefix to 'atom' and the local name to 'entry'.
|
||||
*/
|
||||
public Entry()
|
||||
{
|
||||
super("atom", "entry");
|
||||
|
||||
authors = new ArrayList<Author>();
|
||||
categories = new ArrayList<String>();
|
||||
contributors = new ArrayList<Contributor>();
|
||||
links = new ArrayList<Link>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mashall the data stored in this object into Element objects.
|
||||
*
|
||||
* @return An element that holds the data associated with this object.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element entry = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
entry.addNamespaceDeclaration("sword", Namespaces.NS_SWORD);
|
||||
entry.addNamespaceDeclaration("atom", Namespaces.NS_ATOM);
|
||||
|
||||
if( id != null )
|
||||
{
|
||||
Element idElement = new Element(getQualifiedName("id"), Namespaces.NS_ATOM);
|
||||
idElement.appendChild(id);
|
||||
entry.appendChild(idElement);
|
||||
}
|
||||
|
||||
for( Author author : authors )
|
||||
{
|
||||
entry.appendChild(author.marshall());
|
||||
}
|
||||
|
||||
if( content != null )
|
||||
{
|
||||
entry.appendChild(content.marshall());
|
||||
}
|
||||
|
||||
for( Author contributor : contributors )
|
||||
{
|
||||
entry.appendChild(contributor.marshall());
|
||||
}
|
||||
|
||||
for( Link link : links )
|
||||
{
|
||||
entry.appendChild(link.marshall());
|
||||
}
|
||||
|
||||
if( published != null )
|
||||
{
|
||||
Element publishedElement = new Element(getQualifiedName("published"), Namespaces.NS_ATOM);
|
||||
publishedElement.appendChild(dateToString(published));
|
||||
entry.appendChild(publishedElement);
|
||||
}
|
||||
|
||||
if( rights != null )
|
||||
{
|
||||
entry.appendChild(rights.marshall());
|
||||
}
|
||||
|
||||
if( summary != null )
|
||||
{
|
||||
entry.appendChild(summary.marshall());
|
||||
}
|
||||
|
||||
if( title != null )
|
||||
{
|
||||
entry.appendChild(title.marshall());
|
||||
}
|
||||
|
||||
if( source != null )
|
||||
{
|
||||
entry.appendChild(source.marshall());
|
||||
}
|
||||
|
||||
if( updated != null )
|
||||
{
|
||||
Element updatedElement = new Element(getQualifiedName("updated"), Namespaces.NS_ATOM);
|
||||
updatedElement.appendChild(dateToString(updated));
|
||||
entry.appendChild(updatedElement);
|
||||
}
|
||||
|
||||
Element categoryElement = null;
|
||||
for( String category : categories )
|
||||
{
|
||||
categoryElement = new Element(getQualifiedName("category"), Namespaces.NS_ATOM );
|
||||
categoryElement.appendChild(category);
|
||||
entry.appendChild(categoryElement);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the contents of the Entry element into the internal data objects
|
||||
* in this object.
|
||||
*
|
||||
* @param entry The Entry element to process.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain an ATOM entry
|
||||
* element, or if there is a problem processing the element or any
|
||||
* subelements.
|
||||
*/
|
||||
public void unmarshall(Element entry)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(entry, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException( "Not a " + getQualifiedName() + " element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
authors.clear();
|
||||
categories.clear();
|
||||
contributors.clear();
|
||||
links.clear();
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = entry.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
|
||||
if( isInstanceOf(element, "author", Namespaces.NS_ATOM ) )
|
||||
{
|
||||
Author author = new Author();
|
||||
author.unmarshall(element);
|
||||
authors.add(author);
|
||||
}
|
||||
else if( isInstanceOf(element, "category", Namespaces.NS_ATOM ))
|
||||
{
|
||||
categories.add(unmarshallString(element));
|
||||
}
|
||||
else if( isInstanceOf(element, "content", Namespaces.NS_ATOM))
|
||||
{
|
||||
content = new Content();
|
||||
content.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "contributor", Namespaces.NS_ATOM))
|
||||
{
|
||||
Contributor contributor = new Contributor();
|
||||
contributor.unmarshall(element);
|
||||
contributors.add(contributor);
|
||||
}
|
||||
else if( isInstanceOf(element, "id", Namespaces.NS_ATOM ))
|
||||
{
|
||||
id = unmarshallString(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "link", Namespaces.NS_ATOM))
|
||||
{
|
||||
Link link = new Link();
|
||||
link.unmarshall(element);
|
||||
links.add(link);
|
||||
}
|
||||
else if( isInstanceOf(element, "published", Namespaces.NS_ATOM) )
|
||||
{
|
||||
published = unmarshallDate(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "rights", Namespaces.NS_ATOM))
|
||||
{
|
||||
rights = new Rights();
|
||||
rights.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "summary", Namespaces.NS_ATOM))
|
||||
{
|
||||
summary = new Summary();
|
||||
summary.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "title", Namespaces.NS_ATOM))
|
||||
{
|
||||
title = new Title();
|
||||
title.unmarshall(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "updated", Namespaces.NS_ATOM) )
|
||||
{
|
||||
updated = unmarshallDate(element);
|
||||
}
|
||||
else if( isInstanceOf(element, "source", Namespaces.NS_ATOM))
|
||||
{
|
||||
source = new Source();
|
||||
source.unmarshall(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown element type
|
||||
//counter.other++;
|
||||
}
|
||||
} // for
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Entry: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
throw new UnmarshallException("Unable to parse an element in " + getQualifiedName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the authors in the Entry.
|
||||
*
|
||||
* @return An iterator.
|
||||
*/
|
||||
public Iterator<Author> getAuthors()
|
||||
{
|
||||
return authors.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an author to the Entry.
|
||||
*
|
||||
* @param author The author to add.
|
||||
*/
|
||||
public void addAuthors(Author author)
|
||||
{
|
||||
this.authors.add(author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of authors.
|
||||
*/
|
||||
public void clearAuthors()
|
||||
{
|
||||
this.authors.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator for the categories in this Entry.
|
||||
*
|
||||
* @return An iterator.
|
||||
*/
|
||||
public Iterator<String> getCategories() {
|
||||
return categories.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a category.
|
||||
*
|
||||
* @param category the category to add.
|
||||
*/
|
||||
public void addCategory(String category) {
|
||||
this.categories.add(category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of categories.
|
||||
*/
|
||||
public void clearCategories()
|
||||
{
|
||||
this.categories.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content element for this Entry.
|
||||
*
|
||||
* @return The content element.
|
||||
*/
|
||||
public Content getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content element for this Entry.
|
||||
* @param content
|
||||
*/
|
||||
public void setContent(Content content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of contributors.
|
||||
*
|
||||
* @return An iterator.
|
||||
*/
|
||||
public Iterator<Contributor> getContributors() {
|
||||
return contributors.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a contributor.
|
||||
*
|
||||
* @param contributor The contributor.
|
||||
*/
|
||||
public void addContributor(Contributor contributor) {
|
||||
this.contributors.add(contributor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of contributors.
|
||||
*/
|
||||
public void clearContributors()
|
||||
{
|
||||
this.contributors.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID for this Entry.
|
||||
*
|
||||
* @return The ID.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ID for this Entry.
|
||||
*
|
||||
* @param id The ID.
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of links for this Entry.
|
||||
*
|
||||
* @return An iterator.
|
||||
*/
|
||||
public Iterator<Link> getLinks() {
|
||||
return links.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the link for this Entry.
|
||||
*
|
||||
* @param link The link.
|
||||
*/
|
||||
public void addLink(Link link) {
|
||||
this.links.add(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the list of links.
|
||||
*/
|
||||
public void clearLinks()
|
||||
{
|
||||
this.links.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the published date, expressed as a String.
|
||||
*
|
||||
* @return The date.
|
||||
*/
|
||||
public String getPublished() {
|
||||
return dateToString(published);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the published date. Converts the date string into a date.
|
||||
* The date should be expressed as a string with the format:
|
||||
* 'yyyy-mm-ddThh:mm:ssZ'.
|
||||
*
|
||||
* @param published The string.
|
||||
*
|
||||
* @throws ParseException, if the date does not match format.
|
||||
*/
|
||||
public void setPublished(String published)
|
||||
throws ParseException
|
||||
{
|
||||
this.published = stringToDate(published);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rights for this Entry.
|
||||
* @return The rights.
|
||||
*/
|
||||
public Rights getRights() {
|
||||
return rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the rights for this Entry.
|
||||
*
|
||||
* @param rights The rights.
|
||||
*/
|
||||
public void setRights(Rights rights) {
|
||||
this.rights = rights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source for this Entry.
|
||||
* @return The source.
|
||||
*/
|
||||
public Source getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the source for this entry.
|
||||
*
|
||||
* @param source The source.
|
||||
*/
|
||||
public void setSource(Source source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the summary.
|
||||
*
|
||||
* @return The summary.
|
||||
*/
|
||||
public Summary getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the summary.
|
||||
*
|
||||
* @param summary The summary.
|
||||
*/
|
||||
public void setSummary(Summary summary) {
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title.
|
||||
*
|
||||
* @return The title.
|
||||
*/
|
||||
public Title getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title.
|
||||
*
|
||||
* @param title The title.
|
||||
*/
|
||||
public void setTitle(Title title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the updated date, expressed as a String.
|
||||
*
|
||||
* @return The date.
|
||||
*/
|
||||
public String getUpdated() {
|
||||
return dateToString(updated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the updated date. Converts the date string into a date.
|
||||
* The date should be expressed as a string with the format:
|
||||
* 'yyyy-mm-ddThh:mm:ssZ'.
|
||||
*
|
||||
* @param updated The string.
|
||||
*
|
||||
* @throws ParseException, if the date does not match format.
|
||||
*/
|
||||
public void setUpdated(String updated)
|
||||
throws ParseException
|
||||
{
|
||||
this.updated = stringToDate(updated);
|
||||
}
|
||||
|
||||
}
|
210
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Generator.java
Executable file
210
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Generator.java
Executable file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Attribute;
|
||||
import nu.xom.Element;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Generator element.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Generator extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The content for the element.
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* The URI attribute.
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* The version attribute.
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'generator'.
|
||||
*/
|
||||
public Generator()
|
||||
{
|
||||
super("atom", "generator");
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in the object to an Element object.
|
||||
*
|
||||
* @return The element.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element element = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
|
||||
if( content != null )
|
||||
{
|
||||
element.appendChild(content);
|
||||
}
|
||||
|
||||
if( uri != null )
|
||||
{
|
||||
Attribute uriAttribute = new Attribute("uri", uri);
|
||||
element.addAttribute(uriAttribute);
|
||||
}
|
||||
|
||||
if( version != null )
|
||||
{
|
||||
Attribute versionAttribute = new Attribute("version", version);
|
||||
element.addAttribute(versionAttribute);
|
||||
}
|
||||
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the specified Generator element into the data in this object.
|
||||
*
|
||||
* @param generator The generator element.
|
||||
*
|
||||
* @throws UnmarshallException If the specified element is not an atom:generator
|
||||
* element, or if there is an error accessing the data.
|
||||
*/
|
||||
public void unmarshall(Element generator)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(generator, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException( "Not an atom:generator element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// get the attributes
|
||||
int attributeCount = generator.getAttributeCount();
|
||||
Attribute attribute = null;
|
||||
for( int i = 0; i < attributeCount; i++ )
|
||||
{
|
||||
attribute = generator.getAttribute(i);
|
||||
if( "uri".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
uri = attribute.getValue();
|
||||
}
|
||||
else if( "version".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
version = attribute.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
int length = generator.getChildCount();
|
||||
if( length > 0 )
|
||||
{
|
||||
content = unmarshallString(generator);
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Generator: " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse element in Generator", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content.
|
||||
*
|
||||
* @return The content.
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content.
|
||||
*
|
||||
* @param content The content.
|
||||
*/
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URI.
|
||||
*
|
||||
* @return The URI.
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URI.
|
||||
*
|
||||
* @param uri The URI.
|
||||
*/
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version.
|
||||
*
|
||||
* @return The version.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version.
|
||||
*
|
||||
* @param version The version.
|
||||
*/
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
/**
|
||||
* An invalid media type has been detected during parsing.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class InvalidMediaTypeException extends Exception
|
||||
{
|
||||
/**
|
||||
* Create a new instance and store the message.
|
||||
*
|
||||
* @param message The exception's message.
|
||||
*/
|
||||
public InvalidMediaTypeException( String message )
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
}
|
351
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Link.java
Executable file
351
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Link.java
Executable file
@@ -0,0 +1,351 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Attribute;
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Link element.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Link extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* Stores the href.
|
||||
*/
|
||||
private String href;
|
||||
|
||||
/**
|
||||
* Stores the Rel attribute.
|
||||
*/
|
||||
private String rel;
|
||||
|
||||
/**
|
||||
* Stores the type.
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* Stores the HREF lang.
|
||||
*/
|
||||
private String hreflang;
|
||||
|
||||
/**
|
||||
* Stores the title.
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* Stores the length.
|
||||
*/
|
||||
private String length;
|
||||
|
||||
/**
|
||||
* Stores the content.
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* Create a new instance and set prefix and local name to 'atom' and 'link',
|
||||
* respectively.
|
||||
*/
|
||||
public Link()
|
||||
{
|
||||
super("atom", "link");
|
||||
}
|
||||
|
||||
/**
|
||||
* Mashall the data stored in this object into Element objects.
|
||||
*
|
||||
* @return An element that holds the data associated with this object.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element element = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
|
||||
if( content != null )
|
||||
{
|
||||
element.appendChild(content);
|
||||
}
|
||||
|
||||
if( href != null )
|
||||
{
|
||||
Attribute hrefAttribute = new Attribute("href", href);
|
||||
element.addAttribute(hrefAttribute);
|
||||
}
|
||||
|
||||
if( rel != null )
|
||||
{
|
||||
Attribute relAttribute = new Attribute("rel", rel);
|
||||
element.addAttribute(relAttribute);
|
||||
}
|
||||
|
||||
if( type != null )
|
||||
{
|
||||
Attribute typeAttribute = new Attribute("type", type);
|
||||
element.addAttribute(typeAttribute);
|
||||
}
|
||||
|
||||
if( hreflang != null )
|
||||
{
|
||||
Attribute hreflangAttribute = new Attribute("hreflang", hreflang);
|
||||
element.addAttribute(hreflangAttribute);
|
||||
}
|
||||
|
||||
if( title != null )
|
||||
{
|
||||
Attribute titleAttribute = new Attribute("title", title);
|
||||
element.addAttribute(titleAttribute);
|
||||
}
|
||||
|
||||
if( length != null )
|
||||
{
|
||||
Attribute lengthAttribute = new Attribute("length", length);
|
||||
element.addAttribute(lengthAttribute);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the contents of the Link element into the internal data objects
|
||||
* in this object.
|
||||
*
|
||||
* @param link The Link element to process.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain an ATOM link
|
||||
* element, or if there is a problem processing the element or any
|
||||
* subelements.
|
||||
*/
|
||||
public void unmarshall(Element link)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(link, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException( "Not an atom:link element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// get the attributes
|
||||
int attributeCount = link.getAttributeCount();
|
||||
Attribute attribute = null;
|
||||
for( int i = 0; i < attributeCount; i++ )
|
||||
{
|
||||
attribute = link.getAttribute(i);
|
||||
if( "href".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
href = attribute.getValue();
|
||||
}
|
||||
else if( "rel".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
rel = attribute.getValue();
|
||||
}
|
||||
else if( "type".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
type = attribute.getValue();
|
||||
}
|
||||
else if( "hreflang".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
// FIXME - is this the correct element?
|
||||
hreflang = attribute.getValue();
|
||||
}
|
||||
else if( "title".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
title = attribute.getValue();
|
||||
}
|
||||
else if( "length".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
length = attribute.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = link.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
content = unmarshallString(element);
|
||||
// FIXME - is this correct?
|
||||
|
||||
} // for
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Link: " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse element in link", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HREF attribute.
|
||||
*
|
||||
* @return The HREF.
|
||||
*/
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HREF attribute.
|
||||
*
|
||||
* @param href The href.
|
||||
*/
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Rel attribute.
|
||||
*
|
||||
* @return The Rel.
|
||||
*/
|
||||
public String getRel() {
|
||||
return rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Rel attribute.
|
||||
*
|
||||
* @param rel The Rel.
|
||||
*/
|
||||
public void setRel(String rel) {
|
||||
this.rel = rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type.
|
||||
* @param type The type.
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HREF Lang attribute.
|
||||
*
|
||||
* @return The HREF Lang.
|
||||
*/
|
||||
public String getHreflang() {
|
||||
return hreflang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HREF Lang attribute.
|
||||
*
|
||||
* @param hreflang The HREF Lang.
|
||||
*/
|
||||
public void setHreflang(String hreflang) {
|
||||
this.hreflang = hreflang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title.
|
||||
*
|
||||
* @return The title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title.
|
||||
*
|
||||
* @param title The title.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length.
|
||||
*
|
||||
* @return The length.
|
||||
*/
|
||||
public String getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length.
|
||||
*
|
||||
* @param length The length.
|
||||
*/
|
||||
public void setLength(String length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content.
|
||||
*
|
||||
* @return The content.
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content.
|
||||
*
|
||||
* @param content The content.
|
||||
*/
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
}
|
57
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Rights.java
Executable file
57
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Rights.java
Executable file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Rights element. This is a simple subclass of the
|
||||
* TextConstruct class.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Rights extends TextConstruct
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'rights'.
|
||||
*/
|
||||
public Rights()
|
||||
{
|
||||
super("atom", "rights");
|
||||
}
|
||||
|
||||
}
|
148
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Source.java
Executable file
148
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Source.java
Executable file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Element;
|
||||
import nu.xom.Elements;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Generator element.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Source extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The generator data for this object.
|
||||
*/
|
||||
private Generator generator;
|
||||
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'source'.
|
||||
*/
|
||||
public Source()
|
||||
{
|
||||
super("atom", "source");
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data stored in this object into Element objects.
|
||||
*
|
||||
* @return An element that holds the data associated with this object.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element source = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
|
||||
if( generator != null )
|
||||
{
|
||||
source.appendChild(generator.marshall());
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the contents of the source element into the internal data objects
|
||||
* in this object.
|
||||
*
|
||||
* @param source The Source element to process.
|
||||
*
|
||||
* @throws UnmarshallException If the element does not contain an ATOM Source
|
||||
* element, or if there is a problem processing the element or any
|
||||
* sub-elements.
|
||||
*/
|
||||
public void unmarshall(Element source)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(source, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException( "Not an atom:source element" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// retrieve all of the sub-elements
|
||||
Elements elements = source.getChildElements();
|
||||
Element element = null;
|
||||
int length = elements.size();
|
||||
|
||||
for(int i = 0; i < length; i++ )
|
||||
{
|
||||
element = elements.get(i);
|
||||
if( isInstanceOf(element, "generator", Namespaces.NS_ATOM ) )
|
||||
{
|
||||
generator = new Generator();
|
||||
generator.unmarshall(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in Source: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
throw new UnmarshallException("Unable to parse an element in Source", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the generator.
|
||||
*
|
||||
* @return The generator.
|
||||
*/
|
||||
public Generator getGenerator()
|
||||
{
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the generator.
|
||||
*
|
||||
* @param generator The generator.
|
||||
*/
|
||||
public void setGenerator(Generator generator)
|
||||
{
|
||||
this.generator = generator;
|
||||
}
|
||||
}
|
55
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Summary.java
Executable file
55
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Summary.java
Executable file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Summary element. This is a simple subclass of the
|
||||
* TextConstruct class.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Summary extends TextConstruct
|
||||
{
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'summary'.
|
||||
*/
|
||||
public Summary()
|
||||
{
|
||||
super("atom", "summary");
|
||||
}
|
||||
}
|
213
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/TextConstruct.java
Executable file
213
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/TextConstruct.java
Executable file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
import nu.xom.Attribute;
|
||||
import nu.xom.Element;
|
||||
|
||||
import org.purl.sword.base.InfoLogger;
|
||||
import org.purl.sword.base.Namespaces;
|
||||
import org.purl.sword.base.SwordElementInterface;
|
||||
import org.purl.sword.base.UnmarshallException;
|
||||
import org.purl.sword.base.XmlElement;
|
||||
|
||||
/**
|
||||
* Represents a text construct in the ATOM elements. This is a superclass of
|
||||
* several elements within this implementation.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class TextConstruct extends XmlElement implements SwordElementInterface
|
||||
{
|
||||
/**
|
||||
* The content in the element.
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* The type of the element.
|
||||
*/
|
||||
private ContentType type;
|
||||
|
||||
/**
|
||||
* Create a new instance, specifying the prefix and local name.
|
||||
*
|
||||
* @param prefix The prefix.
|
||||
* @param name The local name.
|
||||
*/
|
||||
public TextConstruct(String prefix, String name)
|
||||
{
|
||||
super(prefix, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance. Set the default type to TextConstructType.TEXT.
|
||||
*
|
||||
* @param name The name that will be applied.
|
||||
*/
|
||||
public TextConstruct(String name)
|
||||
{
|
||||
super(name);
|
||||
this.type = ContentType.TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshall the data in this object to an Element object.
|
||||
*
|
||||
* @return The data expressed in an Element.
|
||||
*/
|
||||
public Element marshall()
|
||||
{
|
||||
Element element = new Element(getQualifiedName(), Namespaces.NS_ATOM);
|
||||
if( type != null )
|
||||
{
|
||||
Attribute typeAttribute = new Attribute("type", type.toString());
|
||||
element.addAttribute(typeAttribute);
|
||||
}
|
||||
|
||||
if( content != null )
|
||||
{
|
||||
element.appendChild(content);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshall the text element into this object.
|
||||
*
|
||||
* This unmarshaller only handles plain text content, although it can
|
||||
* recognise the three different type elements of text, html and xhtml. This
|
||||
* is an area that can be improved in a future implementation, if necessary.
|
||||
*
|
||||
* @param text The text element.
|
||||
*
|
||||
* @throws UnmarshallException If the specified element is not of
|
||||
* the correct type, where the localname is used
|
||||
* to specify the valid name. Also thrown
|
||||
* if there is an issue accessing the data.
|
||||
*/
|
||||
public void unmarshall(Element text)
|
||||
throws UnmarshallException
|
||||
{
|
||||
if( ! isInstanceOf(text, localName, Namespaces.NS_ATOM))
|
||||
{
|
||||
throw new UnmarshallException( "Not a " + getQualifiedName() + " element" );
|
||||
}
|
||||
try
|
||||
{
|
||||
// get the attributes
|
||||
int attributeCount = text.getAttributeCount();
|
||||
Attribute attribute = null;
|
||||
for( int i = 0; i < attributeCount; i++ )
|
||||
{
|
||||
attribute = text.getAttribute(i);
|
||||
if( "type".equals(attribute.getQualifiedName()))
|
||||
{
|
||||
String value = attribute.getValue();
|
||||
if( ContentType.TEXT.toString().equals(value) )
|
||||
{
|
||||
type = ContentType.TEXT;
|
||||
}
|
||||
else if( ContentType.HTML.toString().equals(value) )
|
||||
{
|
||||
type = ContentType.HTML;
|
||||
}
|
||||
else if( ContentType.XHTML.toString().equals(value) )
|
||||
{
|
||||
type = ContentType.XHTML;
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse extract type in " + getQualifiedName() );
|
||||
// FIXME - check error handling here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve all of the sub-elements
|
||||
int length = text.getChildCount();
|
||||
if( length > 0 )
|
||||
{
|
||||
content = unmarshallString(text);
|
||||
}
|
||||
// FIXME - the above only handles plain text content.
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
InfoLogger.getLogger().writeError("Unable to parse an element in " + getQualifiedName() + ": " + ex.getMessage());
|
||||
throw new UnmarshallException("Unable to parse an element in " + getQualifiedName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content in this TextConstruct.
|
||||
*
|
||||
* @return The content, expressed as a string.
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content. This only supports text content.
|
||||
*
|
||||
* @param content The content.
|
||||
*/
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public ContentType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type.
|
||||
*
|
||||
* @param type The type.
|
||||
*/
|
||||
public void setType(ContentType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
}
|
55
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Title.java
Executable file
55
dspace-sword/dspace-sword-api/src/main/java/org/w3/atom/Title.java
Executable file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
package org.w3.atom;
|
||||
|
||||
/**
|
||||
* Represents an ATOM Title element. This is a simple subclass of the
|
||||
* TextConstruct class.
|
||||
*
|
||||
* @author Neil Taylor
|
||||
*/
|
||||
public class Title extends TextConstruct
|
||||
{
|
||||
/**
|
||||
* Create a new instance and set the prefix to
|
||||
* 'atom' and the local name to 'title'.
|
||||
*/
|
||||
public Title()
|
||||
{
|
||||
super("atom", "title");
|
||||
}
|
||||
}
|
162
dspace-sword/dspace-sword-webapp/pom.xml
Normal file
162
dspace-sword/dspace-sword-webapp/pom.xml
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword-webapp</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>DSpace SWORD :: Web Application</name>
|
||||
<description>DSpace SWORD Deposit Service Provider Web Application</description>
|
||||
<url>http://www.ukoln.ac.uk/repositories/digirep/index/SWORD</url>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword</artifactId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Snapshot Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<updatePolicy>never</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>
|
||||
scm:svn:http://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-webapp
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-webapp
|
||||
</developerConnection>
|
||||
<url>
|
||||
http://dspace.svn.sourceforge.net/viewvc/dspace/branches/dspace-1_5_x/dspace-sword/dspace-sword-webapp
|
||||
</url>
|
||||
</scm>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<!--
|
||||
when activated a dspace.config configuration
|
||||
file location passed on the commandline
|
||||
(-Ddspace.config=...) can be passed through
|
||||
to be used as a filter source by projects for
|
||||
tasks such as updating the ${dspace.dir} in
|
||||
web.xml etc.
|
||||
-->
|
||||
<profile>
|
||||
<activation>
|
||||
<property>
|
||||
<name>dspace.config</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<filters>
|
||||
<filter>${dspace.config}</filter>
|
||||
</filters>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>oracle-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>db.name</name>
|
||||
<value>oracle</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc14</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>postgres-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!db.name</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword-api</artifactId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
|
||||
|
||||
<!-- web.xml
|
||||
- This is the web application configuration for the DSpace SWORD
|
||||
- module. It is not advisable to change the contents of this
|
||||
- file unless you know exactly what you are doing
|
||||
-->
|
||||
|
||||
<web-app>
|
||||
|
||||
<display-name>DSpace SWORD Server</display-name>
|
||||
|
||||
<!-- Configuration Information -->
|
||||
|
||||
<context-param>
|
||||
<param-name>dspace-config</param-name>
|
||||
<param-value>${dspace.dir}/config/dspace.cfg</param-value>
|
||||
<description>
|
||||
The location of the main DSpace configuration file
|
||||
</description>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>server-class</param-name>
|
||||
<param-value>org.dspace.sword.DSpaceSWORDServer</param-value>
|
||||
<description>
|
||||
The SWORDServer class name
|
||||
</description>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>authentication-method</param-name>
|
||||
<param-value>Basic</param-value>
|
||||
<description>
|
||||
The type of authentication used : [Basic|None]
|
||||
</description>
|
||||
</context-param>
|
||||
|
||||
<!-- Servlets -->
|
||||
|
||||
<!-- DSpace configuration initialisation. This needs to be loaded before
|
||||
other servlets. -->
|
||||
<servlet>
|
||||
<servlet-name>load-dspace-config</servlet-name>
|
||||
<servlet-class>org.dspace.sword.LoadDSpaceConfig</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>servicedocument</servlet-name>
|
||||
<servlet-class>org.purl.sword.server.ServiceDocumentServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>deposit</servlet-name>
|
||||
<servlet-class>org.purl.sword.server.DepositServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<!-- Servlet Mappings -->
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>servicedocument</servlet-name>
|
||||
<url-pattern>/servicedocument</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>deposit</servlet-name>
|
||||
<url-pattern>/deposit/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
BIN
dspace-sword/example/example.zip
Normal file
BIN
dspace-sword/example/example.zip
Normal file
Binary file not shown.
164
dspace-sword/example/mets.xml
Normal file
164
dspace-sword/example/mets.xml
Normal file
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<mets ID="sort-mets_mets" OBJID="sword-mets" LABEL="DSpace SWORD Item"
|
||||
PROFILE="DSpace METS SIP Profile 1.0" xmlns="http://www.loc.gov/METS/"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.loc.gov/METS/ http://www.loc.gov/standards/mets/mets.xsd">
|
||||
|
||||
<metsHdr CREATEDATE="2007-09-01T00:00:00">
|
||||
<agent ROLE="CUSTODIAN" TYPE="ORGANIZATION">
|
||||
<name>Richard Jones</name>
|
||||
</agent>
|
||||
</metsHdr>
|
||||
|
||||
<dmdSec ID="sword-mets-dmd-1" GROUPID="sword-mets-dmd-1_group-1">
|
||||
<mdWrap LABEL="SWAP Metadata" MDTYPE="OTHER" OTHERMDTYPE="EPDCX"
|
||||
MIMETYPE="text/xml">
|
||||
|
||||
<xmlData>
|
||||
<epdcx:descriptionSet
|
||||
xmlns:epdcx="http://purl.org/eprint/epdcx/2006-11-16/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://purl.org/eprint/epdcx/2006-11-16/ http://purl.org/eprint/epdcx/xsd/2006-11-16/epdcx.xsd">
|
||||
|
||||
<epdcx:description
|
||||
epdcx:resourceId="sword-mets-epdcx-1">
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/type"
|
||||
epdcx:valueURI="http://purl.org/eprint/entityType/ScholarlyWork" />
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/title">
|
||||
<epdcx:valueString>
|
||||
Attempts to detect retrotransposition
|
||||
and de novo deletion of Alus and other
|
||||
dispersed repeats at specific loci in
|
||||
the human genome
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/terms/abstract">
|
||||
<epdcx:valueString>
|
||||
Dispersed repeat elements contribute to
|
||||
genome instability by de novo insertion
|
||||
and unequal recombination between
|
||||
repeats. To study the dynamics of these
|
||||
processes, we have developed single DNA
|
||||
molecule approaches to detect de novo
|
||||
insertions at a single locus and
|
||||
Alu-mediated deletions at two different
|
||||
loci in human genomic DNA. Validation
|
||||
experiments showed these approaches
|
||||
could detect insertions and deletions at
|
||||
frequencies below 10(-6) per cell.
|
||||
However, bulk analysis of germline
|
||||
(sperm) and somatic DNA showed no
|
||||
evidence for genuine mutant molecules,
|
||||
placing an upper limit of insertion and
|
||||
deletion rates of 2 x 10(-7) and 3 x
|
||||
10(-7), respectively, in the individuals
|
||||
tested. Such re-arrangements at these
|
||||
loci therefore occur at a rate lower
|
||||
than that detectable by the most
|
||||
sensitive methods currently available.
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/creator">
|
||||
<epdcx:valueString>
|
||||
Hollies, C.R.
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/creator">
|
||||
<epdcx:valueString>
|
||||
Monckton, D.G.
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/creator">
|
||||
<epdcx:valueString>
|
||||
Jeffreys, A.J.
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/identifier">
|
||||
<epdcx:valueString
|
||||
epdcx:sesURI="http://purl.org/dc/terms/URI">
|
||||
http://www.myu.ac.uk/some/identifier
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/eprint/terms/isExpressedAs"
|
||||
epdcx:valueRef="sword-mets-expr-1" />
|
||||
</epdcx:description>
|
||||
|
||||
<epdcx:description
|
||||
epdcx:resourceId="sword-mets-expr-1">
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/type"
|
||||
epdcx:valueURI="http://purl.org/eprint/entityType/Expression" />
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/language"
|
||||
epdcx:vesURI="http://purl.org/dc/terms/RFC3066">
|
||||
<epdcx:valueString>en</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/elements/1.1/type"
|
||||
epdcx:vesURI="http://purl.org/eprint/terms/Type"
|
||||
epdcx:valueURI="http://purl.org/eprint/type/JournalArticle" />
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/dc/terms/available">
|
||||
<epdcx:valueString
|
||||
epdcx:sesURI="http://purl.org/dc/terms/W3CDTF">
|
||||
2001-02
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/eprint/terms/status"
|
||||
epdcx:vesURI="http://purl.org/eprint/terms/Status"
|
||||
epdcx:valueURI="http://purl.org/eprint/status/PeerReviewed" />
|
||||
<epdcx:statement
|
||||
epdcx:propertyURI="http://purl.org/eprint/terms/copyrightHolder">
|
||||
<epdcx:valueString>
|
||||
Nature Publishing Group
|
||||
</epdcx:valueString>
|
||||
</epdcx:statement>
|
||||
</epdcx:description>
|
||||
</epdcx:descriptionSet>
|
||||
</xmlData>
|
||||
</mdWrap>
|
||||
</dmdSec>
|
||||
|
||||
<fileSec>
|
||||
<fileGrp ID="sword-mets-fgrp-1" USE="CONTENT">
|
||||
<file GROUPID="sword-mets-fgid-0" ID="sword-mets-file-1"
|
||||
MIMETYPE="application/pdf">
|
||||
<FLocat LOCTYPE="URL" xlink:href="pdf1.pdf" />
|
||||
</file>
|
||||
<file GROUPID="sword-mets-fgid-1" ID="sword-mets-file-2"
|
||||
MIMETYPE="application/pdf">
|
||||
<FLocat LOCTYPE="URL" xlink:href="pdf2.pdf" />
|
||||
</file>
|
||||
<file GROUPID="sword-mets-fgid-2" ID="sword-mets-file-3"
|
||||
MIMETYPE="application/pdf">
|
||||
<FLocat LOCTYPE="URL" xlink:href="pdf3.pdf" />
|
||||
</file>
|
||||
</fileGrp>
|
||||
</fileSec>
|
||||
|
||||
<structMap ID="sword-mets-struct-1" LABEL="structure"
|
||||
TYPE="LOGICAL">
|
||||
<div ID="sword-mets-div-1" DMDID="sword-mets-dmd-1" TYPE="SWORD Object">
|
||||
<div ID="sword-mets-div-2" TYPE="File">
|
||||
<fptr FILEID="sword-mets-file-1" />
|
||||
</div>
|
||||
<div ID="sword-mets-div-3" TYPE="File">
|
||||
<fptr FILEID="sword-mets-file-2" />
|
||||
</div>
|
||||
<div ID="sword-mets-div-4" TYPE="File">
|
||||
<fptr FILEID="sword-mets-file-3" />
|
||||
</div>
|
||||
</div>
|
||||
</structMap>
|
||||
|
||||
</mets>
|
BIN
dspace-sword/example/pdf1.pdf
Normal file
BIN
dspace-sword/example/pdf1.pdf
Normal file
Binary file not shown.
BIN
dspace-sword/example/pdf2.pdf
Normal file
BIN
dspace-sword/example/pdf2.pdf
Normal file
Binary file not shown.
BIN
dspace-sword/example/pdf3.pdf
Normal file
BIN
dspace-sword/example/pdf3.pdf
Normal file
Binary file not shown.
79
dspace-sword/pom.xml
Normal file
79
dspace-sword/pom.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>DSpace SWORD</name>
|
||||
<description>DSpace SWORD Deposit Service Provider Web Application</description>
|
||||
<url>http://www.ukoln.ac.uk/repositories/digirep/index/SWORD</url>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Snapshot Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>maven.dspace.org/snapshot</id>
|
||||
<name>DSpace Maven Repository</name>
|
||||
<url>http://maven.dspace.org/snapshot</url>
|
||||
<releases>
|
||||
<updatePolicy>never</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<updatePolicy>always</updatePolicy>
|
||||
<checksumPolicy>fail</checksumPolicy>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>
|
||||
scm:svn:http://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword
|
||||
</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://dspace.svn.sourceforge.net/svnroot/dspace/branches/dspace-1_5_x/dspace-sword
|
||||
</developerConnection>
|
||||
<url>
|
||||
http://dspace.svn.sourceforge.net/viewvc/dspace/branches/dspace-1_5_x/dspace-sword
|
||||
</url>
|
||||
</scm>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>dspace-sword-api</module>
|
||||
<module>dspace-sword-webapp</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
144
dspace/config/crosswalks/sword-swap-ingest.xsl
Normal file
144
dspace/config/crosswalks/sword-swap-ingest.xsl
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- sord-swap-ingest.xsl
|
||||
*
|
||||
* Copyright (c) 2007, Aberystwyth University
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* - Neither the name of the Centre for Advanced Software and
|
||||
* Intelligent Systems (CASIS) nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
-->
|
||||
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:dim="http://www.dspace.org/xmlns/dspace/dim"
|
||||
xmlns:epdcx="http://purl.org/eprint/epdcx/2006-11-16/"
|
||||
version="1.0">
|
||||
|
||||
<!-- NOTE: This stylesheet is a work in progress, and does not
|
||||
cover all aspects of the SWAP and EPDCX specification/schema.
|
||||
It is used principally to demonstrate the SWORD ingest
|
||||
process -->
|
||||
|
||||
<!-- This stylesheet converts incoming DC metadata in a SWAP
|
||||
profile into the DSpace Interal Metadata format (DIM) -->
|
||||
|
||||
<!-- Catch all. This template will ensure that nothing
|
||||
other than explicitly what we want to xwalk will be dealt
|
||||
with -->
|
||||
<xsl:template match="text()"></xsl:template>
|
||||
|
||||
<!-- match the top level descriptionSet element and kick off the
|
||||
template matching process -->
|
||||
<xsl:template match="/epdcx:descriptionSet">
|
||||
<dim:dim>
|
||||
<xsl:apply-templates/>
|
||||
</dim:dim>
|
||||
</xsl:template>
|
||||
|
||||
<!-- general matcher for all "statement" elements -->
|
||||
<xsl:template match="/epdcx:descriptionSet/epdcx:description/epdcx:statement">
|
||||
|
||||
<!-- title element: dc.title -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/elements/1.1/title'">
|
||||
<dim:field mdschema="dc" element="title">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
<!-- abstract element: dc.description.abstract -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/terms/abstract'">
|
||||
<dim:field mdschema="dc" element="description" qualifier="abstract">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
<!-- creator element: dc.contributor.author -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/elements/1.1/creator'">
|
||||
<dim:field mdschema="dc" element="contributor" qualifier="author">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
<!-- identifier element: dc.identifier.* -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/elements/1.1/identifier'">
|
||||
<xsl:element name="dim:field">
|
||||
<xsl:attribute name="mdschema">dc</xsl:attribute>
|
||||
<xsl:attribute name="element">identifier</xsl:attribute>
|
||||
<xsl:if test="epdcx:valueString[epdcx:sesURI]='http://purl.org/dc/terms/URI'">
|
||||
<xsl:attribute name="qualifier">uri</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
|
||||
<!-- language element: dc.language.iso -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/elements/1.1/language' and ./@epdcx:vesURI='http://purl.org/dc/terms/RFC3066'">
|
||||
<dim:field mdschema="dc" element="language" qualifier="rfc3066">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
<!-- item type element: dc.type -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/elements/1.1/type' and ./@epdcx:vesURI='http://purl.org/eprint/terms/Type'">
|
||||
<xsl:if test="./@epdcx:valueURI='http://purl.org/eprint/type/JournalArticle'">
|
||||
<dim:field mdschema="dc" element="type">
|
||||
Journal Article
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
|
||||
<!-- date available element: dc.date.issued -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/dc/terms/available'">
|
||||
<dim:field mdschema="dc" element="date" qualifier="issued">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
<!-- publication status element: dc.description.version -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/eprint/terms/status' and ./@epdcx:vesURI='http://purl.org/eprint/terms/Status'">
|
||||
<xsl:if test="./@epdcx:valueURI='http://purl.org/eprint/status/PeerReviewed'">
|
||||
<dim:field mdschema="dc" element="description" qualifier="version">
|
||||
Peer Reviewed
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
|
||||
<!-- copyright holder element: dc.rights.holder -->
|
||||
<xsl:if test="./@epdcx:propertyURI='http://purl.org/eprint/terms/copyrightHolder'">
|
||||
<dim:field mdschema="dc" element="rights" qualifier="holder">
|
||||
<xsl:value-of select="epdcx:valueString"/>
|
||||
</dim:field>
|
||||
</xsl:if>
|
||||
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
@@ -1068,3 +1068,58 @@ event.consumer.eperson.filters = EPerson+Create
|
||||
#xmlui.bitstream.mets = true
|
||||
|
||||
|
||||
#####################################################################
|
||||
# SWORD Configuration
|
||||
#####################################################################
|
||||
#
|
||||
# tell the SWORD METS implementation which package ingester to use
|
||||
# to install deposited content. This should refer to one of the
|
||||
# classes configured for:
|
||||
#
|
||||
# plugin.named.org.dspace.content.packager.PackageIngester
|
||||
#
|
||||
# The value of sword.mets-ingester.package-ingester tells the
|
||||
# system which named plugin for this interface should be used
|
||||
# to ingest SWORD METS packages
|
||||
#
|
||||
# The default is METS
|
||||
#
|
||||
# sword.mets-ingester.package-ingester = METS
|
||||
|
||||
# Define the metadata type EPDCX (EPrints DC XML)
|
||||
# to be handled by the SWORD crosswalk configuration
|
||||
#
|
||||
mets.submission.crosswalk.EPDCX = SWORD
|
||||
|
||||
# define the stylesheet which will be used by the self-named
|
||||
# XSLTIngestionCrosswalk class when asked to load the SWORD
|
||||
# configuration (as specified above). This will use the
|
||||
# specified stylesheet to crosswalk the incoming SWAP metadata
|
||||
# to the DIM format for ingestion
|
||||
#
|
||||
crosswalk.submission.SWORD.stylesheet = crosswalks/sword-swap-ingest.xsl
|
||||
|
||||
# The base URL of the SWORD deposit. This is the URL from
|
||||
# which DSpace will construct the deposit location urls for
|
||||
# collections.
|
||||
#
|
||||
# The default is {dspace.url}/dspace-sword/deposit
|
||||
#
|
||||
# In the event that you are not deploying DSpace as the ROOT
|
||||
# application in the servlet container, this will generate
|
||||
# incorrect URLs, and you should override the functionality
|
||||
# by specifying in full as below:
|
||||
#
|
||||
# sword.deposit.url = http://www.myu.ac.uk/dspace-sword/deposit
|
||||
|
||||
# The metadata field in which to store the updated date for
|
||||
# items deposited via SWORD.
|
||||
#
|
||||
sword.updated.field = dc.date.updated
|
||||
|
||||
# The metadata field in which to store the value of the slug
|
||||
# header if it is supplied
|
||||
#
|
||||
sword.slug.field = dc.identifier.slug
|
||||
|
||||
#####################################################################
|
@@ -212,6 +212,54 @@
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<!--
|
||||
Builds SWORD WAR for DSpace
|
||||
-->
|
||||
<profile>
|
||||
|
||||
<id>sword-api</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>../dspace-sword-api/pom.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>../dspace-sword-api</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<!--
|
||||
Builds SWORD WAR for DSpace
|
||||
-->
|
||||
<profile>
|
||||
|
||||
<id>sword-webapp</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>../dspace-sword-webapp/pom.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>../dspace-sword-webapp</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<!--
|
||||
Builds SWORD WAR for DSpace
|
||||
-->
|
||||
<profile>
|
||||
|
||||
<id>sword</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>../dspace-sword/pom.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>../dspace-sword</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
<!--
|
||||
Builds each separate XMLUI module for the XMLUI war (for development/Eclipse)
|
||||
-->
|
||||
|
@@ -226,7 +226,7 @@ Common usage:
|
||||
UI web applications from ${dspace.dir}/webapps/, then you
|
||||
can jump straight to restarting your Web servlet container
|
||||
|
||||
* Otherwise, you will need to copy any web applications from
|
||||
* Otherwise, you will need to copy any web applications from
|
||||
${dspace.dir}/webapps/ to the appropriate place for your servlet
|
||||
container. (e.g. '$CATALINA_HOME/webapps' for Tomcat)
|
||||
|
||||
@@ -364,8 +364,17 @@ Common usage:
|
||||
<sysproperty key="dspace.configuration" value="${config}"/>
|
||||
<arg line="-f ${dspace.dir}/config/registries/dublin-core-types.xml"/>
|
||||
</java>
|
||||
|
||||
</target>
|
||||
|
||||
<!-- FIXME: this should be more modular -->
|
||||
<!-- import the SWORD required metadata -->
|
||||
<java classname="org.dspace.administer.MetadataImporter" classpathref="class.path" fork="yes" failonerror="yes">
|
||||
<sysproperty key="log4j.configuration" value="file:config/log4j-console.properties"/>
|
||||
<sysproperty key="dspace.log.init.disable" value="true"/>
|
||||
<sysproperty key="dspace.configuration" value="${config}"/>
|
||||
<arg line="-f ${dspace.dir}/config/registries/sword-metadata.xml"/>
|
||||
</java>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<!-- ============================================================= -->
|
||||
|
11
pom.xml
11
pom.xml
@@ -21,6 +21,7 @@
|
||||
<module>dspace-xmlui</module>
|
||||
<module>dspace-lni</module>
|
||||
<module>dspace-oai</module>
|
||||
<module>dspace-sword</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
@@ -135,6 +136,16 @@
|
||||
<artifactId>language-packs</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-jspui-api</artifactId>
|
||||
|
Reference in New Issue
Block a user