[DS-602] Move Sword Client module to trunk

git-svn-id: http://scm.dspace.org/svn/repo/dspace/trunk@6533 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Robin Taylor
2011-08-07 11:19:38 +00:00
parent e7efc9c689
commit 527fcc7b16
27 changed files with 2233 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?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>
<packaging>jar</packaging>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-api</artifactId>
<version>1.8.0-SNAPSHOT</version>
<name>DSpace Sword Client :: Sword Client API</name>
<parent>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client</artifactId>
<version>1.8.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-api</artifactId>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-api</artifactId>
</dependency>
</dependencies>
<!--
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://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-api</connection>
<developerConnection>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-api
</developerConnection>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-api</url>
</scm>
</project>

View File

@@ -0,0 +1,234 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.content.DSpaceObject;
import org.dspace.content.packager.PackageDisseminator;
import org.dspace.content.packager.PackageParameters;
import org.dspace.core.Context;
import org.dspace.core.PluginManager;
import org.dspace.handle.HandleManager;
import org.dspace.sword.client.exceptions.HttpException;
import org.dspace.sword.client.exceptions.InvalidHandleException;
import org.dspace.sword.client.exceptions.PackageFormatException;
import org.dspace.sword.client.exceptions.PackagerException;
import org.purl.sword.base.DepositResponse;
import org.purl.sword.base.SWORDEntry;
import org.purl.sword.base.ServiceDocument;
import org.purl.sword.client.Client;
import org.purl.sword.client.PostMessage;
import org.purl.sword.client.SWORDClientException;
import org.purl.sword.client.Status;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.UUID;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class DSpaceSwordClient
{
private Client client;
private PostMessage message;
private String onBehalfOf;
private String serviceDocUrl;
private String filename;
private String tempDirectory;
private String packageFormat;
private PackageParameters pkgParams;
private static Logger log = Logger.getLogger(DSpaceSwordClient.class);
public DSpaceSwordClient()
{
client = new Client();
// The default timeout is way too low so increase it x10.
client.setSocketTimeout(200000);
client.setUserAgent("DSpace Sword Client");
message = new PostMessage();
message.setUseMD5(false);
message.setChecksumError(false);
message.setVerbose(false);
message.setNoOp(false);
message.setUserAgent("DSpace Sword Client");
setFilename();
}
public void setFilename()
{
if ((tempDirectory == null) || (tempDirectory.equals("")))
{
tempDirectory = System.getProperty("java.io.tmpdir");
}
if (!tempDirectory.endsWith(System.getProperty("file.separator")))
{
tempDirectory += System.getProperty("file.separator");
}
filename = tempDirectory + UUID.randomUUID().toString();
}
public void setRemoteServer(String chosenUrl) throws MalformedURLException
{
serviceDocUrl = chosenUrl;
URL url = new URL(chosenUrl);
client.setServer(url.getHost(), url.getPort());
}
public void setCredentials(String username, String password, String onBehalfOf)
{
client.setCredentials(username, password);
this.onBehalfOf = onBehalfOf;
}
public ServiceDocument getServiceDocument() throws HttpException, SWORDClientException
{
log.info("Getting Sword Service Document from " + serviceDocUrl);
ServiceDocument sd = client.getServiceDocument(serviceDocUrl, onBehalfOf);
Status status = client.getStatus();
if (status.getCode() == 200)
{
log.info("Sword Service Document successfully retrieved from " + serviceDocUrl);
return sd;
}
else
{
log.info("Error retrieving Sword Service Document from " + serviceDocUrl);
throw new HttpException("No service document available - Http status code " + status);
}
}
public void setCollection(String destination)
{
message.setDestination(destination);
}
public void setFileType(String fileType)
{
message.setFiletype(fileType);
}
public void setPackageFormat(String packageFormat) throws PackageFormatException
{
// todo : Read all this stuff from config
if (packageFormat.equals("http://purl.org/net/sword-types/METSDSpaceSIP"))
{
this.packageFormat = "METS";
pkgParams = new PackageParameters();
pkgParams.addProperty("dmd", "MODS");
message.setFormatNamespace("http://purl.org/net/sword-types/METSDSpaceSIP");
}
else
{
throw new PackageFormatException("Invalid package format selected");
}
}
public void deposit(Context context, String handle) throws InvalidHandleException, PackagerException, SWORDClientException, PackageFormatException, HttpException
{
File file = new File(filename);
createPackage(context, handle, file);
sendMessage();
}
/**
* Create the package and write it to disk.
*/
public void createPackage(Context context, String handle, File file) throws InvalidHandleException, PackagerException, PackageFormatException
{
// Note - in the future we may need to allow for more than zipped up packages.
PackageDisseminator dip = (PackageDisseminator) PluginManager
.getNamedPlugin(PackageDisseminator.class, packageFormat);
if (dip == null)
{
log.error("Error - unknown package type " + packageFormat);
throw new PackageFormatException("Unknown package type " + packageFormat);
}
DSpaceObject dso = null;
try
{
dso = HandleManager.resolveToObject(context, handle);
}
catch (SQLException e)
{
log.error("Unable to resolve handle " + handle);
throw new InvalidHandleException("Unable to resolve handle " + handle);
}
if (dso == null)
{
log.error("Unable to resolve handle " + handle);
throw new InvalidHandleException("Unable to resolve handle " + handle);
}
try
{
dip.disseminate(context, dso, pkgParams, file);
}
catch (Exception e)
{
log.error("Error creating package", e);
throw new PackagerException("Error creating package", e);
}
}
/**
* Reads the file, probably a zipped package, and sends it to the Sword server.
*
* @return A unique ID returned by a successful deposit
* @throws org.purl.sword.client.SWORDClientException
*
*/
public String sendMessage() throws SWORDClientException, HttpException
{
message.setFilepath(filename);
DepositResponse resp = client.postFile(message);
Status status = client.getStatus();
if ((status.getCode() == 201) || (status.getCode() == 202))
{
SWORDEntry se = resp.getEntry();
return se.getId();
}
else
{
String error = status.getCode() + " " + status.getMessage() + " - " + resp.getEntry().getSummary().getContent();
log.info("Error depositing Sword package : " + error);
throw new HttpException(error);
}
}
}

View File

@@ -0,0 +1,111 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client;
import org.dspace.core.ConfigurationManager;
import org.purl.sword.base.Collection;
import org.purl.sword.base.ServiceDocument;
import org.purl.sword.base.SwordAcceptPackaging;
import org.purl.sword.base.Workspace;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class ServiceDocumentHelper {
public static List<Collection> getCollections(ServiceDocument serviceDoc)
{
List<Collection> allCollections = new ArrayList<Collection>();
List<Workspace> workspaces = serviceDoc.getService().getWorkspacesList();
for (Workspace ws : workspaces)
{
List<Collection> collections = ws.getCollections();
allCollections.addAll(collections);
}
return allCollections;
}
public static Collection getCollection(ServiceDocument serviceDoc, String location)
{
List<Collection> allCollections = getCollections(serviceDoc);
for (Collection collection : allCollections)
{
if (collection.getLocation().equals(location))
{
return collection;
}
}
// If we got here then we didn't find a match.
return null;
}
public static String[] getCommonFileTypes(ServiceDocument serviceDoc, String location)
{
String FTsString = ConfigurationManager.getProperty("sword-client", "sword-client.file-types");
String[] clientFTsArray = FTsString.split(",");
List<String> clientFTs = Arrays.asList(clientFTsArray);
List<String> commonFTs = new ArrayList<String>();
Collection collection = ServiceDocumentHelper.getCollection(serviceDoc, location);
String[] serverFTs = collection.getAccepts();
for (String serverFT : serverFTs)
{
if (clientFTs.contains(serverFT))
{
commonFTs.add(serverFT);
}
}
return commonFTs.toArray(new String[commonFTs.size()]);
}
public static String[] getCommonPackageFormats(ServiceDocument serviceDoc, String location)
{
String PFsString = ConfigurationManager.getProperty("sword-client", "sword-client.package-formats");
String[] clientPFsArray = PFsString.split(",");
List<String> clientPFs = Arrays.asList(clientPFsArray);
List<String> commonPFs = new ArrayList<String>();
Collection collection = ServiceDocumentHelper.getCollection(serviceDoc, location);
List<SwordAcceptPackaging> serverPFs = collection.getAcceptPackaging();
for (SwordAcceptPackaging serverPF : serverPFs)
{
if (clientPFs.contains(serverPF.getContent()))
{
commonPFs.add(serverPF.getContent());
}
}
return commonPFs.toArray(new String[commonPFs.size()]);
}
public static String[] getPackageFormats(Collection collection)
{
List<String> packageFormats = new ArrayList<String>();
List<SwordAcceptPackaging> pfs = collection.getAcceptPackaging();
for (SwordAcceptPackaging pf : pfs)
{
packageFormats.add(pf.getContent());
}
return packageFormats.toArray(new String[pfs.size()]);
}
}

View File

@@ -0,0 +1,40 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client.exceptions;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class HttpException extends Exception
{
public HttpException()
{
super();
}
public HttpException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public HttpException(String arg0)
{
super(arg0);
}
public HttpException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -0,0 +1,40 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client.exceptions;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class InvalidHandleException extends Exception
{
public InvalidHandleException()
{
super();
}
public InvalidHandleException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public InvalidHandleException(String arg0)
{
super(arg0);
}
public InvalidHandleException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -0,0 +1,40 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client.exceptions;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class PackageFormatException extends Exception
{
public PackageFormatException()
{
super();
}
public PackageFormatException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public PackageFormatException(String arg0)
{
super(arg0);
}
public PackageFormatException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -0,0 +1,40 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.sword.client.exceptions;
/**
* User: Robin Taylor
* Date: 15/02/11
* Time: 21:12
*/
public class PackagerException extends Exception
{
public PackagerException()
{
super();
}
public PackagerException(String arg0, Throwable arg1)
{
super(arg0, arg1);
}
public PackagerException(String arg0)
{
super(arg0);
}
public PackagerException(Throwable arg0)
{
super(arg0);
}
}

View File

@@ -0,0 +1,60 @@
<?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>
<packaging>jar</packaging>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-xmlui-api</artifactId>
<version>1.8.0-SNAPSHOT</version>
<name>DSpace Sword Client :: Sword Client XMLUI API</name>
<parent>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client</artifactId>
<version>1.8.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-xmlui-api</artifactId>
<exclusions>
<exclusion>
<artifactId>solr-solrj</artifactId>
<groupId>org.apache.solr</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- external -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-api</artifactId>
<version>1.8.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!--
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://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-api
</connection>
<developerConnection>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-api
</developerConnection>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-api</url>
</scm>
</project>

View File

@@ -0,0 +1,83 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.aspect.administrative.FlowResult;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.core.Context;
import org.dspace.sword.client.*;
import org.dspace.sword.client.exceptions.HttpException;
import org.dspace.sword.client.exceptions.InvalidHandleException;
import org.dspace.sword.client.exceptions.PackageFormatException;
import org.dspace.sword.client.exceptions.PackagerException;
import org.purl.sword.client.SWORDClientException;
/**
* User: Robin Taylor
* Date: 27/03/11
* Time: 15:47
*/
public class DepositAction {
private static final Message T_success = new Message("default", "xmlui.swordclient.DepositAction.success");
private static final Message T_package_format_error = new Message("default", "xmlui.swordclient.DepositAction.package_format_error");
private static final Message T_invalid_handle = new Message("default", "xmlui.swordclient.DepositAction.invalid_handle");
private static final Message T_package_error = new Message("default", "xmlui.swordclient.DepositAction.package_error");
private static final Message T_error = new Message("default", "xmlui.swordclient.DepositAction.error");
private static Logger log = Logger.getLogger(DepositAction.class);
public FlowResult processDeposit(Context context, String handle, DSpaceSwordClient DSClient)
{
FlowResult result = new FlowResult();
result.setContinue(false);
try
{
DSClient.deposit(context, handle);
result.setContinue(true);
result.setOutcome(true);
result.setMessage(T_success);
}
catch (PackageFormatException e)
{
log.error("Package Format Exception", e);
result.setOutcome(false);
result.setMessage(T_package_format_error);
}
catch (InvalidHandleException e)
{
log.error("Invalid handle Exception", e);
result.setOutcome(false);
result.setMessage(T_invalid_handle);
}
catch (PackagerException e)
{
log.error("Packager Exception", e);
result.setOutcome(false);
result.setMessage(T_package_error);
}
catch (SWORDClientException e)
{
log.error("SWORDClientException encountered " + e.getMessage(), e);
result.setOutcome(false);
result.setMessage(T_error.parameterize(e.getMessage()));
}
catch (HttpException e)
{
log.error("HttpException encountered " + e.getMessage(), e);
result.setOutcome(false);
result.setMessage(T_error.parameterize(e.getMessage()));
}
return result;
}
}

View File

@@ -0,0 +1,84 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.excalibur.source.SourceValidity;
import org.apache.excalibur.source.impl.validity.NOPValidity;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.utils.HandleUtil;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.List;
import org.dspace.app.xmlui.wing.element.Options;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.AuthorizeManager;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
public class Navigation extends AbstractDSpaceTransformer implements CacheableProcessingComponent
{
private static final Message T_context_swordclient_head = message("xmlui.swordclient.Navigation.context_head");
private static final Message T_swordclient_copy = message("xmlui.swordclient.Navigation.context_copy");
/** Cached validity object */
private SourceValidity validity;
/**
* Generate the unique caching key.
* This key must be unique inside the space of this component.
*/
public Serializable getKey() {
return 1;
}
/**
* Generate the cache validity object.
*
* The cache is always valid.
*/
public SourceValidity getValidity() {
return NOPValidity.SHARED_INSTANCE;
}
public void addOptions(Options options) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException
{
// todo : Some other navigation classes seem to add skeleton lists. I haven't done so here as
// todo : I don't understand what they do.
List context = options.addList("context");
// Context Administrative options
DSpaceObject dso = HandleUtil.obtainHandle(objectModel);
if (dso instanceof Item)
{
Item item = (Item) dso;
if (AuthorizeManager.isAdmin(this.context, dso))
{
context.setHead(T_context_swordclient_head);
context.addItemXref(contextPath + "/swordclient?itemID="+item.getID(), T_swordclient_copy);
}
}
}
}

View File

@@ -0,0 +1,59 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.Request;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.aspect.administrative.FlowResult;
import org.dspace.core.Context;
import org.dspace.sword.client.DSpaceSwordClient;
import org.dspace.sword.client.ServiceDocumentHelper;
import org.purl.sword.base.Collection;
import org.purl.sword.base.ServiceDocument;
/**
* User: Robin Taylor
* Date: 21/03/11
* Time: 22:12
*/
public class SelectCollectionAction
{
private static Logger log = Logger.getLogger(SelectCollectionAction.class);
public FlowResult processSelectCollection(Context context, Request request, DSpaceSwordClient DSClient)
{
FlowResult result = new FlowResult();
result.setContinue(false);
// Get all our request parameters
String location = request.getParameter("location");
ServiceDocument serviceDoc = (ServiceDocument) request.getAttribute("serviceDoc");
log.info("Collection selected is " + location);
log.info("Service Doc reference is " + serviceDoc);
// Set the target collection.
DSClient.setCollection(location);
//Collection collection = ServiceDocumentHelper.getCollection(serviceDoc, location);
// Find out what file types and package formats are available and return them to let the user select.
String[] fileTypes = ServiceDocumentHelper.getCommonFileTypes(serviceDoc, location);
String[] packageFormats = ServiceDocumentHelper.getCommonPackageFormats(serviceDoc, location);
result.setParameter("location", location);
result.setParameter("serviceDoc", serviceDoc);
result.setParameter("fileTypes", fileTypes);
result.setParameter("packageFormats", packageFormats);
result.setContinue(true);
result.setOutcome(true);
return result;
}
}

View File

@@ -0,0 +1,149 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.*;
import org.dspace.authorize.AuthorizeException;
import org.dspace.sword.client.ServiceDocumentHelper;
import org.purl.sword.base.Collection;
import org.purl.sword.base.ServiceDocument;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.sql.SQLException;
/**
* User: Robin Taylor
* Date: 21-Sep-2010
* Time: 13:44:28
*/
public class SelectCollectionTransformer extends AbstractDSpaceTransformer {
private static Logger log = Logger.getLogger(SelectCollectionTransformer.class);
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
private static final Message T_title = message("xmlui.swordclient.SelectCollection.title");
private static final Message T_SwordCopy_trail = message("xmlui.swordclient.general.SwordCopy_trail");
private static final Message T_trail = message("xmlui.swordclient.SelectCollection.trail");
private static final Message T_main_head = message("xmlui.swordclient.general.main_head");
private static final Message T_collection_head = message("xmlui.swordclient.SelectCollection.collection_head");
private static final Message T_collection_title = message("xmlui.swordclient.SelectCollection.collection_title");
private static final Message T_collection_policy = message("xmlui.swordclient.SelectCollection.collection policy");
private static final Message T_collection_mediation = message("xmlui.swordclient.SelectCollection.collection_mediation");
private static final Message T_collection_file_types = message("xmlui.swordclient.SelectCollection.collection_file_types");
private static final Message T_collection_package_formats = message("xmlui.swordclient.SelectCollection.collection_package_formats");
private static final Message T_collection_deposit_button = message("xmlui.swordclient.SelectCollection.collection_deposit_button");
private static final Message T_sub_service_target = message("xmlui.swordclient.SelectCollection.sub_service_target");
private static final Message T_sub_service_target_button = message("xmlui.swordclient.SelectCollection.sub_service_target_button");
private static final Message T_submit_cancel = message("xmlui.general.cancel");
/**
* Add a page title and trail links
*/
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
pageMeta.addMetadata("title").addContent(T_title);
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
pageMeta.addTrail().addContent(T_SwordCopy_trail);
pageMeta.addTrail().addContent(T_trail);
}
public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
String handle = parameters.getParameter("handle", null);
Division main = body.addInteractiveDivision("servicedocument-target", contextPath + "/swordclient", Division.METHOD_POST, "");
main.setHead(T_main_head.parameterize(handle));
Request request = ObjectModelHelper.getRequest(objectModel);
ServiceDocument serviceDoc = (ServiceDocument) request.getAttribute("serviceDoc");
java.util.List<Collection> collections = ServiceDocumentHelper.getCollections(serviceDoc);
List collectionsList = main.addList("collectionsList", List.TYPE_SIMPLE);
for (Collection collection : collections)
{
// Now we need another list for the individual collection, each of which encompasses a form.
List collectionList = collectionsList.addList(collection + "List", List.TYPE_FORM);
// Add a header to each individual collection List.
collectionList.setHead(T_collection_head.parameterize(collection.getLocation()));
// Now add another list of the remaining collection parameters.
List paramsList = collectionList.addList(collection + "Params", List.TYPE_BULLETED);
paramsList.addItem().addContent(T_collection_title.parameterize(collection.getTitle()));
paramsList.addItem().addContent(T_collection_policy.parameterize(collection.getCollectionPolicy()));
paramsList.addItem().addContent(T_collection_mediation.parameterize(Boolean.toString(collection.getMediation())));
String[] fileTypes = collection.getAccepts();
String fileTypesString = arrayToString(fileTypes);
paramsList.addItem().addContent(T_collection_file_types.parameterize(fileTypesString));
String[] packageFormats = ServiceDocumentHelper.getPackageFormats(collection);
String packageFormatsString = arrayToString(packageFormats);
paramsList.addItem().addContent(T_collection_package_formats.parameterize(packageFormatsString));
// Assuming there are available file types and package formats then add a deposit button.
if ((fileTypes.length > 0 ) && (packageFormats.length > 0))
{
collectionList.addItem().addHidden("location").setValue(collection.getLocation());
collectionList.addItem().addButton("deposit").setValue(T_collection_deposit_button);
}
// If the collection contains a reference to a 'sub service' then allow the user to select
// the service doc for that sub service.
if ((collection.getService() != null) && (collection.getService().length() > 0))
{
collectionList.addItem().addContent(T_sub_service_target + collection.getService());
collectionList.addItem().addHidden("sub-service").setValue(collection.getService());
collectionList.addItem().addButton("sub-service").setValue(T_sub_service_target_button);
}
}
Para buttonList = main.addPara();
buttonList.addButton("submit_cancel").setValue(T_submit_cancel);
main.addHidden("swordclient-continue").setValue(knot.getId());
}
private String arrayToString(String[] strings)
{
if (strings.length == 0)
{
return "none";
}
else
{
StringBuffer text = new StringBuffer("");
for (String string : strings)
{
text.append(string).append(", ");
}
text.delete(text.length() - 2, text.length() - 1);
return text.toString();
}
}
}

View File

@@ -0,0 +1,54 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.Request;
import org.dspace.app.xmlui.aspect.administrative.FlowResult;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.core.Context;
import org.dspace.sword.client.DSpaceSwordClient;
import org.dspace.sword.client.exceptions.PackageFormatException;
/**
* User: Robin Taylor
* Date: 21/03/11
* Time: 22:12
*/
public class SelectPackagingAction
{
private static final Message T_packageFormat_error = new Message("default", "xmlui.swordclient.SelectPackagingFormat.packageFormat_error");
public FlowResult processSelectPackaging(Context context, Request request, DSpaceSwordClient DSClient)
{
FlowResult result = new FlowResult();
result.setContinue(false);
// Get all our request parameters
String fileType = request.getParameter("fileType");
String packageFormat = request.getParameter("packageFormat");
DSClient.setFileType(fileType);
try
{
DSClient.setPackageFormat(packageFormat);
result.setContinue(true);
result.setOutcome(true);
}
catch (PackageFormatException e)
{
// This exception should never actually happen since the user selects from a drop down list but...
result.setOutcome(false);
result.setMessage(T_packageFormat_error);
}
return result;
}
}

View File

@@ -0,0 +1,107 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.*;
import org.dspace.authorize.AuthorizeException;
import org.dspace.sword.client.ServiceDocumentHelper;
import org.purl.sword.base.Collection;
import org.purl.sword.base.ServiceDocument;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.sql.SQLException;
/**
* User: Robin Taylor
* Date: 21-Sep-2010
* Time: 13:44:28
*/
public class SelectPackagingTransformer extends AbstractDSpaceTransformer
{
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
private static final Message T_title = message("xmlui.swordclient.SelectCollection.title");
private static final Message T_SwordCopy_trail = message("xmlui.swordclient.general.SwordCopy_trail");
private static final Message T_trail = message("xmlui.swordclient.SelectCollection.trail");
private static final Message T_main_head = message("xmlui.swordclient.general.main_head");
private static final Message T_collection_head = message("xmlui.swordclient.SelectPackagingAction.head");
private static final Message T_collection_title = message("xmlui.swordclient.SelectPackagingAction.title");
private static final Message T_collection_policy = message("xmlui.swordclient.SelectPackagingAction.policy");
private static final Message T_collection_mediation = message("xmlui.swordclient.SelectPackagingAction.mediation");
private static final Message T_collection_file_types = message("xmlui.swordclient.SelectPackagingAction.file_types");
private static final Message T_collection_package_formats = message("xmlui.swordclient.SelectPackagingAction.package_formats");
private static final Message T_submit_next = message("xmlui.general.next");
private static final Message T_submit_cancel = message("xmlui.general.cancel");
private static Logger log = Logger.getLogger(SelectPackagingTransformer.class);
/**
* Add a page title and trail links
*/
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
pageMeta.addMetadata("title").addContent(T_title);
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
pageMeta.addTrail().addContent(T_SwordCopy_trail);
pageMeta.addTrail().addContent(T_trail);
}
public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException {
String handle = parameters.getParameter("handle", null);
Request request = ObjectModelHelper.getRequest(objectModel);
ServiceDocument serviceDoc = (ServiceDocument) request.getAttribute("serviceDoc");
String location = (String) request.getAttribute("location");
String[] fileTypes = (String[]) request.getAttribute("fileTypes");
String[] packageFormats = (String[]) request.getAttribute("packageFormats");
Collection collection = ServiceDocumentHelper.getCollection(serviceDoc, location);
Division main = body.addInteractiveDivision("confirm-collection", contextPath + "/swordclient", Division.METHOD_POST, "");
main.setHead(T_main_head.parameterize(handle));
List collectionList = main.addList("collectionList", List.TYPE_FORM);
collectionList.setHead(T_collection_head.parameterize(location));
collectionList.addItem().addContent(T_collection_title.parameterize(collection.getTitle()));
collectionList.addItem().addContent(T_collection_policy.parameterize(collection.getCollectionPolicy()));
collectionList.addItem().addContent(T_collection_mediation.parameterize(Boolean.toString(collection.getMediation())));
Select fileType = collectionList.addItem().addSelect("fileType");
for (String ft : fileTypes) {
fileType.addOption(false, ft, ft);
}
fileType.setLabel(T_collection_file_types);
Select packageFormat = collectionList.addItem().addSelect("packageFormat");
for (String pf : packageFormats) {
packageFormat.addOption(false, pf, pf);
}
packageFormat.setLabel(T_collection_package_formats);
Para buttonList = main.addPara();
buttonList.addButton("submit_next").setValue(T_submit_next);
buttonList.addButton("submit_cancel").setValue(T_submit_cancel);
main.addHidden("swordclient-continue").setValue(knot.getId());
}
}

View File

@@ -0,0 +1,176 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.Request;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.aspect.administrative.FlowResult;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.core.Context;
import org.dspace.sword.client.exceptions.HttpException;
import org.dspace.sword.client.DSpaceSwordClient;
import org.purl.sword.base.ServiceDocument;
import org.purl.sword.client.SWORDClientException;
import java.net.MalformedURLException;
import java.net.URL;
/**
* User: Robin Taylor
* Date: 08/02/11
* Time: 21:41
*/
public class SelectTargetAction
{
private static final Message T_url_error = new Message("default", "xmlui.swordclient.SelectTargetAction.url_error");
private static final Message T_serviceDoc_error = new Message("default", "xmlui.swordclient.SelectTargetAction.serviceDoc_error");
private static Logger log = Logger.getLogger(SelectTargetAction.class);
public FlowResult processSelectTarget(Context context, Request request, DSpaceSwordClient DSClient)
{
FlowResult result = new FlowResult();
result.setContinue(false);
// Get all our request parameters
String url = request.getParameter("url").trim();
String otherUrl = request.getParameter("otherUrl").trim();
String username = request.getParameter("username").trim();
String password = request.getParameter("password").trim();
String onBehalfOf = request.getParameter("onBehalfOf").trim();
// If we have errors, the form needs to be resubmitted to fix those problems
String chosenUrl = "";
if (!StringUtils.isEmpty(otherUrl))
{
// If otherUrl has been entered then it will take precedence.
try
{
new URL(otherUrl);
chosenUrl = otherUrl;
}
catch (MalformedURLException e)
{
result.addError("otherUrl");
}
}
else
{
if (!StringUtils.isEmpty(url))
{
chosenUrl = url;
}
else
{
result.addError("url");
}
}
if (StringUtils.isEmpty(username))
{
result.addError("username");
}
if (StringUtils.isEmpty(password))
{
result.addError("password");
}
// No errors, the input parameters look healthy.
if (result.getErrors() == null)
{
try
{
DSClient.setRemoteServer(chosenUrl);
DSClient.setCredentials(username, password, onBehalfOf);
ServiceDocument serviceDoc = DSClient.getServiceDocument();
result.setParameter("serviceDoc", serviceDoc);
result.setContinue(true);
result.setOutcome(true);
}
catch (MalformedURLException e)
{
log.error("Malformed URL : " + chosenUrl);
result.setOutcome(false);
result.setMessage(T_url_error);
}
catch (HttpException e)
{
log.error("HttpException encountered", e);
result.setOutcome(false);
result.setMessage(T_serviceDoc_error.parameterize(e.getMessage()));
}
catch (SWORDClientException e)
{
log.error("SwordClientException : " + e.getMessage(), e);
result.setOutcome(false);
result.setMessage(T_serviceDoc_error.parameterize(e.getMessage()));
}
}
return result;
}
public FlowResult processSelectSubTarget(Context context, Request request, DSpaceSwordClient DSClient)
{
FlowResult result = new FlowResult();
result.setContinue(false);
// Get all our request parameters.
String url = request.getParameter("sub-service").trim();
log.info("target selected is : " + url);
if (StringUtils.isEmpty(url))
{
// Note : this shouldn't ever happen since the user doesn't enter it manually.
result.addError("sub-service");
}
// No errors, the input parameters look healthy.
if (result.getErrors() == null)
{
try
{
DSClient.setRemoteServer(url);
ServiceDocument serviceDoc = DSClient.getServiceDocument();
result.setParameter("serviceDoc", serviceDoc);
result.setOutcome(true);
}
catch (MalformedURLException e)
{
log.error("Malformed URL : " + url);
result.setOutcome(false);
result.setMessage(T_url_error);
}
catch (HttpException e)
{
log.error("HttpException encountered", e);
result.setOutcome(false);
result.setMessage(T_serviceDoc_error.parameterize(e.getMessage()));
}
catch (SWORDClientException e)
{
log.error("SwordClientException : " + e.getMessage(), e);
result.setOutcome(false);
result.setMessage(T_serviceDoc_error.parameterize(e.getMessage()));
}
}
return result;
}
}

View File

@@ -0,0 +1,150 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.*;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.ConfigurationManager;
import org.dspace.services.ConfigurationService;
import org.dspace.utils.DSpace;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
/**
* User: Robin Taylor
* Date: 21-Sep-2010
* Time: 13:44:28
*/
public class SelectTargetTransformer extends AbstractDSpaceTransformer
{
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
private static final Message T_title = message("xmlui.swordclient.SelectTarget.title");
private static final Message T_SwordCopy_trail = message("xmlui.swordclient.general.SwordCopy_trail");
private static final Message T_trail = message("xmlui.swordclient.SelectTarget.trail");
private static final Message T_main_head = message("xmlui.swordclient.general.main_head");
private static final Message T_submit_next = message("xmlui.general.next");
private static final Message T_submit_cancel = message("xmlui.general.cancel");
private static final Message T_url = message("xmlui.swordclient.SelectTarget.url");
private static final Message T_other_url = message("xmlui.swordclient.SelectTarget.other_url");
private static final Message T_username = message("xmlui.swordclient.SelectTarget.username");
private static final Message T_password = message("xmlui.swordclient.SelectTarget.password");
private static final Message T_on_behalf_of = message("xmlui.swordclient.SelectTarget.on_behalf_of");
private static final Message T_url_error = message("xmlui.swordclient.SelectTargetAction.url_error");
private static final Message T_username_error = message("xmlui.swordclient.SelectTargetAction.username_error");
private static final Message T_password_error = message("xmlui.swordclient.SelectTargetAction.password_error");
private static Logger log = Logger.getLogger(SelectTargetTransformer.class);
/**
* Add a page title and trail links
*/
public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException
{
pageMeta.addMetadata("title").addContent(T_title);
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
pageMeta.addTrail().addContent(T_SwordCopy_trail);
pageMeta.addTrail().addContent(T_trail);
}
public void addBody(Body body) throws SAXException, WingException, SQLException, IOException, AuthorizeException
{
Request request = ObjectModelHelper.getRequest(objectModel);
String handle = parameters.getParameter("handle", null);
String errorString = parameters.getParameter("errors",null);
ArrayList<String> errors = new ArrayList<String>();
if (!StringUtils.isEmpty(errorString))
{
for (String error : errorString.split(","))
{
errors.add(error);
}
}
// If this screen is being redisplayed then get the previously entered values.
String urlValue = request.getParameter("url");
String otherUrlValue = request.getParameter("otherUrl");
String usernameValue = request.getParameter("username");
String passwordValue = request.getParameter("password");
Division main = body.addInteractiveDivision("service-document", contextPath + "/swordclient", Division.METHOD_POST, "");
main.setHead(T_main_head.parameterize(handle));
List targetDetails = main.addList("target_details",List.TYPE_FORM);
Select source = targetDetails.addItem().addSelect("url");
String targetsString = ConfigurationManager.getProperty("sword-client", "sword-client.targets");
String[] targets = targetsString.split(",");
for (String target : targets)
{
if ((urlValue != null) && (urlValue.length() > 0) && (urlValue.equals(target)))
{
source.addOption(false, target, target);
}
else
{
source.addOption(false, target, target);
}
}
source.setLabel(T_url);
Text otherUrl = targetDetails.addItem().addText("otherUrl");
otherUrl.setLabel(T_other_url);
otherUrl.setValue(otherUrlValue);
if (errors.contains("otherUrl"))
{
otherUrl.addError(T_url_error);
}
Text username = targetDetails.addItem().addText("username");
username.setRequired();
username.setLabel(T_username);
username.setValue(usernameValue);
if (errors.contains("username"))
{
username.addError(T_username_error);
}
Password password = targetDetails.addItem().addPassword("password");
password.setRequired();
password.setLabel(T_password);
// Comment - Element Password doesn't allow me to set a value, don't know why not.
//password.setValue(passwordValue);
if (errors.contains("password"))
{
password.addError(T_password_error);
}
Text onBehalfOf = targetDetails.addItem().addText("onBehalfOf");
onBehalfOf.setLabel(T_on_behalf_of);
Para buttonList = main.addPara();
buttonList.addButton("submit_next").setValue(T_submit_next);
buttonList.addButton("submit_cancel").setValue(T_submit_cancel);
main.addHidden("swordclient-continue").setValue(knot.getId());
}
}

View File

@@ -0,0 +1,56 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.xmlui.aspect.swordclient;
import org.dspace.app.xmlui.cocoon.AbstractDSpaceTransformer;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.Body;
import org.dspace.app.xmlui.wing.element.PageMeta;
import org.dspace.authorize.AuthorizeException;
import java.sql.SQLException;
/**
* User: Robin Taylor
* Date: 08-Apr-2010
* Time: 09:54:52
*/
public class SwordResponseTransformer extends AbstractDSpaceTransformer
{
private static final Message T_dspace_home = message("xmlui.general.dspace_home");
private static final Message T_title = message("xmlui.swordclient.SwordResponse.title");
private static final Message T_SwordCopy_trail = message("xmlui.swordclient.general.SwordCopy_trail");
private static final Message T_trail = message("xmlui.swordclient.SwordResponse.trail");
private static final Message T_main_head = message("xmlui.swordclient.general.main_head");
public void addPageMeta(PageMeta pageMeta) throws WingException
{
pageMeta.addMetadata("title").addContent(T_title);
pageMeta.addTrailLink(contextPath + "/", T_dspace_home);
pageMeta.addTrail().addContent(T_SwordCopy_trail);
pageMeta.addTrail().addContent(T_trail);
}
public void addBody(Body body) throws WingException, SQLException, AuthorizeException
{
String handle = parameters.getParameter("handle", null);
//Division main = body.addDivision("deposit-response");
//main.setHead(T_main_head.parameterize(handle));
}
}

View File

@@ -0,0 +1,76 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the license and copyright
detailed in the LICENSE and NOTICE files at the root of the source
tree and available online at
http://www.dspace.org/license/
-->
<catalogue xml:lang="en" xmlns:i18n="http://apache.org/cocoon/i18n/2.1" xmlns="http://apache.org/cocoon/i18n/2.1">
<!--
The format used by all keys is as follows
xmlui.<Aspect>.<Java Class>.<name>
There are a few exceptions to this nameing format,
1) Some general keys are in the xmlui.general namespace
because they are used very frequently.
2) Some general keys which are specific to a particular aspect
may be found at xmlui.<Aspect> without specifiying a
particular java class.
-->
<!-- Sword Client -->
<message key="xmlui.swordclient.Navigation.context_head">Sword Copy</message>
<message key="xmlui.swordclient.Navigation.context_copy">Copy item to another repository</message>
<message key="xmlui.swordclient.general.SwordCopy_trail">Sword Copy</message>
<message key="xmlui.swordclient.general.main_head">Copy item: {0}</message>
<message key="xmlui.swordclient.SelectTarget.title">Sword copy target</message>
<message key="xmlui.swordclient.SelectTarget.trail">Select target</message>
<message key="xmlui.swordclient.SelectTarget.url">URL</message>
<message key="xmlui.swordclient.SelectTarget.other_url">Alternative URL</message>
<message key="xmlui.swordclient.SelectTarget.username">Username</message>
<message key="xmlui.swordclient.SelectTarget.password">Password</message>
<message key="xmlui.swordclient.SelectTarget.on_behalf_of">On behalf of</message>
<message key="xmlui.swordclient.SelectTargetAction.url_error">Invalid URL</message>
<message key="xmlui.swordclient.SelectTargetAction.username_error">Invalid username</message>
<message key="xmlui.swordclient.SelectTargetAction.password_error">Invalid password</message>
<message key="xmlui.swordclient.SelectTargetAction.serviceDoc_error">Error fetching Sword Service Document: {0}</message>
<message key="xmlui.swordclient.SelectCollection.title">Sword target collections</message>
<message key="xmlui.swordclient.SelectCollection.trail">Select collections</message>
<message key="xmlui.swordclient.SelectCollection.collection_head">Collection: {0}</message>
<message key="xmlui.swordclient.SelectCollection.collection_title">Title: {0} </message>
<message key="xmlui.swordclient.SelectCollection.collection policy">Policy: {0}</message>
<message key="xmlui.swordclient.SelectCollection.collection_mediation">Mediation: {0}</message>
<message key="xmlui.swordclient.SelectCollection.collection_file_types">File Types: {0}</message>
<message key="xmlui.swordclient.SelectCollection.collection_package_formats">Package Formats: {0}</message>
<message key="xmlui.swordclient.SelectCollection.collection_deposit_button">Deposit in this location</message>
<message key="xmlui.swordclient.SelectCollection.sub_service_target">Sub Service target</message>
<message key="xmlui.swordclient.SelectCollection.sub_service_target_button">Get Sub Service Document</message>
<message key="xmlui.swordclient.SelectPackagingAction.head">Collection:{0}</message>
<message key="xmlui.swordclient.SelectPackagingAction.title">Title: {0}</message>
<message key="xmlui.swordclient.SelectPackagingAction.policy">Policy: {0} </message>
<message key="xmlui.swordclient.SelectPackagingAction.mediation">Mediation:{0} </message>
<message key="xmlui.swordclient.SelectPackagingAction.file_types">File Type</message>
<message key="xmlui.swordclient.SelectPackagingAction.package_formats">Package Format</message>
<message key="xmlui.swordclient.SelectPackagingAction.packageFormat_error">Unsupported package format selected</message>
<message key="xmlui.swordclient.DepositAction.success">Item successfully copied</message>
<message key="xmlui.swordclient.DepositAction.package_error">Package format error</message>
<message key="xmlui.swordclient.DepositAction.invalid_handle">Invalid handle</message>
<message key="xmlui.swordclient.DepositAction.package_error">An error occurred creating the packaging object</message>
<message key="xmlui.swordclient.DepositAction.error">Error encountered during deposit: {0}</message>
<message key="xmlui.swordclient.SwordResponse.title">Sword response</message>
<message key="xmlui.swordclient.SwordResponse.trail">Sword response</message>
</catalogue>

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
sitemap.xmap for Sword.
Version: $Revision: 3705 $
Date: $Date: 2009-04-11 19:02:24 +0200 (So, 11 dub 2009) $
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.
-->
<!--
Sword aspect
-->
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:transformers>
<map:transformer name="SelectTargetTransformer"
src="org.dspace.app.xmlui.aspect.swordclient.SelectTargetTransformer"/>
<map:transformer name="SelectCollectionTransformer"
src="org.dspace.app.xmlui.aspect.swordclient.SelectCollectionTransformer"/>
<map:transformer name="SelectPackagingTransformer"
src="org.dspace.app.xmlui.aspect.swordclient.SelectPackagingTransformer"/>
<map:transformer name="DepositResponseTransformer"
src="org.dspace.app.xmlui.aspect.swordclient.SwordResponseTransformer"/>
<map:transformer name="Navigation" src="org.dspace.app.xmlui.aspect.swordclient.Navigation"/>
</map:transformers>
<map:selectors>
<map:selector name="AuthenticatedSelector" src="org.dspace.app.xmlui.aspect.general.AuthenticatedSelector"/>
</map:selectors>
</map:components>
<map:flow language="javascript">
<map:script src="sword.js"/>
</map:flow>
<map:pipelines>
<map:pipeline>
<!-- Flow Entry points -->
<map:select type="AuthenticatedSelector">
<map:when test="administrator">
<map:match pattern="swordclient">
<map:match type="request" pattern="swordclient-continue">
<map:call continuation="{1}"/>
</map:match>
<map:call function="startSwordDeposit"/>
</map:match>
</map:when>
</map:select>
<map:generate/>
<!-- Add the navigation bar -->
<map:transform type="Navigation"/>
<map:select type="AuthenticatedSelector">
<map:when test="administrator">
<map:match type="WildcardParameterMatcher" pattern="true">
<map:parameter name="parameter-name" value="flow"/>
<map:parameter name="flow" value="{flow-attribute:flow}"/>
<!-- General Notices
Sometimes notices are generated by flow parameters that are not tied to
the specific state. In this case several flow-attributes are created that
describe the notice, if they are present then we add them to the DRI document
before all other flow pages.
-->
<map:match pattern="swordclient/**">
<map:match type="WildcardParameterMatcher" pattern="true">
<map:parameter name="parameter-name" value="notice"/>
<map:parameter name="notice" value="{flow-attribute:notice}"/>
<map:transform type="notice">
<map:parameter name="outcome" value="{flow-attribute:outcome}"/>
<map:parameter name="header" value="{flow-attribute:header}"/>
<map:parameter name="message" value="{flow-attribute:message}"/>
<map:parameter name="characters" value="{flow-attribute:characters}"/>
</map:transform>
</map:match>
</map:match>
</map:match>
<map:match pattern="swordclient/select-target">
<map:transform type="SelectTargetTransformer">
<map:parameter name="handle" value="{flow-attribute:handle}"/>
<map:parameter name="errors" value="{flow-attribute:errors}"/>
</map:transform>
</map:match>
<map:match pattern="swordclient/select-collection">
<map:transform type="SelectCollectionTransformer">
<map:parameter name="handle" value="{flow-attribute:handle}"/>
</map:transform>
</map:match>
<map:match pattern="swordclient/select-packaging">
<map:transform type="SelectPackagingTransformer">
<map:parameter name="handle" value="{flow-attribute:handle}"/>
</map:transform>
</map:match>
<map:match pattern="swordclient/deposit-response">
<map:transform type="DepositResponseTransformer">
<map:parameter name="handle" value="{flow-attribute:handle}"/>
</map:transform>
</map:match>
</map:when>
<map:otherwise>
<!-- The user is not an administrator (ie not logged in) so redirect them to the login page -->
<map:match pattern="swordclient">
<map:act type="StartAuthentication"/>
</map:match>
</map:otherwise>
</map:select>
<map:serialize type="xml"/>
</map:pipeline>
</map:pipelines>
</map:sitemap>

View File

@@ -0,0 +1,281 @@
importClass(Packages.org.dspace.authorize.AuthorizeManager);
importClass(Packages.org.dspace.app.xmlui.utils.FlowscriptUtils);
importClass(Packages.org.dspace.app.xmlui.utils.ContextUtil);
importClass(Packages.org.dspace.sword.client.DSpaceSwordClient);
importClass(Packages.org.dspace.app.xmlui.aspect.swordclient.SelectTargetAction);
importClass(Packages.org.dspace.app.xmlui.aspect.swordclient.SelectCollectionAction);
importClass(Packages.org.dspace.app.xmlui.aspect.swordclient.SelectPackagingAction);
importClass(Packages.org.dspace.app.xmlui.aspect.swordclient.DepositAction);
importClass(Packages.org.dspace.content.Item);
/**
* Simple access method to access the current cocoon object model.
*/
function getObjectModel()
{
return FlowscriptUtils.getObjectModel(cocoon);
}
/**
* Return the DSpace context for this request since each HTTP request generates
* a new context this object should never be stored and instead allways accessed
* through this method so you are ensured that it is the correct one.
*/
function getDSContext()
{
return ContextUtil.obtainContext(getObjectModel());
}
/**
* The result object could potentialy contain a notice message and a list of
* errors. If either of these are present then they are added to the sitemap's
* parameters.
*/
function sendPage(uri,bizData,result)
{
if (bizData == null)
bizData = {};
if (result != null)
{
var outcome = result.getOutcome();
var header = result.getHeader();
var message = result.getMessage();
var characters = result.getCharacters();
if (message != null || characters != null)
{
bizData["notice"] = "true";
bizData["outcome"] = outcome;
bizData["header"] = header;
bizData["message"] = message;
bizData["characters"] = characters;
}
var errors = result.getErrorString();
if (errors != null)
{
bizData["errors"] = errors;
}
}
// Comment - Ugh ! In Cocoon terms 'sendPage' should be used when there is no 'flow' but Manakin sets this misleading parameter
// to force it through another part of the sitemap - Robin.
bizData["flow"] = "true";
cocoon.sendPage(uri,bizData);
}
function sendPageAndWait(uri,bizData,result)
{
if (bizData == null)
bizData = {};
if (result != null)
{
var outcome = result.getOutcome();
var header = result.getHeader();
var message = result.getMessage();
var characters = result.getCharacters();
if (message != null || characters != null)
{
bizData["notice"] = "true";
bizData["outcome"] = outcome;
bizData["header"] = header;
bizData["message"] = message;
bizData["characters"] = characters;
}
var errors = result.getErrorString();
if (errors != null)
{
bizData["errors"] = errors;
}
}
// just to remember where we came from.
bizData["flow"] = "true";
cocoon.sendPageAndWait(uri,bizData);
}
/**
* Return whether the currently authenticated eperson is an
* administrator.
*/
function isAdministrator() {
return AuthorizeManager.isAdmin(getDSContext());
}
/**
* Assert that the currently authenticated eperson is an administrator.
* If they are not then an error page is returned and this function
* will NEVER return.
*/
function assertAdministrator() {
if ( ! isAdministrator()) {
sendPage("admin/not-authorized");
cocoon.exit();
}
}
/*********************
* Entry Point flows
*********************/
function startSwordDeposit()
{
assertAdministrator();
var itemID = cocoon.request.get("itemID");
var item = Item.find(getDSContext(),itemID);
var handle = item.getHandle();
var DSClient = new DSpaceSwordClient();
var result = null;
// The URL of the service document (or 'sub' service document).
var serviceDoc;
// The URL of the selected collection.
var location;
// The available file types. An intersection of what the client and server can support.
var fileTypes;
// The available package formats. An intersection of what the client and server can support.
var packageFormats;
// Retrieve the high level service document
result = getServiceDoc(handle, DSClient);
serviceDoc = result.getParameter("serviceDoc");
// Select a collection in which to deposit.
result = getCollection(handle, serviceDoc, DSClient);
location = result.getParameter("location");
serviceDoc = result.getParameter("serviceDoc");
fileTypes = result.getParameter("fileTypes");
packageFormats = result.getParameter("packageFormats");
// Ask the user to select which file type and package format combo they want.
getPackageType(handle, fileTypes, packageFormats, location, serviceDoc, DSClient);
// Now send the item.
sendItem(handle, DSClient);
}
function getServiceDoc(handle, DSClient)
{
var selectTargetAction;
var result;
do {
sendPageAndWait("swordclient/select-target", {handle: handle}, result);
if (cocoon.request.get("submit_next"))
{
selectTargetAction = new SelectTargetAction();
result = selectTargetAction.processSelectTarget(getDSContext(), cocoon.request, DSClient);
}
else if (cocoon.request.get("submit_cancel"))
{
cocoon.redirectTo(cocoon.request.getContextPath() + "/handle/" + handle, true);
getDSContext().complete();
cocoon.exit();
}
} while (result == null || !result.getContinue());
return result;
}
function getCollection(handle, serviceDoc, DSClient)
{
var selectCollectionAction;
var selectTargetAction;
var result;
do {
cocoon.request.setAttribute("serviceDoc", serviceDoc);
sendPageAndWait("swordclient/select-collection", {handle: handle}, result);
if (cocoon.request.get("deposit"))
{
// A collection, or rather the location of one, has been selected, so lets
// see what file type and package format combos are available.
// We have a new request so need to attach the service doc again.
cocoon.request.setAttribute("serviceDoc", serviceDoc);
selectCollectionAction = new SelectCollectionAction();
result = selectCollectionAction.processSelectCollection(getDSContext(), cocoon.request, DSClient);
}
else if (cocoon.request.get("sub-service"))
{
// The user has opted to drill down into a 'sub' service document
// Note : The 'result' from this action should never have 'continue=true'.
selectTargetAction = new SelectTargetAction();
result = selectTargetAction.processSelectSubTarget(getDSContext(), cocoon.request, DSClient);
// Reset serviceDoc so that when we loop round we display the contents of the new service document.
serviceDoc = result.getParameter("serviceDoc");
}
else if (cocoon.request.get("submit_cancel"))
{
cocoon.redirectTo(cocoon.request.getContextPath() + "/handle/" + handle, true);
getDSContext().complete();
cocoon.exit();
}
} while (result == null || !result.getContinue());
return result;
}
function getPackageType(handle, fileTypes, packageFormats, location, serviceDoc, DSClient)
{
var selectPackagingAction;
var result;
do {
cocoon.request.setAttribute("fileTypes", fileTypes);
cocoon.request.setAttribute("packageFormats", packageFormats);
cocoon.request.setAttribute("location", location);
cocoon.request.setAttribute("serviceDoc", serviceDoc);
sendPageAndWait("swordclient/select-packaging", {handle: handle}, result);
if (cocoon.request.get("submit_next"))
{
// Update the Sword Client with the selected file type and package format
selectPackagingAction = new SelectPackagingAction();
result = selectPackagingAction.processSelectPackaging(getDSContext(), cocoon.request, DSClient);
}
else if (cocoon.request.get("submit_cancel"))
{
cocoon.redirectTo(cocoon.request.getContextPath() + "/handle/" + handle, true);
getDSContext().complete();
cocoon.exit();
}
} while (result == null || !result.getContinue());
}
function sendItem(handle, DSClient)
{
var depositAction;
var result;
depositAction = new DepositAction();
result = depositAction.processDeposit(getDSContext(), handle, DSClient);
sendPage("swordclient/deposit-response", {handle: handle}, result);
}

View File

@@ -0,0 +1,94 @@
<?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>
<packaging>war</packaging>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-xmlui-webapp</artifactId>
<version>1.8.0-SNAPSHOT</version>
<name>DSpace Sword Client :: Sword Client XMLUI Webapp</name>
<parent>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client</artifactId>
<version>1.8.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-xmlui-api</artifactId>
<exclusions>
<exclusion>
<artifactId>solr-solrj</artifactId>
<groupId>org.apache.solr</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-xmlui-api</artifactId>
<version>1.8.0-SNAPSHOT</version>
</dependency>
<!-- external -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>false</archiveClasses>
<attachClasses>true</attachClasses>
<classesClassifier>classes</classesClassifier>
<failOnMissingWebXml>false</failOnMissingWebXml>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
<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>
<!--
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://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-webapp
</connection>
<developerConnection>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-webapp
</developerConnection>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-sword-client-xmlui-webapp</url>
</scm>
</project>

View File

@@ -0,0 +1,40 @@
<?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>
<packaging>pom</packaging>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client</artifactId>
<version>1.8.0-SNAPSHOT</version>
<name>DSpace Sword Client</name>
<parent>
<artifactId>dspace-parent</artifactId>
<groupId>org.dspace</groupId>
<version>1.8.0-SNAPSHOT</version>
</parent>
<modules>
<module>dspace-sword-client-api</module>
<module>dspace-sword-client-xmlui-api</module>
<module>dspace-sword-client-xmlui-webapp</module>
</modules>
<!--
The Subversion repository location is used by Continuum to update
against when changes have occurred, this spawns a new build cycle
and releases snapshots into the snapshot repository below.
-->
<scm>
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-sword-client</connection>
<developerConnection>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-sword-client
</developerConnection>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-sword-client</url>
</scm>
<issueManagement>
<system>JIRA</system>
<url>http://jira.dspace.org/jira/browse/SWORD</url>
</issueManagement>
</project>

View File

@@ -0,0 +1,15 @@
# List of remote Sword servers. Used to build the drop-down list of selectable Sword targets.
sword-client.targets = http://localhost:8080/sword/servicedocument, \
http://client.swordapp.org/client/servicedocument, \
http://dspace.swordapp.org/sword/servicedocument, \
http://sword.eprints.org/sword-app/servicedocument, \
http://sword.intralibrary.com/IntraLibrary-Deposit/service, \
http://fedora.swordapp.org/sword-fedora/servicedocument
# List of file types from which the user can select. If a type is not supported by the remote server
# it will not appear in the drop-down list.
sword-client.file-types = application/zip
# List of package formats from which the user can select. If a format is not supported by the remote server
# it will not appear in the drop-down list.
sword-client.package-formats = http://purl.org/net/sword-types/METSDSpaceSIP

View File

@@ -80,6 +80,8 @@
as leaving it on together with discovery will cause UI overlap issues
<aspect name="Discovery" path="resource://aspects/Discovery/" />
-->
<!--<aspect name="SwordClient" path="resource://aspects/SwordClient/" />-->
<!--
This aspect tests the various possible DRI features,
it helps a theme developer create themes

View File

@@ -159,6 +159,18 @@
<type>war</type>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-xmlui-api</artifactId>
<version>1.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-client-xmlui-webapp</artifactId>
<version>1.8.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<!-- DSpace XMLUI API -->
<dependency>
@@ -173,6 +185,12 @@
<scope>provided</scope>
</dependency>
<!-- A bit untidy but needed for XMLUI Sword client -->
<dependency>
<groupId>org.dspace</groupId>
<artifactId>dspace-sword-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -255,6 +255,19 @@
</modules>
</profile>
<!-- Builds DSpace Sword Client from local source if present -->
<profile>
<id>dspace-sword-client</id>
<activation>
<file>
<exists>../dspace-sword-client/pom.xml</exists>
</file>
</activation>
<modules>
<module>../dspace-sword-client</module>
</modules>
</profile>
<!--
Builds each separate XMLUI module for the XMLUI war (for development/Eclipse)
-->

View File

@@ -81,6 +81,7 @@
<module>dspace-lni</module>
<module>dspace-oai</module>
<module>dspace-sword</module>
<module>dspace-sword-client</module>
<module>dspace</module>
</modules>
</profile>
@@ -104,6 +105,7 @@
<module>dspace-lni</module>
<module>dspace-oai</module>
<module>dspace-sword</module>
<module>dspace-sword-client</module>
</modules>
</profile>