mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 10:04:21 +00:00
Merge pull request #10570 from tdonohue/remove_unused_sword_client_7x
[Port dspace-7_x] Remove unused, unmaintained SWORD v1 client code
This commit is contained in:
@@ -1,463 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.apache.http.HttpHost;
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpStatus;
|
|
||||||
import org.apache.http.StatusLine;
|
|
||||||
import org.apache.http.auth.AuthScope;
|
|
||||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.conn.params.ConnRoutePNames;
|
|
||||||
import org.apache.http.entity.ContentType;
|
|
||||||
import org.apache.http.entity.FileEntity;
|
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
|
||||||
import org.apache.http.params.HttpParams;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.purl.sword.base.ChecksumUtils;
|
|
||||||
import org.purl.sword.base.DepositResponse;
|
|
||||||
import org.purl.sword.base.HttpHeaders;
|
|
||||||
import org.purl.sword.base.ServiceDocument;
|
|
||||||
import org.purl.sword.base.SwordValidationInfo;
|
|
||||||
import org.purl.sword.base.UnmarshallException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an example Client implementation to demonstrate how to connect to a
|
|
||||||
* SWORD server. The client supports BASIC HTTP Authentication. This can be
|
|
||||||
* initialised by setting a username and password.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class Client implements SWORDClient {
|
|
||||||
/**
|
|
||||||
* The status field for the response code from the recent network access.
|
|
||||||
*/
|
|
||||||
private Status status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the server to contact.
|
|
||||||
*/
|
|
||||||
private String server;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The port number for the server.
|
|
||||||
*/
|
|
||||||
private int port;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies if the network access should use HTTP authentication.
|
|
||||||
*/
|
|
||||||
private boolean doAuthentication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The username to use for Basic Authentication.
|
|
||||||
*/
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User password that is to be used.
|
|
||||||
*/
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The userAgent to identify this application.
|
|
||||||
*/
|
|
||||||
private String userAgent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The client that is used to send data to the specified server.
|
|
||||||
*/
|
|
||||||
private final DefaultHttpClient client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default connection timeout. This can be modified by using the
|
|
||||||
* setSocketTimeout method.
|
|
||||||
*/
|
|
||||||
public static final int DEFAULT_TIMEOUT = 20000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logger.
|
|
||||||
*/
|
|
||||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(Client.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new Client. The client will not use authentication by default.
|
|
||||||
*/
|
|
||||||
public Client() {
|
|
||||||
client = new DefaultHttpClient();
|
|
||||||
HttpParams params = client.getParams();
|
|
||||||
params.setParameter("http.socket.timeout",
|
|
||||||
Integer.valueOf(DEFAULT_TIMEOUT));
|
|
||||||
HttpHost proxyHost = (HttpHost) params
|
|
||||||
.getParameter(ConnRoutePNames.DEFAULT_PROXY); // XXX does this really work?
|
|
||||||
log.debug("proxy host: " + proxyHost.getHostName());
|
|
||||||
log.debug("proxy port: " + proxyHost.getPort());
|
|
||||||
doAuthentication = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the server that will be used to send the network access.
|
|
||||||
*
|
|
||||||
* @param server server address/hostname
|
|
||||||
* @param port server port
|
|
||||||
*/
|
|
||||||
public void setServer(String server, int port) {
|
|
||||||
this.server = server;
|
|
||||||
this.port = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the user credentials that will be used when making the access to the
|
|
||||||
* server.
|
|
||||||
*
|
|
||||||
* @param username The username.
|
|
||||||
* @param password The password.
|
|
||||||
*/
|
|
||||||
public void setCredentials(String username, String password) {
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
doAuthentication = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the basic credentials. You must have previously set the server and
|
|
||||||
* port using setServer.
|
|
||||||
*
|
|
||||||
* @param username The username.
|
|
||||||
* @param password The password.
|
|
||||||
*/
|
|
||||||
private void setBasicCredentials(String username, String password) {
|
|
||||||
log.debug("server: " + server + " port: " + port + " u: '" + username
|
|
||||||
+ "' p '" + password + "'");
|
|
||||||
client.getCredentialsProvider().setCredentials(new AuthScope(server, port),
|
|
||||||
new UsernamePasswordCredentials(username, password));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a proxy that should be used by the client when trying to access the
|
|
||||||
* server. If this is not set, the client will attempt to make a direct
|
|
||||||
* direct connection to the server. The port is set to 80.
|
|
||||||
*
|
|
||||||
* @param host The hostname.
|
|
||||||
*/
|
|
||||||
public void setProxy(String host) {
|
|
||||||
setProxy(host, 80);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a proxy that should be used by the client when trying to access the
|
|
||||||
* server. If this is not set, the client will attempt to make a direct
|
|
||||||
* direct connection to the server.
|
|
||||||
*
|
|
||||||
* @param host The name of the host.
|
|
||||||
* @param port The port.
|
|
||||||
*/
|
|
||||||
public void setProxy(String host, int port) {
|
|
||||||
client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
|
|
||||||
new HttpHost(host, port)); // XXX does this really work?
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the proxy setting.
|
|
||||||
*/
|
|
||||||
public void clearProxy() {
|
|
||||||
client.getParams().removeParameter(ConnRoutePNames.DEFAULT_PROXY); // XXX does this really work?
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear any user credentials that have been set for this client.
|
|
||||||
*/
|
|
||||||
public void clearCredentials() {
|
|
||||||
client.getCredentialsProvider().clear();
|
|
||||||
doAuthentication = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserAgent(String userAgent) {
|
|
||||||
this.userAgent = userAgent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the connection timeout for the socket.
|
|
||||||
*
|
|
||||||
* @param milliseconds The time, expressed as a number of milliseconds.
|
|
||||||
*/
|
|
||||||
public void setSocketTimeout(int milliseconds) {
|
|
||||||
client.getParams().setParameter("http.socket.timeout",
|
|
||||||
Integer.valueOf(milliseconds));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the service document. The service document is located at the
|
|
||||||
* specified URL. This calls getServiceDocument(url,onBehalfOf).
|
|
||||||
*
|
|
||||||
* @param url The location of the service document.
|
|
||||||
* @return The ServiceDocument, or <code>null</code> if there was a
|
|
||||||
* problem accessing the document. e.g. invalid access.
|
|
||||||
* @throws SWORDClientException If there is an error accessing the resource.
|
|
||||||
*/
|
|
||||||
public ServiceDocument getServiceDocument(String url)
|
|
||||||
throws SWORDClientException {
|
|
||||||
return getServiceDocument(url, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the service document. The service document is located at the
|
|
||||||
* specified URL. This calls getServiceDocument(url,onBehalfOf).
|
|
||||||
*
|
|
||||||
* @param url The location of the service document.
|
|
||||||
* @return The ServiceDocument, or <code>null</code> if there was a
|
|
||||||
* problem accessing the document. e.g. invalid access.
|
|
||||||
* @throws SWORDClientException If there is an error accessing the resource.
|
|
||||||
*/
|
|
||||||
public ServiceDocument getServiceDocument(String url, String onBehalfOf)
|
|
||||||
throws SWORDClientException {
|
|
||||||
URL serviceDocURL = null;
|
|
||||||
try {
|
|
||||||
serviceDocURL = new URL(url);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
// Try relative URL
|
|
||||||
URL baseURL = null;
|
|
||||||
try {
|
|
||||||
baseURL = new URL("http", server, Integer.valueOf(port), "/");
|
|
||||||
serviceDocURL = new URL(baseURL, (url == null) ? "" : url);
|
|
||||||
} catch (MalformedURLException e1) {
|
|
||||||
// No dice, can't even form base URL...
|
|
||||||
throw new SWORDClientException(url + " is not a valid URL ("
|
|
||||||
+ e1.getMessage()
|
|
||||||
+ "), and could not form a relative one from: "
|
|
||||||
+ baseURL + " / " + url, e1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpGet httpget = new HttpGet(serviceDocURL.toExternalForm());
|
|
||||||
if (doAuthentication) {
|
|
||||||
// this does not perform any check on the username password. It
|
|
||||||
// relies on the server to determine if the values are correct.
|
|
||||||
setBasicCredentials(username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties properties = new Properties();
|
|
||||||
|
|
||||||
if (containsValue(onBehalfOf)) {
|
|
||||||
log.debug("Setting on-behalf-of: " + onBehalfOf);
|
|
||||||
httpget.addHeader(url, url);
|
|
||||||
httpget.addHeader(HttpHeaders.X_ON_BEHALF_OF, onBehalfOf);
|
|
||||||
properties.put(HttpHeaders.X_ON_BEHALF_OF, onBehalfOf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containsValue(userAgent)) {
|
|
||||||
log.debug("Setting userAgent: " + userAgent);
|
|
||||||
httpget.addHeader(HttpHeaders.USER_AGENT, userAgent);
|
|
||||||
properties.put(HttpHeaders.USER_AGENT, userAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceDocument doc = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
HttpResponse response = client.execute(httpget);
|
|
||||||
StatusLine statusLine = response.getStatusLine();
|
|
||||||
int statusCode = statusLine.getStatusCode();
|
|
||||||
// store the status code
|
|
||||||
status = new Status(statusCode, statusLine.getReasonPhrase());
|
|
||||||
|
|
||||||
if (status.getCode() == HttpStatus.SC_OK) {
|
|
||||||
String message = readResponse(response.getEntity().getContent());
|
|
||||||
log.debug("returned message is: " + message);
|
|
||||||
doc = new ServiceDocument();
|
|
||||||
lastUnmarshallInfo = doc.unmarshall(message, properties);
|
|
||||||
} else {
|
|
||||||
throw new SWORDClientException(
|
|
||||||
"Received error from service document request: "
|
|
||||||
+ status);
|
|
||||||
}
|
|
||||||
} catch (IOException ioex) {
|
|
||||||
throw new SWORDClientException(ioex.getMessage(), ioex);
|
|
||||||
} catch (UnmarshallException uex) {
|
|
||||||
throw new SWORDClientException(uex.getMessage(), uex);
|
|
||||||
} finally {
|
|
||||||
httpget.releaseConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SwordValidationInfo lastUnmarshallInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return SWORD validation info
|
|
||||||
*/
|
|
||||||
public SwordValidationInfo getLastUnmarshallInfo() {
|
|
||||||
return lastUnmarshallInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post a file to the server. The different elements of the post are encoded
|
|
||||||
* in the specified message.
|
|
||||||
*
|
|
||||||
* @param message The message that contains the post information.
|
|
||||||
* @throws SWORDClientException if there is an error during the post operation.
|
|
||||||
*/
|
|
||||||
public DepositResponse postFile(PostMessage message)
|
|
||||||
throws SWORDClientException {
|
|
||||||
if (message == null) {
|
|
||||||
throw new SWORDClientException("Message cannot be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpPost httppost = new HttpPost(message.getDestination());
|
|
||||||
|
|
||||||
if (doAuthentication) {
|
|
||||||
setBasicCredentials(username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
DepositResponse response = null;
|
|
||||||
|
|
||||||
String messageBody = "";
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (message.isUseMD5()) {
|
|
||||||
String md5 = ChecksumUtils.generateMD5(message.getFilepath());
|
|
||||||
if (message.getChecksumError()) {
|
|
||||||
md5 = "1234567890";
|
|
||||||
}
|
|
||||||
log.debug("checksum error is: " + md5);
|
|
||||||
if (md5 != null) {
|
|
||||||
httppost.addHeader(HttpHeaders.CONTENT_MD5, md5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String filename = message.getFilename();
|
|
||||||
if (!"".equals(filename)) {
|
|
||||||
httppost.addHeader(HttpHeaders.CONTENT_DISPOSITION,
|
|
||||||
" filename=" + filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containsValue(message.getSlug())) {
|
|
||||||
httppost.addHeader(HttpHeaders.SLUG, message.getSlug());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.getCorruptRequest()) {
|
|
||||||
// insert a header with an invalid boolean value
|
|
||||||
httppost.addHeader(HttpHeaders.X_NO_OP, "Wibble");
|
|
||||||
} else {
|
|
||||||
httppost.addHeader(HttpHeaders.X_NO_OP, Boolean
|
|
||||||
.toString(message.isNoOp()));
|
|
||||||
}
|
|
||||||
httppost.addHeader(HttpHeaders.X_VERBOSE, Boolean
|
|
||||||
.toString(message.isVerbose()));
|
|
||||||
|
|
||||||
String packaging = message.getPackaging();
|
|
||||||
if (packaging != null && packaging.length() > 0) {
|
|
||||||
httppost.addHeader(HttpHeaders.X_PACKAGING, packaging);
|
|
||||||
}
|
|
||||||
|
|
||||||
String onBehalfOf = message.getOnBehalfOf();
|
|
||||||
if (containsValue(onBehalfOf)) {
|
|
||||||
httppost.addHeader(HttpHeaders.X_ON_BEHALF_OF, onBehalfOf);
|
|
||||||
}
|
|
||||||
|
|
||||||
String userAgent = message.getUserAgent();
|
|
||||||
if (containsValue(userAgent)) {
|
|
||||||
httppost.addHeader(HttpHeaders.USER_AGENT, userAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
FileEntity requestEntity = new FileEntity(
|
|
||||||
new File(message.getFilepath()),
|
|
||||||
ContentType.create(message.getFiletype()));
|
|
||||||
httppost.setEntity(requestEntity);
|
|
||||||
|
|
||||||
HttpResponse httpResponse = client.execute(httppost);
|
|
||||||
StatusLine statusLine = httpResponse.getStatusLine();
|
|
||||||
int statusCode = statusLine.getStatusCode();
|
|
||||||
status = new Status(statusCode, statusLine.getReasonPhrase());
|
|
||||||
|
|
||||||
log.info("Checking the status code: " + status.getCode());
|
|
||||||
|
|
||||||
if (status.getCode() == HttpStatus.SC_ACCEPTED
|
|
||||||
|| status.getCode() == HttpStatus.SC_CREATED) {
|
|
||||||
messageBody = readResponse(httpResponse.getEntity().getContent());
|
|
||||||
response = new DepositResponse(status.getCode());
|
|
||||||
response.setLocation(httpResponse.getFirstHeader("Location").getValue());
|
|
||||||
// added call for the status code.
|
|
||||||
lastUnmarshallInfo = response.unmarshall(messageBody, new Properties());
|
|
||||||
} else {
|
|
||||||
messageBody = readResponse(httpResponse.getEntity().getContent());
|
|
||||||
response = new DepositResponse(status.getCode());
|
|
||||||
response.unmarshallErrorDocument(messageBody);
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException nex) {
|
|
||||||
throw new SWORDClientException("Unable to use MD5. "
|
|
||||||
+ nex.getMessage(), nex);
|
|
||||||
} catch (IOException ioex) {
|
|
||||||
throw new SWORDClientException(ioex.getMessage(), ioex);
|
|
||||||
} catch (UnmarshallException uex) {
|
|
||||||
throw new SWORDClientException(uex.getMessage() + "(<pre>" + messageBody + "</pre>)", uex);
|
|
||||||
} finally {
|
|
||||||
httppost.releaseConnection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a response from the stream and return it as a string.
|
|
||||||
*
|
|
||||||
* @param stream The stream that contains the response.
|
|
||||||
* @return The string extracted from the screen.
|
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* @throws IOException A general class of exceptions produced by failed or interrupted I/O
|
|
||||||
* operations.
|
|
||||||
*/
|
|
||||||
private String readResponse(InputStream stream)
|
|
||||||
throws UnsupportedEncodingException, IOException {
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
|
||||||
stream, "UTF-8"));
|
|
||||||
String line = null;
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
buffer.append(line);
|
|
||||||
buffer.append("\n");
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the status information that was returned from the most recent
|
|
||||||
* request sent to the server.
|
|
||||||
*
|
|
||||||
* @return The status code returned from the most recent access.
|
|
||||||
*/
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check to see if the specified item contains a non-empty string.
|
|
||||||
*
|
|
||||||
* @param item The string to check.
|
|
||||||
* @return True if the string is not null and has a length greater than 0
|
|
||||||
* after any whitespace is trimmed from the start and end.
|
|
||||||
* Otherwise, false.
|
|
||||||
*/
|
|
||||||
private boolean containsValue(String item) {
|
|
||||||
return ((item != null) && (item.trim().length() > 0));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,40 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hold general constants for the client.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class ClientConstants {
|
|
||||||
/**
|
|
||||||
* Current software version.
|
|
||||||
*/
|
|
||||||
public static final String CLIENT_VERSION = "1.1";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the name of this application
|
|
||||||
*/
|
|
||||||
public static final String SERVICE_NAME = "CASIS Test Client";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the name of this application
|
|
||||||
*/
|
|
||||||
public static final String NOT_DEFINED_TEXT = "Not defined";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logging property file.
|
|
||||||
*/
|
|
||||||
public static final String LOGGING_PROPERTY_FILE = "log4j.properties";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor
|
|
||||||
*/
|
|
||||||
private ClientConstants() { }
|
|
||||||
}
|
|
@@ -1,116 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry point for the SWORD Demonstration Client. This will parse the list of
|
|
||||||
* command line options and load either a Command Line client or a GUI client.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class ClientFactory {
|
|
||||||
/**
|
|
||||||
* Generate a string that specifies the command line options for this
|
|
||||||
* program.
|
|
||||||
*
|
|
||||||
* @return A list of the options for this program.
|
|
||||||
*/
|
|
||||||
public static String usage() {
|
|
||||||
StringBuilder buffer = new StringBuilder();
|
|
||||||
buffer.append("swordclient: version ");
|
|
||||||
buffer.append(ClientConstants.CLIENT_VERSION);
|
|
||||||
buffer.append("\n");
|
|
||||||
|
|
||||||
buffer.append("GUI Mode: ");
|
|
||||||
buffer.append("swordclient [-gui] [-nocapture]");
|
|
||||||
buffer.append("\n\n");
|
|
||||||
|
|
||||||
buffer.append("Command Mode: Service - Request a Service Document\n");
|
|
||||||
buffer.append("swordclient -cmd -t service [user-options] [proxy-options] -href url [-onBehalfOf name] ");
|
|
||||||
buffer.append("\n\n");
|
|
||||||
|
|
||||||
buffer.append("Command Mode: Post - Post a file to a remote service.\n");
|
|
||||||
buffer.append("swordclient -cmd -t post [user-options] [proxy-options] [post-options] \n");
|
|
||||||
buffer.append(" [-file file] [-filetype type] [-onBehalfOf name]");
|
|
||||||
buffer.append("\n\n");
|
|
||||||
|
|
||||||
buffer.append("Command Mode: MultiPost - Post a file to multiple remote services.\n");
|
|
||||||
buffer.append("swordclient -cmd -t multipost [user-options] [proxy-options] [post-options] \n");
|
|
||||||
buffer.append(" [-dest dest]");
|
|
||||||
|
|
||||||
buffer.append("\n\n");
|
|
||||||
buffer.append("User options: \n");
|
|
||||||
buffer.append(" -u username Specify a username to access the remote service.\n");
|
|
||||||
buffer.append(" -p password Specify a password to access the remote service.\n");
|
|
||||||
buffer.append(" Required if -u option is used.");
|
|
||||||
|
|
||||||
buffer.append("\n\n");
|
|
||||||
buffer.append("Proxy options: \n");
|
|
||||||
buffer.append(" -host host Hostname of a proxy, wwwproxy.aber.ac.uk.\n");
|
|
||||||
buffer.append(" -port port Proxy port number, e.g. 8080.\n");
|
|
||||||
|
|
||||||
buffer.append("\n\n");
|
|
||||||
buffer.append("Post options: \n");
|
|
||||||
buffer.append(" -noOp Specified to indicate that the post is a test operation.\n");
|
|
||||||
buffer.append(" -md5 Use an MD5 checksum in the message header.\n");
|
|
||||||
buffer.append(" -checksumError Mis-calculate the file checksum for server test purposes.\n");
|
|
||||||
buffer.append(" -formatNamespace ns The format namespace value.\n");
|
|
||||||
buffer.append(" -slug name The slug value.\n");
|
|
||||||
buffer.append(" -verbose Request a verbose response from the server.\n");
|
|
||||||
|
|
||||||
buffer.append("\n\n");
|
|
||||||
buffer.append("Other options: \n");
|
|
||||||
buffer.append(" -help Show this message.\n");
|
|
||||||
buffer.append(" -t type The type of operation: service, post or multipost.\n");
|
|
||||||
buffer.append(" -href url The URL for the service or post document.\n");
|
|
||||||
buffer.append(" Required for service. The post and multipost operations \n");
|
|
||||||
buffer.append(" will prompt you if the value is not provided.\n");
|
|
||||||
buffer.append(" -filetype type The filetype, e.g. application/zip. The post and multipost\n");
|
|
||||||
buffer.append(" will prompt you for the value if it is not provided.\n");
|
|
||||||
buffer.append(" -onBehalfOf name Specify this parameter to set the On Behalf Of value.\n");
|
|
||||||
buffer.append(" -dest dest Specify the destination for a deposit. This can be repeated\n");
|
|
||||||
buffer.append(" multiple times. The format is: \n");
|
|
||||||
buffer.append(" <username>[<onbehalfof>]:<password>@<href>\n");
|
|
||||||
buffer.append(" e.g. sword[nst]:swordpass@http://sword.aber.ac.uk/post/\n");
|
|
||||||
buffer.append(" nst:pass@http://sword.aber.ac.uk/post\n");
|
|
||||||
buffer.append(" -nocapture Do not capture System.out and System.err to a debug panel\n");
|
|
||||||
buffer.append(" in the GUI panel.");
|
|
||||||
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a client. If GUI mode is set, a GUI client is created. Otherwise,
|
|
||||||
* a command line client is created.
|
|
||||||
*
|
|
||||||
* @param options The list of options extracted from the command line.
|
|
||||||
* @return A new client.
|
|
||||||
*/
|
|
||||||
public ClientType createClient(ClientOptions options) {
|
|
||||||
return new CmdClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the application and determine which client should be loaded. The
|
|
||||||
* application currently has two modes: GUI and client. The GUI mode is the
|
|
||||||
* default option.
|
|
||||||
*
|
|
||||||
* @param args the command line arguments given
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
ClientFactory factory = new ClientFactory();
|
|
||||||
|
|
||||||
ClientOptions options = new ClientOptions();
|
|
||||||
if (options.parseOptions(args)) {
|
|
||||||
ClientType client = factory.createClient(options);
|
|
||||||
client.run(options);
|
|
||||||
} else {
|
|
||||||
System.out.println(usage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,605 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
|
||||||
import org.apache.commons.cli.DefaultParser;
|
|
||||||
import org.apache.commons.cli.Option;
|
|
||||||
import org.apache.commons.cli.Options;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of options that are parsed from the command line.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class ClientOptions {
|
|
||||||
/**
|
|
||||||
* Label for the service operation.
|
|
||||||
*/
|
|
||||||
public static final String TYPE_SERVICE = "service";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Label for the post operation.
|
|
||||||
*/
|
|
||||||
public static final String TYPE_POST = "post";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Label for the multipost operation.
|
|
||||||
*/
|
|
||||||
public static final String TYPE_MULTI_POST = "multipost";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The access type.
|
|
||||||
*/
|
|
||||||
private String accessType = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy host name.
|
|
||||||
*/
|
|
||||||
private String proxyHost = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy host port.
|
|
||||||
*/
|
|
||||||
private int proxyPort = 8080;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Username to access the service/post server.
|
|
||||||
*/
|
|
||||||
private String username = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password to access the service/post server.
|
|
||||||
*/
|
|
||||||
private String password = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HREF of the server to access.
|
|
||||||
*/
|
|
||||||
private String href = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filename to post.
|
|
||||||
*/
|
|
||||||
private String filename = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File type.
|
|
||||||
*/
|
|
||||||
private String filetype = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies that the output streams are not to be captured by the GUI client.
|
|
||||||
*/
|
|
||||||
private boolean noCapture = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SLUG Header field.
|
|
||||||
*/
|
|
||||||
private String slug = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NoOp, used to indicate an operation on the server that does not
|
|
||||||
* require the file to be stored.
|
|
||||||
*/
|
|
||||||
private boolean noOp = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request verbose output from the server.
|
|
||||||
*/
|
|
||||||
private boolean verbose = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OnBehalfOf user id.
|
|
||||||
*/
|
|
||||||
private String onBehalfOf = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format namespace to be used for the posted file.
|
|
||||||
*/
|
|
||||||
private String formatNamespace = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Introduce a checksum error. This is used to simulate an error with the
|
|
||||||
* MD5 value.
|
|
||||||
*/
|
|
||||||
private boolean checksumError = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logger.
|
|
||||||
*/
|
|
||||||
private static final Logger log = LogManager.getLogger();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of multiple destination items. Used if the mode is set to multipost.
|
|
||||||
*/
|
|
||||||
private final List<PostDestination> multiPost = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pattern string to extract the data from a destination parameter in multipost mode.
|
|
||||||
*/
|
|
||||||
private static final Pattern MULTI_PATTERN
|
|
||||||
= Pattern.compile("(.*?)(\\[(.*?)\\]) {0,1}(:(.*)) {0,1}@(http://.*)");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag that indicates if the GUI mode has been set. This is
|
|
||||||
* true by default.
|
|
||||||
*/
|
|
||||||
private boolean guiMode = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flat that indicates if the MD5 option has been selected. This
|
|
||||||
* is true by default.
|
|
||||||
*/
|
|
||||||
private boolean md5 = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the list of options contained in the specified array.
|
|
||||||
*
|
|
||||||
* @param args The array of options.
|
|
||||||
* @return True if the options were parsed successfully.
|
|
||||||
*/
|
|
||||||
public boolean parseOptions(String[] args) {
|
|
||||||
Options options = new Options();
|
|
||||||
options.addOption(Option.builder().longOpt("md5").build())
|
|
||||||
.addOption(Option.builder().longOpt("noOp").build())
|
|
||||||
.addOption(Option.builder().longOpt("verbose").build())
|
|
||||||
.addOption(Option.builder().longOpt("cmd").build())
|
|
||||||
.addOption(Option.builder().longOpt("gui").build())
|
|
||||||
.addOption(Option.builder().longOpt("help").build())
|
|
||||||
.addOption(Option.builder().longOpt("nocapture").build());
|
|
||||||
|
|
||||||
Option option;
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("host").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("port").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder("u").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder("p").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("href").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder("t").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("file").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("filetype").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("slug").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("onBehalfOf").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("formatNamespace").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("checksumError").build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
option = Option.builder().longOpt("dest").hasArg().build();
|
|
||||||
options.addOption(option);
|
|
||||||
|
|
||||||
DefaultParser parser = new DefaultParser();
|
|
||||||
CommandLine command;
|
|
||||||
try {
|
|
||||||
command = parser.parse(options, args);
|
|
||||||
} catch (ParseException ex) {
|
|
||||||
log.error(ex.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.hasOption("help")) {
|
|
||||||
return false; // force the calling code to display the usage information.
|
|
||||||
}
|
|
||||||
md5 = command.hasOption("md5");
|
|
||||||
noOp = command.hasOption("noOp");
|
|
||||||
verbose = command.hasOption("verbose");
|
|
||||||
if (command.hasOption("cmd")) {
|
|
||||||
guiMode = false;
|
|
||||||
}
|
|
||||||
if (command.hasOption("gui")) {
|
|
||||||
guiMode = true;
|
|
||||||
}
|
|
||||||
proxyHost = command.getOptionValue("host");
|
|
||||||
if (command.hasOption("port")) {
|
|
||||||
proxyPort = Integer.parseInt(command.getOptionValue("port"));
|
|
||||||
}
|
|
||||||
username = command.getOptionValue("u");
|
|
||||||
password = command.getOptionValue("p");
|
|
||||||
href = command.getOptionValue("href");
|
|
||||||
accessType = command.getOptionValue("t");
|
|
||||||
filename = command.getOptionValue("file");
|
|
||||||
filetype = command.getOptionValue("filetype");
|
|
||||||
slug = command.getOptionValue("slug");
|
|
||||||
onBehalfOf = command.getOptionValue("onBehalfOf");
|
|
||||||
formatNamespace = command.getOptionValue("formatNamespace");
|
|
||||||
checksumError = command.hasOption("checksumError");
|
|
||||||
noCapture = command.hasOption("nocapture");
|
|
||||||
if (command.hasOption("dest")) {
|
|
||||||
String dest = command.getOptionValue("dest");
|
|
||||||
Matcher m = MULTI_PATTERN.matcher(dest);
|
|
||||||
if (!m.matches()) {
|
|
||||||
log.debug("Error with dest parameter. Ignoring value: {}", dest);
|
|
||||||
} else {
|
|
||||||
int numGroups = m.groupCount();
|
|
||||||
for (int g = 0; g <= numGroups; g++) {
|
|
||||||
log.debug("Group ({}) is: {}", g, m.group(g));
|
|
||||||
}
|
|
||||||
|
|
||||||
String group_username = m.group(1);
|
|
||||||
String group_onBehalfOf = m.group(3);
|
|
||||||
String group_password = m.group(5);
|
|
||||||
String group_url = m.group(6);
|
|
||||||
PostDestination destination = new PostDestination(group_url,
|
|
||||||
group_username, group_password, group_onBehalfOf);
|
|
||||||
|
|
||||||
multiPost.add(destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// apply any settings
|
|
||||||
if (href == null && "service".equals(accessType)) {
|
|
||||||
log.error("No href specified.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (multiPost.isEmpty() && "multipost".equals(accessType)) {
|
|
||||||
log.error("No destinations specified");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accessType == null && !guiMode) {
|
|
||||||
log.error("No access type specified");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((username == null && password != null) || (username != null && password == null)) {
|
|
||||||
log.error(
|
|
||||||
"The username and/or password are not specified. If one is specified, the other must also be " +
|
|
||||||
"specified.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
|
||||||
log.error("Error with parameters.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the access type.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getAccessType() {
|
|
||||||
return accessType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the access type.
|
|
||||||
*
|
|
||||||
* @param accessType The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setAccessType(String accessType) {
|
|
||||||
this.accessType = accessType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the proxy host.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getProxyHost() {
|
|
||||||
return proxyHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the proxy host.
|
|
||||||
*
|
|
||||||
* @param proxyHost The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setProxyHost(String proxyHost) {
|
|
||||||
this.proxyHost = proxyHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the proxy port.
|
|
||||||
*
|
|
||||||
* @return The proxy port. Default value is 80.
|
|
||||||
*/
|
|
||||||
public int getProxyPort() {
|
|
||||||
return proxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the proxy port.
|
|
||||||
*
|
|
||||||
* @param proxyPort The proxy port.
|
|
||||||
*/
|
|
||||||
public void setProxyPort(int proxyPort) {
|
|
||||||
this.proxyPort = proxyPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the username.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the username.
|
|
||||||
*
|
|
||||||
* @param username The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the password.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the password.
|
|
||||||
*
|
|
||||||
* @param password The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the HREF of the service to access.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getHref() {
|
|
||||||
return href;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the HREF of the service to access.
|
|
||||||
*
|
|
||||||
* @param href The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setHref(String href) {
|
|
||||||
this.href = href;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of the file to post.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getFilename() {
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the name of the file to post.
|
|
||||||
*
|
|
||||||
* @param filename The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setFilename(String filename) {
|
|
||||||
this.filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the type of the file to post.
|
|
||||||
*
|
|
||||||
* @return The filetype, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getFiletype() {
|
|
||||||
return filetype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the type of the file to post.
|
|
||||||
*
|
|
||||||
* @param filetype The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setFiletype(String filetype) {
|
|
||||||
this.filetype = filetype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the tool is to be run in GUI mode.
|
|
||||||
*
|
|
||||||
* @return True if the tool is set for GUI mode.
|
|
||||||
*/
|
|
||||||
public boolean isGuiMode() {
|
|
||||||
return guiMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the tool to run in GUI mode.
|
|
||||||
*
|
|
||||||
* @param guiMode True if the tool is to run in gui mode.
|
|
||||||
*/
|
|
||||||
public void setGuiMode(boolean guiMode) {
|
|
||||||
this.guiMode = guiMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the MD5 setting. True if the tool is to use MD5 for post operations.
|
|
||||||
*
|
|
||||||
* @return The MD5 setting.
|
|
||||||
*/
|
|
||||||
public boolean isMd5() {
|
|
||||||
return md5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the MD5 setting.
|
|
||||||
*
|
|
||||||
* @param md5 True if the tool should use MD5 for post operations.
|
|
||||||
*/
|
|
||||||
public void setMd5(boolean md5) {
|
|
||||||
this.md5 = md5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the NoOp header should be sent.
|
|
||||||
*
|
|
||||||
* @return True if the header should be sent.
|
|
||||||
*/
|
|
||||||
public boolean isNoOp() {
|
|
||||||
return noOp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the NoOp setting.
|
|
||||||
*
|
|
||||||
* @param noOp True if the NoOp header should be used.
|
|
||||||
*/
|
|
||||||
public void setNoOp(boolean noOp) {
|
|
||||||
this.noOp = noOp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the verbose option is set.
|
|
||||||
*
|
|
||||||
* @return True if verbose option is set.
|
|
||||||
*/
|
|
||||||
public boolean isVerbose() {
|
|
||||||
return verbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the verbose option.
|
|
||||||
*
|
|
||||||
* @param verbose True if verbose should be set.
|
|
||||||
*/
|
|
||||||
public void setVerbose(boolean verbose) {
|
|
||||||
this.verbose = verbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the onBehalfOf value.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public String getOnBehalfOf() {
|
|
||||||
return onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the onBehalf of Value.
|
|
||||||
*
|
|
||||||
* @param onBehalfOf The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setOnBehalfOf(String onBehalfOf) {
|
|
||||||
this.onBehalfOf = onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the format namespace value.
|
|
||||||
*
|
|
||||||
* @return The value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getFormatNamespace() {
|
|
||||||
return formatNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the format namespace value.
|
|
||||||
*
|
|
||||||
* @param formatNamespace The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setFormatNamespace(String formatNamespace) {
|
|
||||||
this.formatNamespace = formatNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the checksum error value.
|
|
||||||
*
|
|
||||||
* @return True if an error should be introduced into the checksum.
|
|
||||||
*/
|
|
||||||
public boolean getChecksumError() {
|
|
||||||
return checksumError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the checksum error value.
|
|
||||||
*
|
|
||||||
* @param checksumError True if the error should be introduced.
|
|
||||||
*/
|
|
||||||
public void setChecksumError(boolean checksumError) {
|
|
||||||
this.checksumError = checksumError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current slug header.
|
|
||||||
*
|
|
||||||
* @return The slug value, or <code>null</code> if the value is not set.
|
|
||||||
*/
|
|
||||||
public String getSlug() {
|
|
||||||
return this.slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the text that is to be used for the slug header.
|
|
||||||
*
|
|
||||||
* @param slug The value, or <code>null</code> to clear the value.
|
|
||||||
*/
|
|
||||||
public void setSlug(String slug) {
|
|
||||||
this.slug = slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the list of post destinations.
|
|
||||||
*
|
|
||||||
* @return An iterator over the list of PostDestination objects.
|
|
||||||
*/
|
|
||||||
public Iterator<PostDestination> getMultiPost() {
|
|
||||||
return multiPost.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the noCapture option is set. This indicates that the code
|
|
||||||
* should not attempt to redirect stdout and stderr to a different output
|
|
||||||
* destination. Intended for use in a GUI client.
|
|
||||||
*
|
|
||||||
* @return The noCapture setting. True if set.
|
|
||||||
*/
|
|
||||||
public boolean isNoCapture() {
|
|
||||||
return noCapture;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for a client. This contains a single method that allows the factory
|
|
||||||
* to pass a set of command line options to the client.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public interface ClientType {
|
|
||||||
/**
|
|
||||||
* Run the client, processing the specified options.
|
|
||||||
*
|
|
||||||
* @param options The options extracted from the command line.
|
|
||||||
*/
|
|
||||||
public void run(ClientOptions options);
|
|
||||||
}
|
|
@@ -1,445 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.purl.sword.atom.Author;
|
|
||||||
import org.purl.sword.atom.Content;
|
|
||||||
import org.purl.sword.atom.Contributor;
|
|
||||||
import org.purl.sword.atom.Generator;
|
|
||||||
import org.purl.sword.atom.Link;
|
|
||||||
import org.purl.sword.atom.Rights;
|
|
||||||
import org.purl.sword.atom.Summary;
|
|
||||||
import org.purl.sword.atom.Title;
|
|
||||||
import org.purl.sword.base.Collection;
|
|
||||||
import org.purl.sword.base.DepositResponse;
|
|
||||||
import org.purl.sword.base.SWORDEntry;
|
|
||||||
import org.purl.sword.base.ServiceDocument;
|
|
||||||
import org.purl.sword.base.SwordAcceptPackaging;
|
|
||||||
import org.purl.sword.base.Workspace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example implementation of a command line client. This can send out service
|
|
||||||
* document requests and print out the results and process posting a file to
|
|
||||||
* either a single or multiple destinations. The command line options are
|
|
||||||
* initialised prior to calling the class. The options are passed into the
|
|
||||||
* run(ClientOptions) method.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class CmdClient implements ClientType {
|
|
||||||
/**
|
|
||||||
* The client that is used to process the service and post requests.
|
|
||||||
*/
|
|
||||||
private SWORDClient client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of the options that can be specified on the command line.
|
|
||||||
*/
|
|
||||||
private ClientOptions options;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger.
|
|
||||||
*/
|
|
||||||
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(CmdClient.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of the class and create an instance of the
|
|
||||||
* client.
|
|
||||||
*/
|
|
||||||
public CmdClient() {
|
|
||||||
client = new Client();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the options that have been initialised from the command line.
|
|
||||||
* This will call one of service(), post() or multiPost().
|
|
||||||
*/
|
|
||||||
public void process() {
|
|
||||||
if (options.getProxyHost() != null) {
|
|
||||||
client.setProxy(options.getProxyHost(), options.getProxyPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String accessType = options.getAccessType();
|
|
||||||
if (ClientOptions.TYPE_SERVICE.equals(accessType)) {
|
|
||||||
service();
|
|
||||||
} else if (ClientOptions.TYPE_POST.equals(accessType)) {
|
|
||||||
post();
|
|
||||||
} else if (ClientOptions.TYPE_MULTI_POST.equals(accessType)) {
|
|
||||||
System.out.println("checking multi-post");
|
|
||||||
multiPost();
|
|
||||||
} else {
|
|
||||||
System.out.println("Access type not recognised.");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (MalformedURLException mex) {
|
|
||||||
System.out
|
|
||||||
.println("The specified href was not valid: " + options.getHref() + " message: " + mex.getMessage());
|
|
||||||
} catch (SWORDClientException ex) {
|
|
||||||
System.out.println("Exception: " + ex.getMessage());
|
|
||||||
log.error("Unable to process request", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the service operation. Output the results of the service request.
|
|
||||||
*
|
|
||||||
* @throws SWORDClientException if there is an error processing the service request.
|
|
||||||
* @throws MalformedURLException if there is an error with the URL for the service request.
|
|
||||||
*/
|
|
||||||
private void service()
|
|
||||||
throws SWORDClientException, MalformedURLException {
|
|
||||||
String href = options.getHref();
|
|
||||||
initialiseServer(href, options.getUsername(), options.getPassword());
|
|
||||||
|
|
||||||
ServiceDocument document = client.getServiceDocument(href, options.getOnBehalfOf());
|
|
||||||
Status status = client.getStatus();
|
|
||||||
System.out.println("The status is: " + status);
|
|
||||||
|
|
||||||
if (status.getCode() == 200) {
|
|
||||||
log.debug("message is: " + document.marshall());
|
|
||||||
|
|
||||||
System.out.println("\nThe following Details were retrieved: ");
|
|
||||||
System.out.println("SWORD Version: "
|
|
||||||
+ document.getService().getVersion());
|
|
||||||
System.out.println("Supports NoOp? " + document.getService().isNoOp());
|
|
||||||
System.out.println("Supports Verbose? "
|
|
||||||
+ document.getService().isVerbose());
|
|
||||||
System.out.println("Max Upload File Size "
|
|
||||||
+ document.getService().getMaxUploadSize() + " kB");
|
|
||||||
|
|
||||||
Iterator<Workspace> workspaces = document.getService().getWorkspaces();
|
|
||||||
for (; workspaces.hasNext(); ) {
|
|
||||||
Workspace workspace = workspaces.next();
|
|
||||||
System.out.println("\nWorkspace Title: '"
|
|
||||||
+ workspace.getTitle() + "'");
|
|
||||||
|
|
||||||
System.out.println("\n+ Collections ---");
|
|
||||||
// process the collections
|
|
||||||
Iterator<Collection> collections = workspace
|
|
||||||
.collectionIterator();
|
|
||||||
for (; collections.hasNext(); ) {
|
|
||||||
Collection collection = collections.next();
|
|
||||||
System.out.println("\nCollection location: "
|
|
||||||
+ collection.getLocation());
|
|
||||||
System.out.println("Collection title: "
|
|
||||||
+ collection.getTitle());
|
|
||||||
System.out
|
|
||||||
.println("Abstract: " + collection.getAbstract());
|
|
||||||
System.out.println("Collection Policy: "
|
|
||||||
+ collection.getCollectionPolicy());
|
|
||||||
System.out.println("Treatment: "
|
|
||||||
+ collection.getTreatment());
|
|
||||||
System.out.println("Mediation: "
|
|
||||||
+ collection.getMediation());
|
|
||||||
|
|
||||||
String[] accepts = collection.getAccepts();
|
|
||||||
if (accepts != null && accepts.length == 0) {
|
|
||||||
System.out.println("Accepts: none specified");
|
|
||||||
} else {
|
|
||||||
for (String s : accepts) {
|
|
||||||
System.out.println("Accepts: " + s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<SwordAcceptPackaging> acceptsPackaging = collection.getAcceptPackaging();
|
|
||||||
|
|
||||||
StringBuilder acceptPackagingList = new StringBuilder();
|
|
||||||
for (Iterator i = acceptsPackaging.iterator(); i.hasNext(); ) {
|
|
||||||
SwordAcceptPackaging accept = (SwordAcceptPackaging) i.next();
|
|
||||||
acceptPackagingList.append(accept.getContent()).append(" (").append(accept.getQualityValue())
|
|
||||||
.append("), ");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Accepts Packaging: " + acceptPackagingList.toString());
|
|
||||||
}
|
|
||||||
System.out.println("+ End of Collections ---");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a post. If any of the destination URL, the filename and the
|
|
||||||
* filetype are missing, the user will be prompted to enter the values.
|
|
||||||
*
|
|
||||||
* @throws SWORDClientException if there is an error processing the post for a requested
|
|
||||||
* destination.
|
|
||||||
* @throws MalformedURLException if there is an error with the URL for the post.
|
|
||||||
*/
|
|
||||||
private void post()
|
|
||||||
throws SWORDClientException, MalformedURLException {
|
|
||||||
String url = options.getHref();
|
|
||||||
if (url == null) {
|
|
||||||
url = readLine("Please enter the URL for the deposit: ");
|
|
||||||
}
|
|
||||||
|
|
||||||
initialiseServer(url, options.getUsername(), options.getPassword());
|
|
||||||
String file = options.getFilename();
|
|
||||||
if (file == null) {
|
|
||||||
file = readLine("Please enter the filename to deposit: ");
|
|
||||||
}
|
|
||||||
String type = options.getFiletype();
|
|
||||||
if (type == null) {
|
|
||||||
type = readLine("Please enter the file type, e.g. application/zip: ");
|
|
||||||
}
|
|
||||||
|
|
||||||
PostMessage message = new PostMessage();
|
|
||||||
message.setFilepath(file);
|
|
||||||
message.setDestination(url);
|
|
||||||
message.setFiletype(type);
|
|
||||||
message.setUseMD5(options.isMd5());
|
|
||||||
message.setVerbose(options.isVerbose());
|
|
||||||
message.setNoOp(options.isNoOp());
|
|
||||||
message.setFormatNamespace(options.getFormatNamespace());
|
|
||||||
message.setOnBehalfOf(options.getOnBehalfOf());
|
|
||||||
message.setChecksumError(options.getChecksumError());
|
|
||||||
message.setUserAgent(ClientConstants.SERVICE_NAME);
|
|
||||||
|
|
||||||
processPost(message);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform a multi-post. Iterate over the list of -dest arguments in the command line
|
|
||||||
* options. For each -dest argument, attempt to post the file to the server.
|
|
||||||
*
|
|
||||||
* @throws SWORDClientException if there is an error processing the post for a requested
|
|
||||||
* destination.
|
|
||||||
* @throws MalformedURLException if there is an error with the URL for the post.
|
|
||||||
*/
|
|
||||||
private void multiPost()
|
|
||||||
throws SWORDClientException, MalformedURLException {
|
|
||||||
// request the common information
|
|
||||||
String file = options.getFilename();
|
|
||||||
if (file == null) {
|
|
||||||
file = readLine("Please enter the filename to deposit: ");
|
|
||||||
}
|
|
||||||
String type = options.getFiletype();
|
|
||||||
if (type == null) {
|
|
||||||
type = readLine("Please enter the file type, e.g. application/zip: ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// process this information for each of the specified destinations
|
|
||||||
PostDestination destination;
|
|
||||||
String url = null;
|
|
||||||
|
|
||||||
Iterator<PostDestination> iterator = options.getMultiPost();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
destination = iterator.next();
|
|
||||||
url = destination.getUrl();
|
|
||||||
initialiseServer(url, destination.getUsername(), destination.getPassword());
|
|
||||||
|
|
||||||
String onBehalfOf = destination.getOnBehalfOf();
|
|
||||||
if (onBehalfOf == null) {
|
|
||||||
onBehalfOf = "";
|
|
||||||
} else {
|
|
||||||
onBehalfOf = " on behalf of: " + onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Sending file to: " + url + " for: " + destination.getUsername() +
|
|
||||||
onBehalfOf);
|
|
||||||
PostMessage message = new PostMessage();
|
|
||||||
message.setFilepath(file);
|
|
||||||
message.setDestination(url);
|
|
||||||
message.setFiletype(type);
|
|
||||||
message.setUseMD5(options.isMd5());
|
|
||||||
message.setVerbose(options.isVerbose());
|
|
||||||
message.setNoOp(options.isNoOp());
|
|
||||||
message.setFormatNamespace(options.getFormatNamespace());
|
|
||||||
message.setOnBehalfOf(destination.getOnBehalfOf());
|
|
||||||
message.setChecksumError(options.getChecksumError());
|
|
||||||
message.setUserAgent(ClientConstants.SERVICE_NAME);
|
|
||||||
|
|
||||||
processPost(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the post response. The message contains the list of arguments
|
|
||||||
* for the post. The method will then print out the details of the
|
|
||||||
* response.
|
|
||||||
*
|
|
||||||
* @param message The post options.
|
|
||||||
* @throws SWORDClientException if there is an error accessing the
|
|
||||||
* post response.
|
|
||||||
*/
|
|
||||||
protected void processPost(PostMessage message)
|
|
||||||
throws SWORDClientException {
|
|
||||||
DepositResponse response = client.postFile(message);
|
|
||||||
|
|
||||||
System.out.println("The status is: " + client.getStatus());
|
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
log.debug("message is: " + response.marshall());
|
|
||||||
|
|
||||||
// iterate over the data and output it
|
|
||||||
SWORDEntry entry = response.getEntry();
|
|
||||||
|
|
||||||
|
|
||||||
System.out.println("Id: " + entry.getId());
|
|
||||||
Title title = entry.getTitle();
|
|
||||||
if (title != null) {
|
|
||||||
System.out.print("Title: " + title.getContent() + " type: ");
|
|
||||||
if (title.getType() != null) {
|
|
||||||
System.out.println(title.getType().toString());
|
|
||||||
} else {
|
|
||||||
System.out.println("Not specified.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// process the authors
|
|
||||||
Iterator<Author> authors = entry.getAuthors();
|
|
||||||
while (authors.hasNext()) {
|
|
||||||
Author author = authors.next();
|
|
||||||
System.out.println("Author - " + author.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<String> categories = entry.getCategories();
|
|
||||||
while (categories.hasNext()) {
|
|
||||||
System.out.println("Category: " + categories.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<Contributor> contributors = entry.getContributors();
|
|
||||||
while (contributors.hasNext()) {
|
|
||||||
Contributor contributor = contributors.next();
|
|
||||||
System.out.println("Contributor - " + contributor.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<Link> links = entry.getLinks();
|
|
||||||
while (links.hasNext()) {
|
|
||||||
Link link = links.next();
|
|
||||||
System.out.println(link.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Generator generator = entry.getGenerator();
|
|
||||||
if (generator != null) {
|
|
||||||
System.out.println("Generator - " + generator.toString());
|
|
||||||
} else {
|
|
||||||
System.out.println("There is no generator");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Published: " + entry.getPublished());
|
|
||||||
|
|
||||||
Content content = entry.getContent();
|
|
||||||
if (content != null) {
|
|
||||||
System.out.println(content.toString());
|
|
||||||
} else {
|
|
||||||
System.out.println("There is no content element.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Rights right = entry.getRights();
|
|
||||||
if (right != null) {
|
|
||||||
System.out.println(right.toString());
|
|
||||||
} else {
|
|
||||||
System.out.println("There is no right element.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Summary summary = entry.getSummary();
|
|
||||||
if (summary != null) {
|
|
||||||
|
|
||||||
System.out.println(summary.toString());
|
|
||||||
} else {
|
|
||||||
System.out.println("There is no summary element.");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Update: " + entry.getUpdated());
|
|
||||||
System.out.println("Published: " + entry.getPublished());
|
|
||||||
System.out.println("Verbose Description: " + entry.getVerboseDescription());
|
|
||||||
System.out.println("Treatment: " + entry.getTreatment());
|
|
||||||
System.out.println("Packaging: " + entry.getPackaging());
|
|
||||||
|
|
||||||
if (entry.isNoOpSet()) {
|
|
||||||
System.out.println("NoOp: " + entry.isNoOp());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.out.println("No valid Entry document was received from the server");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the server. Set the server that will be connected to and
|
|
||||||
* initialise any username and password. If the username and password are
|
|
||||||
* either null or contain empty strings, the user credentials will be cleared.
|
|
||||||
*
|
|
||||||
* @param location The location to connect to. This is a URL, of the format,
|
|
||||||
* http://a.host.com:port/. The host name and port number will
|
|
||||||
* be extracted. If the port is not specified, a default port of
|
|
||||||
* 80 will be used.
|
|
||||||
* @param username The username. If this is null or an empty string, the basic
|
|
||||||
* credentials will be cleared.
|
|
||||||
* @param password The password. If this is null or an empty string, the basic
|
|
||||||
* credentials will be cleared.
|
|
||||||
* @throws MalformedURLException if there is an error processing the URL.
|
|
||||||
*/
|
|
||||||
private void initialiseServer(String location, String username, String password)
|
|
||||||
throws MalformedURLException {
|
|
||||||
URL url = new URL(location);
|
|
||||||
int port = url.getPort();
|
|
||||||
if (port == -1) {
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
client.setServer(url.getHost(), port);
|
|
||||||
|
|
||||||
if (username != null && username.length() > 0 &&
|
|
||||||
password != null && password.length() > 0) {
|
|
||||||
log.info("Setting the username/password: " + username + " "
|
|
||||||
+ password);
|
|
||||||
client.setCredentials(username, password);
|
|
||||||
} else {
|
|
||||||
client.clearCredentials();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a line of text from System.in. If there is an error reading
|
|
||||||
* from the input, the prompt will be redisplayed and the user asked
|
|
||||||
* to try again.
|
|
||||||
*
|
|
||||||
* @param prompt The prompt to display before the prompt.
|
|
||||||
* @return The string that is read from the line.
|
|
||||||
*/
|
|
||||||
private String readLine(String prompt) {
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
|
||||||
System.in));
|
|
||||||
String result = null;
|
|
||||||
|
|
||||||
boolean ok = false;
|
|
||||||
while (!ok) {
|
|
||||||
try {
|
|
||||||
System.out.print(prompt);
|
|
||||||
System.out.flush();
|
|
||||||
result = reader.readLine();
|
|
||||||
ok = true;
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.out.println("There was an error with your input. Please try again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the client and process the specified options.
|
|
||||||
*
|
|
||||||
* @param options The command line options.
|
|
||||||
*/
|
|
||||||
public void run(ClientOptions options) {
|
|
||||||
this.options = options;
|
|
||||||
process();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A stream that will write any output to the specified panel.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class DebugOutputStream extends OutputStream {
|
|
||||||
/**
|
|
||||||
* Panel that will display the messages.
|
|
||||||
*/
|
|
||||||
private MessageOutputPanel panel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance and specify the panel that will receive the output.
|
|
||||||
*
|
|
||||||
* @param panel The panel.
|
|
||||||
*/
|
|
||||||
public DebugOutputStream(MessageOutputPanel panel) {
|
|
||||||
this.panel = panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the write method from OutputStream. Capture the char and
|
|
||||||
* send it to the panel.
|
|
||||||
*
|
|
||||||
* @param arg0 The output character, expressed as an integer.
|
|
||||||
* @see java.io.OutputStream#write(int)
|
|
||||||
*/
|
|
||||||
public void write(int arg0) throws IOException {
|
|
||||||
panel.addCharacter(Character.valueOf((char) arg0));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,138 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import java.awt.GridBagConstraints;
|
|
||||||
import java.awt.GridBagLayout;
|
|
||||||
import java.awt.Insets;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTextArea;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Panel to display output messages. Text or characters can be sent to the
|
|
||||||
* panel for display. The panel also includes a button to clear any
|
|
||||||
* text that is currently displayed.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class MessageOutputPanel extends JPanel
|
|
||||||
implements ActionListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The text area that displays the messages.
|
|
||||||
*/
|
|
||||||
private JTextArea messages = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance and initialise the panel.
|
|
||||||
*/
|
|
||||||
public MessageOutputPanel() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
setLayout(new GridBagLayout());
|
|
||||||
|
|
||||||
messages = new JTextArea();
|
|
||||||
|
|
||||||
JScrollPane detailsPane = new JScrollPane(messages,
|
|
||||||
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
||||||
JButton clearButton = new JButton("Clear");
|
|
||||||
clearButton.addActionListener(this);
|
|
||||||
|
|
||||||
//add components and set constraints
|
|
||||||
//dpc = details pane constraint
|
|
||||||
GridBagConstraints dpc = new GridBagConstraints();
|
|
||||||
dpc.gridx = 0;
|
|
||||||
dpc.gridy = 0;
|
|
||||||
dpc.fill = GridBagConstraints.BOTH;
|
|
||||||
dpc.weightx = 0.75;
|
|
||||||
dpc.weighty = 0.45;
|
|
||||||
dpc.gridwidth = 2;
|
|
||||||
dpc.insets = new Insets(5, 5, 5, 5);
|
|
||||||
add(detailsPane, dpc);
|
|
||||||
|
|
||||||
//cbc = clear button constraint
|
|
||||||
GridBagConstraints cbc = new GridBagConstraints();
|
|
||||||
cbc.gridx = 1;
|
|
||||||
cbc.gridy = 1;
|
|
||||||
cbc.insets = new Insets(0, 0, 5, 5);
|
|
||||||
cbc.anchor = GridBagConstraints.LINE_END;
|
|
||||||
add(clearButton, cbc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a message to the text area. The message will be added with a carriage return.
|
|
||||||
*
|
|
||||||
* @param message The message.
|
|
||||||
*/
|
|
||||||
public void addMessage(String message) {
|
|
||||||
messages.insert(message + "\n", messages.getDocument().getLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a single character to the text area.
|
|
||||||
*
|
|
||||||
* @param character The character.
|
|
||||||
*/
|
|
||||||
public void addCharacter(Character character) {
|
|
||||||
messages.insert(character.toString(), messages.getDocument().getLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the text from the display.
|
|
||||||
*
|
|
||||||
* @param arg0 The action event.
|
|
||||||
*
|
|
||||||
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
|
|
||||||
*/
|
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
|
||||||
messages.setText("");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,140 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Details for a destination. This is used to represent a destination. If
|
|
||||||
* expressed as a string, the destination looks like:
|
|
||||||
* <pre>
|
|
||||||
* <user>[<onBehalfOf>]:<password>@<url>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class PostDestination {
|
|
||||||
/**
|
|
||||||
* URL for the post destination.
|
|
||||||
*/
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The username.
|
|
||||||
*/
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The password.
|
|
||||||
*/
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The onBehalfOf ID.
|
|
||||||
*/
|
|
||||||
private String onBehalfOf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*/
|
|
||||||
public PostDestination() {
|
|
||||||
// No-Op
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*
|
|
||||||
* @param url The url.
|
|
||||||
* @param username The username.
|
|
||||||
* @param password The password.
|
|
||||||
* @param onBehalfOf The onBehalfOf id.
|
|
||||||
*/
|
|
||||||
public PostDestination(String url, String username, String password, String onBehalfOf) {
|
|
||||||
this.url = url;
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
this.onBehalfOf = onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the url
|
|
||||||
*/
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param url the url to set
|
|
||||||
*/
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the username
|
|
||||||
*/
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param username the username to set
|
|
||||||
*/
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the password
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a string representation of this object.
|
|
||||||
*
|
|
||||||
* @return The string.
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
buffer.append(username);
|
|
||||||
if (onBehalfOf != null) {
|
|
||||||
buffer.append("[");
|
|
||||||
buffer.append(onBehalfOf);
|
|
||||||
buffer.append("]");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password != null) {
|
|
||||||
buffer.append(":******");
|
|
||||||
}
|
|
||||||
buffer.append("@");
|
|
||||||
buffer.append(url);
|
|
||||||
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,599 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
|
||||||
import javax.swing.DefaultListModel;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JCheckBox;
|
|
||||||
import javax.swing.JFileChooser;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JList;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JPasswordField;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
|
||||||
import javax.swing.event.ChangeListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog for users to enter details of post destinations.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class PostDialog
|
|
||||||
implements ActionListener, ChangeListener {
|
|
||||||
/**
|
|
||||||
* label for the browse command.
|
|
||||||
*/
|
|
||||||
protected static final String BROWSE = "browse";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* label for the add command.
|
|
||||||
*/
|
|
||||||
protected static final String ADD = "add";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* label for the edit command.
|
|
||||||
*/
|
|
||||||
protected static final String EDIT = "edit";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* label for the delete command.
|
|
||||||
*/
|
|
||||||
protected static final String DELETE = "delete";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* label for the clear command.
|
|
||||||
*/
|
|
||||||
protected static final String CLEAR = "clear";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Username combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post Location combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox postLocation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password field.
|
|
||||||
*/
|
|
||||||
private JPasswordField password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The file combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox file;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The filetype combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox fileType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The onBehalfOf combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox onBehalfOf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The md5 checkbox.
|
|
||||||
*/
|
|
||||||
private JCheckBox useMD5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The corruptMD5 checkbox.
|
|
||||||
*/
|
|
||||||
private JCheckBox corruptMD5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The corruptRequest checkbox.
|
|
||||||
*/
|
|
||||||
private JCheckBox corruptRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The useNoOp checkbox.
|
|
||||||
*/
|
|
||||||
private JCheckBox useNoOp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The verbose checkbox.
|
|
||||||
*/
|
|
||||||
private JCheckBox useVerbose;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The format namespace combo box.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox formatNamespace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The list of post destinations.
|
|
||||||
*/
|
|
||||||
private JList list;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The parent frame for the dialog that is displayed.
|
|
||||||
*/
|
|
||||||
private JFrame parentFrame = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array that lists the labels for the buttons on the panel.
|
|
||||||
*/
|
|
||||||
private static Object[] options = {"Post File", "Cancel"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The panel that holds the controls to show.
|
|
||||||
*/
|
|
||||||
private JPanel controls = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param parentFrame the parent of this dialog.
|
|
||||||
*/
|
|
||||||
public PostDialog(JFrame parentFrame) {
|
|
||||||
this.parentFrame = parentFrame;
|
|
||||||
controls = createControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the dialog with ok and cancel options.
|
|
||||||
* @return The return value from displaying JOptionPane. Either
|
|
||||||
* JOptionPane.OK_OPTION or JOptionPane.CANCEL_OPTION.
|
|
||||||
*/
|
|
||||||
public int show() {
|
|
||||||
int result = JOptionPane.showOptionDialog(parentFrame,
|
|
||||||
controls,
|
|
||||||
"Post Document",
|
|
||||||
JOptionPane.OK_CANCEL_OPTION,
|
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
|
||||||
null,
|
|
||||||
options,
|
|
||||||
null);
|
|
||||||
|
|
||||||
if (result == JOptionPane.OK_OPTION) {
|
|
||||||
// update the combo boxes with the values
|
|
||||||
username.updateList();
|
|
||||||
file.updateList();
|
|
||||||
fileType.updateList();
|
|
||||||
onBehalfOf.updateList();
|
|
||||||
formatNamespace.updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the controls for the main panel.
|
|
||||||
*
|
|
||||||
* @return The panel.
|
|
||||||
*/
|
|
||||||
protected final JPanel createControls() {
|
|
||||||
file = new SWORDComboBox();
|
|
||||||
JPanel filePanel = new JPanel(new BorderLayout());
|
|
||||||
filePanel.add(file, BorderLayout.CENTER);
|
|
||||||
JButton browse = new JButton("Browse...");
|
|
||||||
browse.setActionCommand(BROWSE);
|
|
||||||
browse.addActionListener(this);
|
|
||||||
|
|
||||||
filePanel.add(browse, BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
fileType = new SWORDComboBox();
|
|
||||||
String type = "application/zip";
|
|
||||||
fileType.addItem(type);
|
|
||||||
fileType.setSelectedItem(type);
|
|
||||||
|
|
||||||
// controls that will be used in the second dialog
|
|
||||||
postLocation = new SWORDComboBox();
|
|
||||||
username = new SWORDComboBox();
|
|
||||||
password = new JPasswordField();
|
|
||||||
onBehalfOf = new SWORDComboBox();
|
|
||||||
|
|
||||||
|
|
||||||
useMD5 = new JCheckBox();
|
|
||||||
useMD5.addChangeListener(this);
|
|
||||||
corruptMD5 = new JCheckBox();
|
|
||||||
corruptRequest = new JCheckBox();
|
|
||||||
useNoOp = new JCheckBox();
|
|
||||||
useVerbose = new JCheckBox();
|
|
||||||
formatNamespace = new SWORDComboBox();
|
|
||||||
|
|
||||||
JLabel fileLabel = new JLabel("File:", JLabel.TRAILING);
|
|
||||||
JLabel fileTypeLabel = new JLabel("File Type:", JLabel.TRAILING);
|
|
||||||
JLabel useMD5Label = new JLabel("Use MD5:", JLabel.TRAILING);
|
|
||||||
JLabel corruptMD5Label = new JLabel("Corrupt MD5:", JLabel.TRAILING);
|
|
||||||
JLabel corruptRequestLabel = new JLabel("Corrupt Request:", JLabel.TRAILING);
|
|
||||||
//JLabel corruptMD5Label = new JLabel("Corrupt MD5:", JLabel.TRAILING);
|
|
||||||
JLabel useNoOpLabel = new JLabel("Use noOp:", JLabel.TRAILING);
|
|
||||||
JLabel useVerboseLabel = new JLabel("Use verbose:", JLabel.TRAILING);
|
|
||||||
JLabel formatNamespaceLabel = new JLabel("X-Packaging:", JLabel.TRAILING);
|
|
||||||
JLabel userAgentLabel = new JLabel("User Agent:", JLabel.TRAILING);
|
|
||||||
JLabel userAgentNameLabel = new JLabel(ClientConstants.SERVICE_NAME, JLabel.LEADING);
|
|
||||||
|
|
||||||
SWORDFormPanel panel = new SWORDFormPanel();
|
|
||||||
panel.addFirstRow(new JLabel("Please enter the details for the post operation"));
|
|
||||||
|
|
||||||
JPanel destinations = createDestinationsPanel();
|
|
||||||
|
|
||||||
panel.addRow(new JLabel("Destinations:"), destinations);
|
|
||||||
panel.addRow(fileLabel, filePanel);
|
|
||||||
panel.addRow(fileTypeLabel, fileType);
|
|
||||||
panel.addRow(useMD5Label, useMD5);
|
|
||||||
panel.addRow(corruptMD5Label, corruptMD5);
|
|
||||||
panel.addRow(corruptRequestLabel, corruptRequest);
|
|
||||||
panel.addRow(useNoOpLabel, useNoOp);
|
|
||||||
panel.addRow(useVerboseLabel, useVerbose);
|
|
||||||
panel.addRow(formatNamespaceLabel, formatNamespace);
|
|
||||||
panel.addRow(userAgentLabel, userAgentNameLabel);
|
|
||||||
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the destinations panel. This contains a list and four buttons
|
|
||||||
* to operate on values in the list.
|
|
||||||
*
|
|
||||||
* @return The panel containing the controls.
|
|
||||||
*/
|
|
||||||
protected JPanel createDestinationsPanel() {
|
|
||||||
DefaultListModel model = new DefaultListModel();
|
|
||||||
list = new JList(model);
|
|
||||||
JScrollPane jsp = new JScrollPane(list);
|
|
||||||
|
|
||||||
JPanel destinations = new JPanel(new BorderLayout());
|
|
||||||
destinations.add(jsp, BorderLayout.CENTER);
|
|
||||||
JPanel destinationButtons = new JPanel();
|
|
||||||
|
|
||||||
JButton addButton = new JButton("Add");
|
|
||||||
addButton.setActionCommand(ADD);
|
|
||||||
addButton.addActionListener(this);
|
|
||||||
|
|
||||||
JButton editButton = new JButton("Edit");
|
|
||||||
editButton.setActionCommand(EDIT);
|
|
||||||
editButton.addActionListener(this);
|
|
||||||
|
|
||||||
JButton deleteButton = new JButton("Delete");
|
|
||||||
deleteButton.setActionCommand(DELETE);
|
|
||||||
deleteButton.addActionListener(this);
|
|
||||||
|
|
||||||
JButton clearButton = new JButton("Clear");
|
|
||||||
clearButton.setActionCommand(CLEAR);
|
|
||||||
clearButton.addActionListener(this);
|
|
||||||
|
|
||||||
destinationButtons.add(addButton);
|
|
||||||
destinationButtons.add(editButton);
|
|
||||||
destinationButtons.add(deleteButton);
|
|
||||||
destinationButtons.add(clearButton);
|
|
||||||
|
|
||||||
destinations.add(destinationButtons, BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
return destinations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the button click to select a file to upload.
|
|
||||||
*/
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
|
||||||
String cmd = evt.getActionCommand();
|
|
||||||
|
|
||||||
if (BROWSE.equals(cmd)) {
|
|
||||||
JFileChooser chooser = new JFileChooser();
|
|
||||||
chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
|
|
||||||
int returnVal = chooser.showOpenDialog(parentFrame);
|
|
||||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
||||||
file.setSelectedItem(chooser.getSelectedFile().getAbsolutePath());
|
|
||||||
}
|
|
||||||
} else if (ADD.equals(cmd)) {
|
|
||||||
PostDestination dest = showDestinationDialog(null);
|
|
||||||
if (dest != null) {
|
|
||||||
((DefaultListModel) list.getModel()).addElement(dest);
|
|
||||||
}
|
|
||||||
} else if (EDIT.equals(cmd)) {
|
|
||||||
PostDestination dest = (PostDestination) list.getSelectedValue();
|
|
||||||
if (dest != null) {
|
|
||||||
showDestinationDialog(dest);
|
|
||||||
list.repaint();
|
|
||||||
}
|
|
||||||
} else if (DELETE.equals(cmd)) {
|
|
||||||
if (list.getSelectedIndex() != -1) {
|
|
||||||
((DefaultListModel) list.getModel()).removeElementAt(list.getSelectedIndex());
|
|
||||||
}
|
|
||||||
} else if (CLEAR.equals(cmd)) {
|
|
||||||
((DefaultListModel) list.getModel()).clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the destination dialog. This is used to enter the URL,
|
|
||||||
* username, password and onBehalfOf name for a destination.
|
|
||||||
*
|
|
||||||
* @param destination The post destination. If this is not null, the values
|
|
||||||
* in the object are used to set the current values
|
|
||||||
* in the dialog controls.
|
|
||||||
* @return The post destination value.
|
|
||||||
*/
|
|
||||||
public PostDestination showDestinationDialog(PostDestination destination) {
|
|
||||||
SWORDFormPanel panel = new SWORDFormPanel();
|
|
||||||
panel.addFirstRow(new JLabel("Please enter the details for the post operation"));
|
|
||||||
|
|
||||||
JLabel postLabel = new JLabel("Post Location:", JLabel.TRAILING);
|
|
||||||
JLabel userLabel = new JLabel("Username:", JLabel.TRAILING);
|
|
||||||
JLabel passwordLabel = new JLabel("Password:", JLabel.TRAILING);
|
|
||||||
JLabel onBehalfOfLabel = new JLabel("On Behalf Of:", JLabel.TRAILING);
|
|
||||||
|
|
||||||
panel.addRow(postLabel, postLocation);
|
|
||||||
panel.addRow(userLabel, username);
|
|
||||||
panel.addRow(passwordLabel, password);
|
|
||||||
panel.addRow(onBehalfOfLabel, onBehalfOf);
|
|
||||||
|
|
||||||
if (destination != null) {
|
|
||||||
postLocation.insertItem(destination.getUrl());
|
|
||||||
username.insertItem(destination.getUsername());
|
|
||||||
password.setText(destination.getPassword());
|
|
||||||
onBehalfOf.insertItem(destination.getOnBehalfOf());
|
|
||||||
} else {
|
|
||||||
String s = "";
|
|
||||||
postLocation.insertItem(s);
|
|
||||||
//postLocation.setSelectedItem(s);
|
|
||||||
username.insertItem(s);
|
|
||||||
username.setSelectedItem(s);
|
|
||||||
password.setText(s);
|
|
||||||
onBehalfOf.insertItem(s);
|
|
||||||
onBehalfOf.setSelectedItem(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int result = JOptionPane.showOptionDialog(null,
|
|
||||||
panel,
|
|
||||||
"Destination",
|
|
||||||
JOptionPane.OK_CANCEL_OPTION,
|
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
|
||||||
null,
|
|
||||||
new String[] {"OK", "Cancel"},
|
|
||||||
null);
|
|
||||||
|
|
||||||
if (result == JOptionPane.OK_OPTION) {
|
|
||||||
postLocation.updateList();
|
|
||||||
username.updateList();
|
|
||||||
onBehalfOf.updateList();
|
|
||||||
|
|
||||||
if (destination == null) {
|
|
||||||
destination = new PostDestination();
|
|
||||||
}
|
|
||||||
|
|
||||||
destination.setUrl(postLocation.getText());
|
|
||||||
destination.setUsername(username.getText());
|
|
||||||
String pass = new String(password.getPassword());
|
|
||||||
if (pass.length() > 0) {
|
|
||||||
destination.setPassword(pass);
|
|
||||||
} else {
|
|
||||||
destination.setPassword(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String obo = onBehalfOf.getText();
|
|
||||||
if (obo.length() > 0) {
|
|
||||||
destination.setOnBehalfOf(onBehalfOf.getText());
|
|
||||||
} else {
|
|
||||||
destination.setOnBehalfOf(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the list of Post Destinations.
|
|
||||||
* @return The destinations.
|
|
||||||
*/
|
|
||||||
public PostDestination[] getDestinations() {
|
|
||||||
DefaultListModel model = (DefaultListModel) list.getModel();
|
|
||||||
PostDestination[] destinations = new PostDestination[model.size()];
|
|
||||||
for (int i = 0; i < model.size(); i++) {
|
|
||||||
destinations[i] = (PostDestination) model.get(i);
|
|
||||||
}
|
|
||||||
return destinations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file details.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getFile() {
|
|
||||||
return file.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the filetype value.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getFileType() {
|
|
||||||
return fileType.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the onBehalfOf value.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getOnBehalfOf() {
|
|
||||||
return onBehalfOf.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the format namespace value.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getFormatNamespace() {
|
|
||||||
return formatNamespace.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the MD5 checkbox is selected.
|
|
||||||
*
|
|
||||||
* @return True if the MD5 checkbox is selected.
|
|
||||||
*/
|
|
||||||
public boolean useMd5() {
|
|
||||||
return useMD5.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the noOp checkbox is selected.
|
|
||||||
*
|
|
||||||
* @return True if the checkbox is selected.
|
|
||||||
*/
|
|
||||||
public boolean useNoOp() {
|
|
||||||
return useNoOp.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the verbose checkbox is selected.
|
|
||||||
*
|
|
||||||
* @return True if the checkbox is selected.
|
|
||||||
*/
|
|
||||||
public boolean useVerbose() {
|
|
||||||
return useVerbose.isSelected();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the post location.
|
|
||||||
* @return The post location.
|
|
||||||
*/
|
|
||||||
public String getPostLocation() {
|
|
||||||
return postLocation.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the MD5 hash should be corrupted.
|
|
||||||
* @return True if the corrupt MD5 checkbox is selected. The MD5 checkbox
|
|
||||||
* must also be selected.
|
|
||||||
*/
|
|
||||||
public boolean corruptMD5() {
|
|
||||||
return (corruptMD5.isEnabled() && corruptMD5.isSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the POST request should be corrupted.
|
|
||||||
* @return True if the corrupt request checkbox is selected.
|
|
||||||
*/
|
|
||||||
public boolean corruptRequest() {
|
|
||||||
return (corruptRequest.isSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detect a state change event for the checkbox.
|
|
||||||
*
|
|
||||||
* @param evt The event.
|
|
||||||
*/
|
|
||||||
public void stateChanged(ChangeEvent evt) {
|
|
||||||
corruptMD5.setEnabled(useMD5.isSelected());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of user ids.
|
|
||||||
*
|
|
||||||
* @param users The user ids.
|
|
||||||
*/
|
|
||||||
public void addUserIds(String[] users) {
|
|
||||||
username.insertItems(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of deposit URLs.
|
|
||||||
*
|
|
||||||
* @param deposits The URLs.
|
|
||||||
*/
|
|
||||||
public void addDepositUrls(String[] deposits) {
|
|
||||||
postLocation.insertItems(deposits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of onBehalfOf names.
|
|
||||||
*
|
|
||||||
* @param users The names.
|
|
||||||
*/
|
|
||||||
public void addOnBehalfOf(String[] users) {
|
|
||||||
onBehalfOf.insertItems(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the list of formatNamespace strings.
|
|
||||||
*
|
|
||||||
* @param namespaces list of strings.
|
|
||||||
*/
|
|
||||||
public void addFormatNamespaces(String[] namespaces) {
|
|
||||||
formatNamespace.insertItems(namespaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of file types.
|
|
||||||
*
|
|
||||||
* @param types The file types.
|
|
||||||
*/
|
|
||||||
public void addFileTypes(String[] types) {
|
|
||||||
fileType.insertItems(types);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of file names.
|
|
||||||
* @param files The list of files.
|
|
||||||
*/
|
|
||||||
public void addFiles(String[] files) {
|
|
||||||
file.insertItems(files);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the deposit location.
|
|
||||||
*
|
|
||||||
* @param location The location.
|
|
||||||
*/
|
|
||||||
public void setDepositLocation(String location) {
|
|
||||||
postLocation.insertItem(location);
|
|
||||||
postLocation.setSelectedItem(location);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,344 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the details of a post to a server. The message holds all of the possible values
|
|
||||||
* that are to be sent from the client to the server. Not all elements of the message
|
|
||||||
* must be filled in. Any required fields are defined in the current SWORD specification.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class PostMessage {
|
|
||||||
/**
|
|
||||||
* The local filepath for the file to upload/deposit.
|
|
||||||
*/
|
|
||||||
private String filepath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL of the destination server.
|
|
||||||
*/
|
|
||||||
private String destination;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The filetype of the package that is to be uploaded.
|
|
||||||
*/
|
|
||||||
private String filetype;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The string with the username if the deposit is on behalf of another user.
|
|
||||||
*/
|
|
||||||
private String onBehalfOf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if an MD5 checksum should be sent with the deposit.
|
|
||||||
*/
|
|
||||||
private boolean useMD5;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the deposit is a test and should not result in an actual deposit.
|
|
||||||
*/
|
|
||||||
private boolean noOp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the verbose operation is requested.
|
|
||||||
*/
|
|
||||||
private boolean verbose;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The packaging format for the deposit.
|
|
||||||
*/
|
|
||||||
private String packaging;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the deposit should simulate a checksum error. The client should check this
|
|
||||||
* field to determine if a correct MD5 checksum should be sent or whether the checksum should
|
|
||||||
* be modified so that it generates an error at the server.
|
|
||||||
*/
|
|
||||||
private boolean checksumError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if the deposit should corrupt the POST header. The client should check this
|
|
||||||
* field to determine if a correct header should be sent or whether the header should
|
|
||||||
* be modified so that it generates an error at the server.
|
|
||||||
*/
|
|
||||||
private boolean corruptRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Slug header value.
|
|
||||||
*/
|
|
||||||
private String slug;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The user agent name
|
|
||||||
*/
|
|
||||||
private String userAgent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the filepath.
|
|
||||||
*
|
|
||||||
* @return The filepath.
|
|
||||||
*/
|
|
||||||
public String getFilepath() {
|
|
||||||
return filepath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the filename. This is the last element of the filepath
|
|
||||||
* that has been set in this class.
|
|
||||||
*
|
|
||||||
* @return filename
|
|
||||||
*/
|
|
||||||
public String getFilename() {
|
|
||||||
File file = new File(filepath);
|
|
||||||
return file.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the filepath.
|
|
||||||
*
|
|
||||||
* @param filepath The filepath.
|
|
||||||
*/
|
|
||||||
public void setFilepath(String filepath) {
|
|
||||||
this.filepath = filepath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the destination collection.
|
|
||||||
*
|
|
||||||
* @return The collection.
|
|
||||||
*/
|
|
||||||
public String getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the destination collection.
|
|
||||||
*
|
|
||||||
* @param destination The destination.
|
|
||||||
*/
|
|
||||||
public void setDestination(String destination) {
|
|
||||||
this.destination = destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the filetype.
|
|
||||||
* @return The filetype.
|
|
||||||
*/
|
|
||||||
public String getFiletype() {
|
|
||||||
return filetype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the filetype.
|
|
||||||
*
|
|
||||||
* @param filetype The filetype.
|
|
||||||
*/
|
|
||||||
public void setFiletype(String filetype) {
|
|
||||||
this.filetype = filetype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the onBehalfOf value.
|
|
||||||
*
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getOnBehalfOf() {
|
|
||||||
return onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the onBehalfOf value.
|
|
||||||
*
|
|
||||||
* @param onBehalfOf The value.
|
|
||||||
*/
|
|
||||||
public void setOnBehalfOf(String onBehalfOf) {
|
|
||||||
this.onBehalfOf = onBehalfOf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the MD5 status.
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public boolean isUseMD5() {
|
|
||||||
return useMD5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the md5 state.
|
|
||||||
*
|
|
||||||
* @param useMD5 True if the message should use an MD5 checksum.
|
|
||||||
*/
|
|
||||||
public void setUseMD5(boolean useMD5) {
|
|
||||||
this.useMD5 = useMD5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the no-op state.
|
|
||||||
*
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public boolean isNoOp() {
|
|
||||||
return noOp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the no-op state.
|
|
||||||
*
|
|
||||||
* @param noOp The no-op.
|
|
||||||
*/
|
|
||||||
public void setNoOp(boolean noOp) {
|
|
||||||
this.noOp = noOp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the verbose value.
|
|
||||||
*
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public boolean isVerbose() {
|
|
||||||
return verbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the verbose state.
|
|
||||||
*
|
|
||||||
* @param verbose True if the post message should send a
|
|
||||||
* verbose header.
|
|
||||||
*/
|
|
||||||
public void setVerbose(boolean verbose) {
|
|
||||||
this.verbose = verbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the packaging format.
|
|
||||||
*
|
|
||||||
* @return The value.
|
|
||||||
*/
|
|
||||||
public String getPackaging() {
|
|
||||||
return packaging;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the packaging format.
|
|
||||||
*
|
|
||||||
* @param packaging The packaging format.
|
|
||||||
*/
|
|
||||||
public void setFormatNamespace(String packaging) {
|
|
||||||
this.packaging = packaging;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of the checksum error.
|
|
||||||
*
|
|
||||||
* @return True if the client should simulate a checksum error.
|
|
||||||
*/
|
|
||||||
public boolean getChecksumError() {
|
|
||||||
return checksumError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the state of the checksum error.
|
|
||||||
*
|
|
||||||
* @param checksumError True if the item should include a checksum error.
|
|
||||||
*/
|
|
||||||
public void setChecksumError(boolean checksumError) {
|
|
||||||
this.checksumError = checksumError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status of the corrupt request flag.
|
|
||||||
*
|
|
||||||
* @return True if the client should corrupt the POST header.
|
|
||||||
*/
|
|
||||||
public boolean getCorruptRequest() {
|
|
||||||
return corruptRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the state of the corrupt request flag.
|
|
||||||
*
|
|
||||||
* @param corruptRequest True if the item should corrupt the POST header.
|
|
||||||
*/
|
|
||||||
public void setCorruptRequest(boolean corruptRequest) {
|
|
||||||
this.corruptRequest = corruptRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Slug value.
|
|
||||||
*
|
|
||||||
* @param slug The value.
|
|
||||||
*/
|
|
||||||
public void setSlug(String slug) {
|
|
||||||
this.slug = slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Slug value.
|
|
||||||
*
|
|
||||||
* @return The Slug.
|
|
||||||
*/
|
|
||||||
public String getSlug() {
|
|
||||||
return this.slug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the userAgent
|
|
||||||
*/
|
|
||||||
public String getUserAgent() {
|
|
||||||
return userAgent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the user agent
|
|
||||||
*
|
|
||||||
* @param userAgent the userAgent to set
|
|
||||||
*/
|
|
||||||
public void setUserAgent(String userAgent) {
|
|
||||||
this.userAgent = userAgent;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,240 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Properties;
|
|
||||||
import javax.swing.DefaultCellEditor;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
|
||||||
import javax.swing.table.TableCellEditor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog that is used to edit the collection of properties.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor, Suzana Barreto
|
|
||||||
*/
|
|
||||||
public class PropertiesDialog {
|
|
||||||
/**
|
|
||||||
* The parent frame for the dialog that is displayed.
|
|
||||||
*/
|
|
||||||
private JFrame parentFrame = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array that lists the labels for the buttons on the panel.
|
|
||||||
*/
|
|
||||||
private static Object[] options = {"OK", "Cancel"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The panel that holds the controls to show.
|
|
||||||
*/
|
|
||||||
private JPanel controls = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The configuration properties
|
|
||||||
*/
|
|
||||||
private Properties properties = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Table that is used to display the list of properties.
|
|
||||||
*/
|
|
||||||
private JTable propertiesTable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*
|
|
||||||
* @param parentFrame The parent frame for the dialog.
|
|
||||||
* @param props The properties lisst to display
|
|
||||||
*/
|
|
||||||
public PropertiesDialog(JFrame parentFrame, Properties props) {
|
|
||||||
this.parentFrame = parentFrame;
|
|
||||||
properties = props;
|
|
||||||
controls = createControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the controls that are to be displayed in the system.
|
|
||||||
*
|
|
||||||
* @return A panel that contains the controls.
|
|
||||||
*/
|
|
||||||
protected final JPanel createControls() {
|
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
|
||||||
propertiesTable = new JTable(new PropertiesModel());
|
|
||||||
((DefaultCellEditor) propertiesTable.getDefaultEditor(String.class)).setClickCountToStart(1);
|
|
||||||
JScrollPane scrollpane = new JScrollPane(propertiesTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
||||||
panel.add(scrollpane, BorderLayout.CENTER);
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the dialog and return the status code.
|
|
||||||
*
|
|
||||||
* @return The status code returned from the dialog.
|
|
||||||
*/
|
|
||||||
public int show() {
|
|
||||||
int result = JOptionPane.showOptionDialog(parentFrame,
|
|
||||||
controls,
|
|
||||||
"Edit Properties",
|
|
||||||
JOptionPane.OK_CANCEL_OPTION,
|
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
|
||||||
null,
|
|
||||||
options,
|
|
||||||
null);
|
|
||||||
|
|
||||||
// cancel any edit in the table. If there is a cell editing, the getEditingColumn will
|
|
||||||
// return a non-negative column number. This can be used to retreive the cell editor.
|
|
||||||
// The code then gets the default editor and calls the stopCellEditing. If custom
|
|
||||||
// editors are used, an additional check must be made to get the cell editor
|
|
||||||
// for a specific cell.
|
|
||||||
int column = propertiesTable.getEditingColumn();
|
|
||||||
|
|
||||||
if (column > -1) {
|
|
||||||
TableCellEditor editor = propertiesTable.getDefaultEditor(propertiesTable.getColumnClass(column));
|
|
||||||
if (editor != null) {
|
|
||||||
editor.stopCellEditing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A table model that is used to show the properties. The model links directly
|
|
||||||
* to the underlying properties object. As changes are made in the table, the
|
|
||||||
* corresponding changes are made in the properties object. The user can only
|
|
||||||
* edit the value column in the table.
|
|
||||||
*/
|
|
||||||
public class PropertiesModel extends AbstractTableModel {
|
|
||||||
/**
|
|
||||||
* Column names.
|
|
||||||
*/
|
|
||||||
private String columns[] = {"Property Name", "Value"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of the model. If no properties object exists,
|
|
||||||
* a default model is created. Note, this will allow the table to
|
|
||||||
* continue editing, although this value will not be passed back to
|
|
||||||
* the calling window.
|
|
||||||
*/
|
|
||||||
public PropertiesModel() {
|
|
||||||
super();
|
|
||||||
if (properties == null) {
|
|
||||||
properties = new Properties();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of columns.
|
|
||||||
*
|
|
||||||
* @return The number of columns.
|
|
||||||
*/
|
|
||||||
public int getColumnCount() {
|
|
||||||
return columns.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of rows.
|
|
||||||
*
|
|
||||||
* @return The number of rows.
|
|
||||||
*/
|
|
||||||
public int getRowCount() {
|
|
||||||
return properties.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value that is at the specified cell.
|
|
||||||
*
|
|
||||||
* @param row The row for the cell.
|
|
||||||
* @param col The column for the cell.
|
|
||||||
* @return The data value from the properties.
|
|
||||||
*/
|
|
||||||
public Object getValueAt(int row, int col) {
|
|
||||||
if (col == 0) {
|
|
||||||
return getKeyValue(row);
|
|
||||||
} else {
|
|
||||||
String key = getKeyValue(row);
|
|
||||||
return properties.get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the column name for the specified column.
|
|
||||||
*
|
|
||||||
* @param col The column number.
|
|
||||||
* @return The column name.
|
|
||||||
*/
|
|
||||||
public String getColumnName(int col) {
|
|
||||||
return columns[col];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the column class.
|
|
||||||
*
|
|
||||||
* @param col The column number.
|
|
||||||
* @return The class for the object found at the column position.
|
|
||||||
*/
|
|
||||||
public Class getColumnClass(int col) {
|
|
||||||
return getValueAt(0, col).getClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the cell can be edited. This model will only
|
|
||||||
* allow the second column to be edited.
|
|
||||||
*
|
|
||||||
* @param row The cell row.
|
|
||||||
* @param col The cell column.
|
|
||||||
* @return True if the cell can be edited. Otherwise, false.
|
|
||||||
*/
|
|
||||||
public boolean isCellEditable(int row, int col) {
|
|
||||||
if (col == 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value for the specified cell.
|
|
||||||
*
|
|
||||||
* @param value The value to set.
|
|
||||||
* @param row The row for the cell.
|
|
||||||
* @param col The column.
|
|
||||||
*/
|
|
||||||
public void setValueAt(Object value, int row, int col) {
|
|
||||||
String key = getKeyValue(row);
|
|
||||||
properties.setProperty(key, ((String) value));
|
|
||||||
fireTableCellUpdated(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Key value for the specified row.
|
|
||||||
*
|
|
||||||
* @param row The row.
|
|
||||||
* @return A string that shows the key value.
|
|
||||||
*/
|
|
||||||
public String getKeyValue(int row) {
|
|
||||||
int count = 0;
|
|
||||||
Enumeration<Object> k = properties.keys();
|
|
||||||
while (k.hasMoreElements()) {
|
|
||||||
String key = (String) k.nextElement();
|
|
||||||
if (count == row) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,85 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import org.purl.sword.base.DepositResponse;
|
|
||||||
import org.purl.sword.base.ServiceDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for any SWORD client implementation.
|
|
||||||
*/
|
|
||||||
public interface SWORDClient {
|
|
||||||
/**
|
|
||||||
* Set the server that is to be contacted on the next access.
|
|
||||||
*
|
|
||||||
* @param server The name of the server, e.g. www.aber.ac.uk
|
|
||||||
* @param port The port number, e.g. 80.
|
|
||||||
*/
|
|
||||||
public void setServer(String server, int port);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the user credentials that are to be used for subsequent accesses.
|
|
||||||
*
|
|
||||||
* @param username The username.
|
|
||||||
* @param password The password.
|
|
||||||
*/
|
|
||||||
public void setCredentials(String username, String password);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the credentials settings on the client.
|
|
||||||
*/
|
|
||||||
public void clearCredentials();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the proxy that is to be used for subsequent accesses.
|
|
||||||
*
|
|
||||||
* @param host The host name, e.g. cache.host.com.
|
|
||||||
* @param port The port, e.g. 8080.
|
|
||||||
*/
|
|
||||||
public void setProxy(String host, int port);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the status result returned from the most recent network test.
|
|
||||||
*
|
|
||||||
* @return The status code and message.
|
|
||||||
*/
|
|
||||||
public Status getStatus();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a service document, specified in the URL.
|
|
||||||
*
|
|
||||||
* @param url The URL to connect to.
|
|
||||||
* @return A ServiceDocument that contains the Service details that were
|
|
||||||
* obained from the specified URL.
|
|
||||||
* @throws SWORDClientException If there is an error accessing the
|
|
||||||
* URL.
|
|
||||||
*/
|
|
||||||
public ServiceDocument getServiceDocument(String url) throws SWORDClientException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a service document, specified in the URL. The document is accessed on
|
|
||||||
* behalf of the specified user.
|
|
||||||
*
|
|
||||||
* @param url The URL to connect to.
|
|
||||||
* @param onBehalfOf The username for the onBehalfOf access.
|
|
||||||
* @return A ServiceDocument that contains the Service details that were
|
|
||||||
* obtained from the specified URL.
|
|
||||||
* @throws SWORDClientException If there is an error accessing the URL.
|
|
||||||
*/
|
|
||||||
public ServiceDocument getServiceDocument(String url, String onBehalfOf) throws SWORDClientException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post a file to the specified destination URL.
|
|
||||||
*
|
|
||||||
* @param message The message that defines the requirements for the operation.
|
|
||||||
* @return A DespoitResponse if the response is successful. If there was an error,
|
|
||||||
* <code>null</code> should be returned.
|
|
||||||
* @throws SWORDClientException If there is an error accessing the URL.
|
|
||||||
*/
|
|
||||||
public DepositResponse postFile(PostMessage message) throws SWORDClientException;
|
|
||||||
}
|
|
@@ -1,42 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an exception thrown by the SWORD Client.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class SWORDClientException extends Exception {
|
|
||||||
/**
|
|
||||||
* Create a new exception, without a message.
|
|
||||||
*/
|
|
||||||
public SWORDClientException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new exception with the specified message.
|
|
||||||
*
|
|
||||||
* @param message The message.
|
|
||||||
*/
|
|
||||||
public SWORDClientException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new exception with the specified message and set
|
|
||||||
* the exception that generated this error.
|
|
||||||
*
|
|
||||||
* @param message The message.
|
|
||||||
* @param cause The original exception.
|
|
||||||
*/
|
|
||||||
public SWORDClientException(String message, Exception cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,129 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import javax.swing.JComboBox;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An extension of the JComboBox class. This adds a method that
|
|
||||||
* can update the list of items with the item. The update will only
|
|
||||||
* work on combo boxes that are set to editable.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class SWORDComboBox extends JComboBox {
|
|
||||||
/**
|
|
||||||
* Create an instance of the SWORD Combo box.
|
|
||||||
*/
|
|
||||||
public SWORDComboBox() {
|
|
||||||
super();
|
|
||||||
setEditable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the list for the Combo box with the currently selected
|
|
||||||
* item. This will only add an item to the list if: i) the control
|
|
||||||
* is editable, ii) the selected item is not empty and iii) the
|
|
||||||
* item is not already in the list.
|
|
||||||
*/
|
|
||||||
public void updateList() {
|
|
||||||
Object s = getSelectedItem();
|
|
||||||
|
|
||||||
if (!isEditable() || s == null || ((String) s).trim().length() == 0) {
|
|
||||||
// don't update with an empty item or if the combo box is not editable.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
insertItem(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert an item into the combo box. This will only be added
|
|
||||||
* if the item is not already present in the combo box.
|
|
||||||
*
|
|
||||||
* @param newItem The item to insert.
|
|
||||||
*/
|
|
||||||
public void insertItem(Object newItem) {
|
|
||||||
int count = getItemCount();
|
|
||||||
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < count && !found; i++) {
|
|
||||||
Object item = getItemAt(i);
|
|
||||||
if (item != null && item.equals(newItem)) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
addItem(newItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert multiple items into the combo box.
|
|
||||||
*
|
|
||||||
* @param items The array of items.
|
|
||||||
*/
|
|
||||||
public void insertItems(String[] items) {
|
|
||||||
for (String item : items) {
|
|
||||||
insertItem(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the text of the currently selected item in the combo box.
|
|
||||||
* @return The text. <code>null</code> is returned if no item
|
|
||||||
* is selected.
|
|
||||||
*/
|
|
||||||
public String getText() {
|
|
||||||
Object o = getSelectedItem();
|
|
||||||
if (o != null) {
|
|
||||||
return o.toString().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,144 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.GridBagConstraints;
|
|
||||||
import java.awt.GridBagLayout;
|
|
||||||
import java.awt.Insets;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class. Creates a two column form. The left column is used to show
|
|
||||||
* the label for the row. The right column is used to show the control, e.g.
|
|
||||||
* text box, combo box or checkbox, for the row.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class SWORDFormPanel extends JPanel {
|
|
||||||
/**
|
|
||||||
* Constraints used to control the layout on the panel.
|
|
||||||
*/
|
|
||||||
private GridBagConstraints labelConstraints;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constraints used to control the layout of the input controls on the panel.
|
|
||||||
*/
|
|
||||||
private GridBagConstraints controlConstraints;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index to the next row.
|
|
||||||
*/
|
|
||||||
private int rowIndex = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insets for the top row of the label column.
|
|
||||||
*/
|
|
||||||
private Insets labelTop = new Insets(10, 10, 0, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insets for the top row of the control column.
|
|
||||||
*/
|
|
||||||
private Insets controlTop = new Insets(10, 4, 0, 10);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insets for a general row in the label column.
|
|
||||||
*/
|
|
||||||
private Insets labelGeneral = new Insets(3, 10, 0, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insets for a general row in the control column.
|
|
||||||
*/
|
|
||||||
private Insets controlGeneral = new Insets(3, 4, 0, 10);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of the class.
|
|
||||||
*/
|
|
||||||
public SWORDFormPanel() {
|
|
||||||
super();
|
|
||||||
setLayout(new GridBagLayout());
|
|
||||||
|
|
||||||
labelConstraints = new GridBagConstraints();
|
|
||||||
labelConstraints.fill = GridBagConstraints.NONE;
|
|
||||||
labelConstraints.anchor = GridBagConstraints.LINE_END;
|
|
||||||
labelConstraints.weightx = 0.1;
|
|
||||||
|
|
||||||
controlConstraints = new GridBagConstraints();
|
|
||||||
controlConstraints.fill = GridBagConstraints.HORIZONTAL;
|
|
||||||
controlConstraints.weightx = 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the specified component as the first row. It will occupy two
|
|
||||||
* columns.
|
|
||||||
*
|
|
||||||
* @param one The control to add.
|
|
||||||
*/
|
|
||||||
public void addFirstRow(Component one) {
|
|
||||||
addRow(one, null, labelTop, controlTop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the specified components as the first row in the form.
|
|
||||||
*
|
|
||||||
* @param one The label component.
|
|
||||||
* @param two The control component.
|
|
||||||
*/
|
|
||||||
public void addFirstRow(Component one, Component two) {
|
|
||||||
addRow(one, two, labelTop, controlTop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a component to the general row. This will be added in the label column.
|
|
||||||
*
|
|
||||||
* @param one The component.
|
|
||||||
*/
|
|
||||||
public void addRow(Component one) {
|
|
||||||
addRow(one, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a component to the general row.
|
|
||||||
*
|
|
||||||
* @param one The component to add to the label column.
|
|
||||||
* @param two The component to add to the control column.
|
|
||||||
*/
|
|
||||||
public void addRow(Component one, Component two) {
|
|
||||||
addRow(one, two, labelGeneral, controlGeneral);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a row to the table.
|
|
||||||
*
|
|
||||||
* @param one The component to display in the label column.
|
|
||||||
* @param two The component to display in the control column.
|
|
||||||
* @param labels The insets for the label column.
|
|
||||||
* @param controls The insets for the controls column.
|
|
||||||
*/
|
|
||||||
protected void addRow(Component one, Component two, Insets labels, Insets controls) {
|
|
||||||
labelConstraints.insets = labels;
|
|
||||||
labelConstraints.gridx = 0;
|
|
||||||
labelConstraints.gridy = rowIndex;
|
|
||||||
if (two == null) {
|
|
||||||
labelConstraints.gridwidth = 2;
|
|
||||||
} else {
|
|
||||||
labelConstraints.gridwidth = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
add(one, labelConstraints);
|
|
||||||
|
|
||||||
if (two != null) {
|
|
||||||
controlConstraints.insets = controls;
|
|
||||||
controlConstraints.gridx = 1;
|
|
||||||
controlConstraints.gridy = rowIndex;
|
|
||||||
add(two, controlConstraints);
|
|
||||||
}
|
|
||||||
|
|
||||||
rowIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,227 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JPasswordField;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog that prompts the user to enter the details for a service
|
|
||||||
* document location.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class ServiceDialog {
|
|
||||||
/**
|
|
||||||
* The username.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox username;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The password.
|
|
||||||
*/
|
|
||||||
private JPasswordField password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds the URL for the collection.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The combo box that shows the list of onBehalfOf items.
|
|
||||||
*/
|
|
||||||
private SWORDComboBox onBehalfOf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parent frame for the dialog.
|
|
||||||
*/
|
|
||||||
private JFrame parentFrame = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The panel that holds the controls.
|
|
||||||
*/
|
|
||||||
private JPanel controls = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of buttons.
|
|
||||||
*/
|
|
||||||
private static Object[] options = {"Get Service Document", "Cancel"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*
|
|
||||||
* @param parentFrame The parent frame. The dialog will be shown over the
|
|
||||||
* centre of this frame.
|
|
||||||
*/
|
|
||||||
public ServiceDialog(JFrame parentFrame) {
|
|
||||||
this.parentFrame = parentFrame;
|
|
||||||
controls = createControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the dialog.
|
|
||||||
*
|
|
||||||
* @return The close option. This is one of the dialog options from
|
|
||||||
* JOptionPane.
|
|
||||||
*/
|
|
||||||
public int show() {
|
|
||||||
int result = JOptionPane.showOptionDialog(parentFrame,
|
|
||||||
controls,
|
|
||||||
"Get Service Document",
|
|
||||||
JOptionPane.OK_CANCEL_OPTION,
|
|
||||||
JOptionPane.PLAIN_MESSAGE,
|
|
||||||
null,
|
|
||||||
options,
|
|
||||||
options[1]);
|
|
||||||
|
|
||||||
if (result == JOptionPane.OK_OPTION) {
|
|
||||||
// update the combo boxes with the values
|
|
||||||
username.updateList();
|
|
||||||
location.updateList();
|
|
||||||
onBehalfOf.updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the controls that are displayed in the dialog.
|
|
||||||
*
|
|
||||||
* @return The panel that contains the controls.
|
|
||||||
*/
|
|
||||||
protected final JPanel createControls() {
|
|
||||||
username = new SWORDComboBox();
|
|
||||||
username.setEditable(true);
|
|
||||||
password = new JPasswordField();
|
|
||||||
location = new SWORDComboBox();
|
|
||||||
location.setEditable(true);
|
|
||||||
onBehalfOf = new SWORDComboBox();
|
|
||||||
onBehalfOf.setEditable(true);
|
|
||||||
|
|
||||||
JLabel userLabel = new JLabel("Username:", JLabel.TRAILING);
|
|
||||||
JLabel passwordLabel = new JLabel("Password:", JLabel.TRAILING);
|
|
||||||
JLabel locationLabel = new JLabel("Location:", JLabel.TRAILING);
|
|
||||||
JLabel onBehalfOfLabel = new JLabel("On Behalf Of:", JLabel.TRAILING);
|
|
||||||
|
|
||||||
SWORDFormPanel panel = new SWORDFormPanel();
|
|
||||||
panel.addFirstRow(userLabel, username);
|
|
||||||
panel.addRow(passwordLabel, password);
|
|
||||||
panel.addRow(locationLabel, location);
|
|
||||||
panel.addRow(onBehalfOfLabel, onBehalfOf);
|
|
||||||
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the username from the controls on the dialog.
|
|
||||||
*
|
|
||||||
* @return The username.
|
|
||||||
*/
|
|
||||||
public String getUsername() {
|
|
||||||
return username.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the password from the dialog.
|
|
||||||
*
|
|
||||||
* @return The password.
|
|
||||||
*/
|
|
||||||
public String getPassword() {
|
|
||||||
return new String(password.getPassword());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The location from the dialog.
|
|
||||||
*
|
|
||||||
* @return The location.
|
|
||||||
*/
|
|
||||||
public String getLocation() {
|
|
||||||
return location.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The onBehalfOf value from the dialog.
|
|
||||||
*
|
|
||||||
* @return The onBehalfOf value.
|
|
||||||
*/
|
|
||||||
public String getOnBehalfOf() {
|
|
||||||
String text = onBehalfOf.getText().trim();
|
|
||||||
if (text.length() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the list of user ids to the dialog.
|
|
||||||
*
|
|
||||||
* @param users The list of user ids.
|
|
||||||
*/
|
|
||||||
public void addUserIds(String[] users) {
|
|
||||||
username.insertItems(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the list of service URLs.
|
|
||||||
*
|
|
||||||
* @param services The service URLs.
|
|
||||||
*/
|
|
||||||
public void addServiceUrls(String[] services) {
|
|
||||||
location.insertItems(services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a list of onBehalfOf names.
|
|
||||||
*
|
|
||||||
* @param users The list of onBehalfOf items.
|
|
||||||
*/
|
|
||||||
public void addOnBehalfOf(String[] users) {
|
|
||||||
onBehalfOf.insertItems(users);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,843 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.client;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.Icon;
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JEditorPane;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JScrollPane;
|
|
||||||
import javax.swing.JSplitPane;
|
|
||||||
import javax.swing.JTree;
|
|
||||||
import javax.swing.ToolTipManager;
|
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
|
||||||
import javax.swing.event.TreeSelectionListener;
|
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
|
||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
|
||||||
import javax.swing.tree.DefaultTreeModel;
|
|
||||||
import javax.swing.tree.TreePath;
|
|
||||||
|
|
||||||
import org.purl.sword.atom.Author;
|
|
||||||
import org.purl.sword.atom.Content;
|
|
||||||
import org.purl.sword.atom.Contributor;
|
|
||||||
import org.purl.sword.atom.Generator;
|
|
||||||
import org.purl.sword.atom.Link;
|
|
||||||
import org.purl.sword.atom.TextConstruct;
|
|
||||||
import org.purl.sword.base.Collection;
|
|
||||||
import org.purl.sword.base.DepositResponse;
|
|
||||||
import org.purl.sword.base.SWORDEntry;
|
|
||||||
import org.purl.sword.base.Service;
|
|
||||||
import org.purl.sword.base.ServiceDocument;
|
|
||||||
import org.purl.sword.base.SwordAcceptPackaging;
|
|
||||||
import org.purl.sword.base.Workspace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The main panel for the GUI client. This contains the top-two sub-panels: the
|
|
||||||
* tree and the text area to show the details of the selected node.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class ServicePanel extends JPanel
|
|
||||||
implements TreeSelectionListener {
|
|
||||||
/**
|
|
||||||
* The top level item in the tree that lists services.
|
|
||||||
*/
|
|
||||||
DefaultMutableTreeNode top;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tree model used to display the items.
|
|
||||||
*/
|
|
||||||
DefaultTreeModel treeModel = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tree that holds the list of services.
|
|
||||||
*/
|
|
||||||
private JTree services;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The panel that shows an HTML table with any details for the selected
|
|
||||||
* node in the services tree.
|
|
||||||
*/
|
|
||||||
private JEditorPane details;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A registered listener. This listener will be notified when there is a
|
|
||||||
* different node selected in the service tree.
|
|
||||||
*/
|
|
||||||
private ServiceSelectedListener listener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance of the panel.
|
|
||||||
*/
|
|
||||||
public ServicePanel() {
|
|
||||||
super();
|
|
||||||
setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
top = new DefaultMutableTreeNode("Services & Posted Files");
|
|
||||||
treeModel = new DefaultTreeModel(top);
|
|
||||||
|
|
||||||
services = new JTree(treeModel);
|
|
||||||
services.setCellRenderer(new ServicePostTreeRenderer());
|
|
||||||
|
|
||||||
JScrollPane servicesPane = new JScrollPane(services,
|
|
||||||
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
||||||
|
|
||||||
details = new JEditorPane("text/html",
|
|
||||||
"<html><body><h1>Details</h1><p>This panel will show the details for the currently " +
|
|
||||||
"selected item in the tree.</p></body></html>");
|
|
||||||
|
|
||||||
JScrollPane detailsPane = new JScrollPane(details,
|
|
||||||
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
|
||||||
|
|
||||||
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
|
||||||
servicesPane,
|
|
||||||
detailsPane);
|
|
||||||
splitPane.setOneTouchExpandable(true);
|
|
||||||
splitPane.setResizeWeight(0.5);
|
|
||||||
splitPane.setDividerLocation(200);
|
|
||||||
|
|
||||||
services.addTreeSelectionListener(this);
|
|
||||||
ToolTipManager.sharedInstance().registerComponent(services);
|
|
||||||
|
|
||||||
add(splitPane, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renderer that displays the icons for the tree nodes.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
static class ServicePostTreeRenderer extends DefaultTreeCellRenderer {
|
|
||||||
Icon workspaceIcon;
|
|
||||||
Icon serviceIcon;
|
|
||||||
Icon collectionIcon;
|
|
||||||
Icon fileIcon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the renderer. Load the icons.
|
|
||||||
*/
|
|
||||||
public ServicePostTreeRenderer() {
|
|
||||||
ClassLoader loader = this.getClass().getClassLoader();
|
|
||||||
workspaceIcon = new ImageIcon(loader.getResource("images/WorkspaceNodeImage.gif"));
|
|
||||||
serviceIcon = new ImageIcon(loader.getResource("images/ServiceNodeImage.gif"));
|
|
||||||
collectionIcon = new ImageIcon(loader.getResource("images/CollectionNodeImage.gif"));
|
|
||||||
fileIcon = new ImageIcon(loader.getResource("images/ServiceNodeImage.gif"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the cell renderer. This will be the default tree cell renderer
|
|
||||||
* with a different icon depending upon the type of data in the node.
|
|
||||||
*
|
|
||||||
* @param tree The JTree control.
|
|
||||||
* @param value The value to display.
|
|
||||||
* @param sel True if the node is selected.
|
|
||||||
* @param expanded True if the node is expanded.
|
|
||||||
* @param leaf True if the node is a leaf.
|
|
||||||
* @param row The row.
|
|
||||||
* @param hasFocus True if the node has focus.
|
|
||||||
*/
|
|
||||||
public Component getTreeCellRendererComponent(
|
|
||||||
JTree tree,
|
|
||||||
Object value,
|
|
||||||
boolean sel,
|
|
||||||
boolean expanded,
|
|
||||||
boolean leaf,
|
|
||||||
int row,
|
|
||||||
boolean hasFocus) {
|
|
||||||
|
|
||||||
JComponent comp = (JComponent) super.getTreeCellRendererComponent(
|
|
||||||
tree, value, sel,
|
|
||||||
expanded, leaf, row,
|
|
||||||
hasFocus);
|
|
||||||
|
|
||||||
DefaultMutableTreeNode node =
|
|
||||||
(DefaultMutableTreeNode) value;
|
|
||||||
|
|
||||||
Object o = node.getUserObject();
|
|
||||||
if (o instanceof TreeNodeWrapper) {
|
|
||||||
TreeNodeWrapper wrapper = (TreeNodeWrapper) o;
|
|
||||||
comp.setToolTipText(wrapper.toString());
|
|
||||||
Object data = wrapper.getData();
|
|
||||||
if (data instanceof Service) {
|
|
||||||
setIcon(serviceIcon);
|
|
||||||
} else if (data instanceof Workspace) {
|
|
||||||
setIcon(workspaceIcon);
|
|
||||||
} else if (data instanceof Collection) {
|
|
||||||
setIcon(collectionIcon);
|
|
||||||
} else if (data instanceof SWORDEntry) {
|
|
||||||
setIcon(fileIcon);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
comp.setToolTipText(null);
|
|
||||||
}
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the service selected listener. This listener will be notified when
|
|
||||||
* there is a selection change in the tree.
|
|
||||||
*
|
|
||||||
* @param listener The listener.
|
|
||||||
*/
|
|
||||||
public void setServiceSelectedListener(ServiceSelectedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the specified service document. Add the details as a new child of the
|
|
||||||
* root of the tree.
|
|
||||||
*
|
|
||||||
* @param url The url used to access the service document.
|
|
||||||
* @param doc The service document.
|
|
||||||
*/
|
|
||||||
public void processServiceDocument(String url,
|
|
||||||
ServiceDocument doc) {
|
|
||||||
TreeNodeWrapper wrapper = null;
|
|
||||||
|
|
||||||
Service service = doc.getService();
|
|
||||||
wrapper = new TreeNodeWrapper(url, service);
|
|
||||||
DefaultMutableTreeNode serviceNode = new DefaultMutableTreeNode(wrapper);
|
|
||||||
treeModel.insertNodeInto(serviceNode, top, top.getChildCount());
|
|
||||||
services.scrollPathToVisible(new TreePath(serviceNode.getPath()));
|
|
||||||
|
|
||||||
// process the workspaces
|
|
||||||
DefaultMutableTreeNode workspaceNode = null;
|
|
||||||
|
|
||||||
Iterator<Workspace> workspaces = service.getWorkspaces();
|
|
||||||
for (; workspaces.hasNext(); ) {
|
|
||||||
Workspace workspace = workspaces.next();
|
|
||||||
wrapper = new TreeNodeWrapper(workspace.getTitle(), workspace);
|
|
||||||
workspaceNode = new DefaultMutableTreeNode(wrapper);
|
|
||||||
treeModel.insertNodeInto(workspaceNode, serviceNode, serviceNode.getChildCount());
|
|
||||||
services.scrollPathToVisible(new TreePath(workspaceNode.getPath()));
|
|
||||||
|
|
||||||
DefaultMutableTreeNode collectionNode = null;
|
|
||||||
Iterator<Collection> collections = workspace.collectionIterator();
|
|
||||||
for (; collections.hasNext(); ) {
|
|
||||||
Collection collection = collections.next();
|
|
||||||
wrapper = new TreeNodeWrapper(collection.getTitle(), collection);
|
|
||||||
collectionNode = new DefaultMutableTreeNode(wrapper);
|
|
||||||
treeModel.insertNodeInto(collectionNode, workspaceNode, workspaceNode.getChildCount());
|
|
||||||
services.scrollPathToVisible(new TreePath(collectionNode.getPath()));
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds the data for a tree node. It specifies the name that will be displayed
|
|
||||||
* in the node, and stores associated data.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
static class TreeNodeWrapper {
|
|
||||||
/**
|
|
||||||
* The node name.
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The user data.
|
|
||||||
*/
|
|
||||||
private Object userObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance.
|
|
||||||
*
|
|
||||||
* @param name The name of the node.
|
|
||||||
* @param data The data in the node.
|
|
||||||
*/
|
|
||||||
public TreeNodeWrapper(String name, Object data) {
|
|
||||||
this.name = name;
|
|
||||||
this.userObject = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the data that is stored in this node.
|
|
||||||
*
|
|
||||||
* @return The data.
|
|
||||||
*/
|
|
||||||
public Object getData() {
|
|
||||||
return userObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string description for this node.
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
if (name == null || name.trim().equals("")) {
|
|
||||||
return "Unspecified";
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Respond to a changed tree selection event. Update the details panel to
|
|
||||||
* show an appropriate message for the newly selected node. Also,
|
|
||||||
* alert the selection listener for this panel. The listener will receive
|
|
||||||
* a path, if a collection has been selected. Otherwise, the listener
|
|
||||||
* will receive <code>null</code>.
|
|
||||||
*/
|
|
||||||
public void valueChanged(TreeSelectionEvent evt) {
|
|
||||||
// Get all nodes whose selection status has changed
|
|
||||||
TreePath[] paths = evt.getPaths();
|
|
||||||
|
|
||||||
for (int i = 0; i < paths.length; i++) {
|
|
||||||
if (evt.isAddedPath(i)) {
|
|
||||||
// process new selections
|
|
||||||
DefaultMutableTreeNode node;
|
|
||||||
node = (DefaultMutableTreeNode) (paths[i].getLastPathComponent());
|
|
||||||
|
|
||||||
Object o = node.getUserObject();
|
|
||||||
if (o instanceof TreeNodeWrapper) {
|
|
||||||
try {
|
|
||||||
TreeNodeWrapper wrapper = (TreeNodeWrapper) o;
|
|
||||||
Object data = wrapper.getData();
|
|
||||||
if (data instanceof Service) {
|
|
||||||
showService((Service) data);
|
|
||||||
alertListener(null);
|
|
||||||
} else if (data instanceof Workspace) {
|
|
||||||
showWorkspace((Workspace) data);
|
|
||||||
if (listener != null) {
|
|
||||||
alertListener(null);
|
|
||||||
}
|
|
||||||
} else if (data instanceof Collection) {
|
|
||||||
Collection c = (Collection) data;
|
|
||||||
showCollection(c);
|
|
||||||
alertListener(c.getLocation());
|
|
||||||
} else if (data instanceof SWORDEntry) {
|
|
||||||
showEntry((SWORDEntry) data);
|
|
||||||
alertListener(null);
|
|
||||||
} else {
|
|
||||||
details.setText("<html><body>unknown</body></html>");
|
|
||||||
alertListener(null);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
details.setText(
|
|
||||||
"<html><body>An error occurred. The message was: " + e.getMessage() + "</body></html>");
|
|
||||||
alertListener(null);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
details.setText("<html><body>please select one of the other nodes</body></html>");
|
|
||||||
alertListener(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify the listener that there has been a change to the currently selected
|
|
||||||
* item in the tree.
|
|
||||||
*
|
|
||||||
* @param value The value to send to the listener.
|
|
||||||
*/
|
|
||||||
private void alertListener(String value) {
|
|
||||||
if (listener != null) {
|
|
||||||
listener.selected(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new HTML table row to the specified StringBuffer. The label is displayed in
|
|
||||||
* the left column and the value is displayed in the right column.
|
|
||||||
*
|
|
||||||
* @param buffer The destination string buffer.
|
|
||||||
* @param label The label to add.
|
|
||||||
* @param value The corresponding value to add.
|
|
||||||
*/
|
|
||||||
private void addTableRow(StringBuffer buffer, String label, Object value) {
|
|
||||||
buffer.append("<tr bgcolor=\"#ffffff;\"><td>");
|
|
||||||
buffer.append(label);
|
|
||||||
buffer.append("</td><td>");
|
|
||||||
buffer.append(displayableValue(value));
|
|
||||||
buffer.append("</td></tr>");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the specified service data in the details panel.
|
|
||||||
*
|
|
||||||
* @param service The service node to display.
|
|
||||||
*/
|
|
||||||
private void showService(Service service) {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
buffer.append("<html>");
|
|
||||||
buffer.append("<body>");
|
|
||||||
|
|
||||||
buffer.append("<table border=\"1\" width=\"100%\">");
|
|
||||||
buffer.append("<tr bgcolor=\"#69a5c8;\"><td colspan=\"2\"><font size=\"+2\">Service Summary</font></td></tr>");
|
|
||||||
addTableRow(buffer, "SWORD Version", service.getVersion());
|
|
||||||
addTableRow(buffer, "NoOp Support ", service.isNoOp());
|
|
||||||
addTableRow(buffer, "Verbose Support ", service.isVerbose());
|
|
||||||
|
|
||||||
String maxSize = "";
|
|
||||||
|
|
||||||
// Commented out the following code as the client code is out of step with the
|
|
||||||
// Sword 'base' library and wont compile. - Robin Taylor.
|
|
||||||
//if ( service.maxUploadIsDefined() )
|
|
||||||
//{
|
|
||||||
// maxSize = "" + service.getMaxUploadSize() + "kB";
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
maxSize = "undefined";
|
|
||||||
//}
|
|
||||||
|
|
||||||
addTableRow(buffer, "Max File Upload Size ", maxSize);
|
|
||||||
|
|
||||||
buffer.append("</table>");
|
|
||||||
|
|
||||||
buffer.append("</body>");
|
|
||||||
buffer.append("</html>");
|
|
||||||
details.setText(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the workspace data in the details panel.
|
|
||||||
*
|
|
||||||
* @param workspace The workspace.
|
|
||||||
*/
|
|
||||||
private void showWorkspace(Workspace workspace) {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
buffer.append("<html>");
|
|
||||||
buffer.append("<body>");
|
|
||||||
|
|
||||||
buffer.append("<table border=\"1\" width=\"100%\">");
|
|
||||||
buffer
|
|
||||||
.append("<tr bgcolor=\"#69a5c8;\"><td colspan=\"2\"><font size=\"+2\">Workspace Summary</font></td></tr>");
|
|
||||||
addTableRow(buffer, "Workspace Title", workspace.getTitle());
|
|
||||||
buffer.append("</table>");
|
|
||||||
|
|
||||||
buffer.append("</body>");
|
|
||||||
buffer.append("</html>");
|
|
||||||
details.setText(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the parameter unmodified if set, or the not defined text if null
|
|
||||||
* @param s
|
|
||||||
* @return s or ClientConstants.NOT_DEFINED_TEXT
|
|
||||||
*/
|
|
||||||
private Object displayableValue(Object s) {
|
|
||||||
if (null == s) {
|
|
||||||
return ClientConstants.NOT_DEFINED_TEXT;
|
|
||||||
} else {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a string within paragraph tags.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer to add the message to.
|
|
||||||
* @param message The message to add.
|
|
||||||
*/
|
|
||||||
private void addPara(StringBuffer buffer, String message) {
|
|
||||||
buffer.append("<p>" + message + "</p>");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the specified collection data in the details panel.
|
|
||||||
*
|
|
||||||
* @param collection The collection data.
|
|
||||||
*/
|
|
||||||
private void showCollection(Collection collection) {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
buffer.append("<html>");
|
|
||||||
buffer.append("<body>");
|
|
||||||
|
|
||||||
if (collection == null) {
|
|
||||||
addPara(buffer, "Invalid Collection object. Unable to display details.");
|
|
||||||
} else {
|
|
||||||
buffer.append("<table border=\"1\" width=\"100%\">");
|
|
||||||
buffer.append(
|
|
||||||
"<tr bgcolor=\"#69a5c8;\"><td colspan=\"2\"><font size=\"+2\">Collection Summary</font></td></tr>");
|
|
||||||
addTableRow(buffer, "Collection location", collection.getLocation());
|
|
||||||
addTableRow(buffer, "Collection title", collection.getTitle());
|
|
||||||
addTableRow(buffer, "Abstract", collection.getAbstract());
|
|
||||||
addTableRow(buffer, "Collection Policy", collection.getCollectionPolicy());
|
|
||||||
addTableRow(buffer, "Treatment", collection.getTreatment());
|
|
||||||
addTableRow(buffer, "Mediation", collection.getMediation());
|
|
||||||
addTableRow(buffer, "Nested Service Document", collection.getService());
|
|
||||||
|
|
||||||
String[] accepts = collection.getAccepts();
|
|
||||||
StringBuilder acceptList = new StringBuilder();
|
|
||||||
if (accepts != null && accepts.length == 0) {
|
|
||||||
acceptList.append("None specified");
|
|
||||||
} else {
|
|
||||||
for (String s : accepts) {
|
|
||||||
acceptList.append(s).append("<br>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addTableRow(buffer, "Accepts", acceptList.toString());
|
|
||||||
|
|
||||||
List<SwordAcceptPackaging> acceptsPackaging = collection.getAcceptPackaging();
|
|
||||||
|
|
||||||
StringBuilder acceptPackagingList = new StringBuilder();
|
|
||||||
for (Iterator i = acceptsPackaging.iterator(); i.hasNext(); ) {
|
|
||||||
SwordAcceptPackaging accept = (SwordAcceptPackaging) i.next();
|
|
||||||
acceptPackagingList.append(accept.getContent()).append(" (").append(accept.getQualityValue())
|
|
||||||
.append(")");
|
|
||||||
|
|
||||||
// add a , separator if there are any more items in the list
|
|
||||||
if (i.hasNext()) {
|
|
||||||
acceptPackagingList.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addTableRow(buffer, "Accepts Packaging", acceptPackagingList.toString());
|
|
||||||
|
|
||||||
buffer.append("</table>");
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.append("</body>");
|
|
||||||
buffer.append("</html>");
|
|
||||||
details.setText(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the contents of a Post entry in the display panel.
|
|
||||||
*
|
|
||||||
* @param entry The entry to display.
|
|
||||||
*/
|
|
||||||
private void showEntry(SWORDEntry entry) {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
buffer.append("<html>");
|
|
||||||
buffer.append("<body>");
|
|
||||||
|
|
||||||
if (entry == null) {
|
|
||||||
addPara(buffer, "Invalid Entry object. Unable to display details.");
|
|
||||||
} else {
|
|
||||||
buffer.append("<table border=\"1\" width=\"100%\">");
|
|
||||||
buffer
|
|
||||||
.append("<tr bgcolor=\"#69a5c8;\"><td colspan=\"2\"><font size=\"+2\">Entry Summary</font></td></tr>");
|
|
||||||
|
|
||||||
// process atom:title
|
|
||||||
String titleString = getTextConstructDetails(entry.getSummary());
|
|
||||||
addTableRow(buffer, "Title", titleString);
|
|
||||||
|
|
||||||
// process id
|
|
||||||
addTableRow(buffer, "ID", entry.getId());
|
|
||||||
|
|
||||||
// process updated
|
|
||||||
addTableRow(buffer, "Date Updated", entry.getUpdated());
|
|
||||||
|
|
||||||
String authorString = getAuthorDetails(entry.getAuthors());
|
|
||||||
addTableRow(buffer, "Authors", authorString);
|
|
||||||
|
|
||||||
// process summary
|
|
||||||
String summaryString = getTextConstructDetails(entry.getSummary());
|
|
||||||
addTableRow(buffer, "Summary", summaryString);
|
|
||||||
|
|
||||||
// process content
|
|
||||||
Content content = entry.getContent();
|
|
||||||
String contentString = "";
|
|
||||||
if (content == null) {
|
|
||||||
contentString = "Not defined.";
|
|
||||||
} else {
|
|
||||||
contentString += "Source: '" + content.getSource() + "', Type: '" +
|
|
||||||
content.getType() + "'";
|
|
||||||
}
|
|
||||||
addTableRow(buffer, "Content", contentString);
|
|
||||||
|
|
||||||
// process links
|
|
||||||
Iterator<Link> links = entry.getLinks();
|
|
||||||
StringBuffer linkBuffer = new StringBuffer();
|
|
||||||
for (; links.hasNext(); ) {
|
|
||||||
Link link = links.next();
|
|
||||||
linkBuffer.append("href: '");
|
|
||||||
linkBuffer.append(link.getHref());
|
|
||||||
linkBuffer.append("', href lang: '");
|
|
||||||
linkBuffer.append(link.getHreflang());
|
|
||||||
linkBuffer.append("', rel: '");
|
|
||||||
linkBuffer.append(link.getRel());
|
|
||||||
linkBuffer.append("')<br>");
|
|
||||||
}
|
|
||||||
if (linkBuffer.length() == 0) {
|
|
||||||
linkBuffer.append("Not defined");
|
|
||||||
}
|
|
||||||
addTableRow(buffer, "Links", linkBuffer.toString());
|
|
||||||
|
|
||||||
// process contributors
|
|
||||||
String contributorString = getContributorDetails(entry.getContributors());
|
|
||||||
addTableRow(buffer, "Contributors", contributorString);
|
|
||||||
|
|
||||||
// process source
|
|
||||||
String sourceString = "";
|
|
||||||
Generator generator = entry.getGenerator();
|
|
||||||
if (generator != null) {
|
|
||||||
sourceString += "Content: '" + generator.getContent() + "' <br>'";
|
|
||||||
sourceString += "Version: '" + generator.getVersion() + "' <br>'";
|
|
||||||
sourceString += "Uri: '" + generator.getUri() + "'";
|
|
||||||
} else {
|
|
||||||
sourceString += "No generator defined.";
|
|
||||||
}
|
|
||||||
|
|
||||||
addTableRow(buffer, "Generator", sourceString);
|
|
||||||
|
|
||||||
// process treatment
|
|
||||||
addTableRow(buffer, "Treatment", entry.getTreatment());
|
|
||||||
|
|
||||||
// process verboseDescription
|
|
||||||
addTableRow(buffer, "Verbose Description", entry.getVerboseDescription());
|
|
||||||
|
|
||||||
// process noOp
|
|
||||||
addTableRow(buffer, "NoOp", entry.isNoOp());
|
|
||||||
|
|
||||||
// process formatNamespace
|
|
||||||
addTableRow(buffer, "Packaging", entry.getPackaging());
|
|
||||||
|
|
||||||
// process userAgent
|
|
||||||
addTableRow(buffer, "User Agent", entry.getUserAgent());
|
|
||||||
|
|
||||||
|
|
||||||
buffer.append("</table>");
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.append("</body>");
|
|
||||||
buffer.append("</html>");
|
|
||||||
details.setText(buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the details for a TextConstruct object.
|
|
||||||
*
|
|
||||||
* @param data The text construct object to display.
|
|
||||||
*
|
|
||||||
* @return Either 'Not defined' if the data is <code>null</code>, or
|
|
||||||
* details of the text content element.
|
|
||||||
*/
|
|
||||||
private String getTextConstructDetails(TextConstruct data) {
|
|
||||||
String summaryStr = "";
|
|
||||||
if (data == null) {
|
|
||||||
summaryStr = "Not defined";
|
|
||||||
} else {
|
|
||||||
summaryStr = "Content: '" + data.getContent() + "', Type: ";
|
|
||||||
if (data.getType() != null) {
|
|
||||||
summaryStr += "'" + data.getType().toString() + "'";
|
|
||||||
} else {
|
|
||||||
summaryStr += "undefined.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return summaryStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the author details and insert them into a string.
|
|
||||||
*
|
|
||||||
* @param authors the list of authors to process.
|
|
||||||
*
|
|
||||||
* @return A string containing the list of authors.
|
|
||||||
*/
|
|
||||||
private String getAuthorDetails(Iterator<Author> authors) {
|
|
||||||
// process author
|
|
||||||
StringBuffer authorBuffer = new StringBuffer();
|
|
||||||
for (; authors.hasNext(); ) {
|
|
||||||
Author a = authors.next();
|
|
||||||
authorBuffer.append(getAuthorDetails(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authorBuffer.length() == 0) {
|
|
||||||
authorBuffer.append("Not defined");
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorBuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the contributor details and insert them into a string.
|
|
||||||
*
|
|
||||||
* @param contributors The contributors.
|
|
||||||
*
|
|
||||||
* @return The string that lists the details of the contributors.
|
|
||||||
*/
|
|
||||||
private String getContributorDetails(Iterator<Contributor> contributors) {
|
|
||||||
// process author
|
|
||||||
StringBuffer authorBuffer = new StringBuffer();
|
|
||||||
for (; contributors.hasNext(); ) {
|
|
||||||
Contributor c = contributors.next();
|
|
||||||
authorBuffer.append(getAuthorDetails(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authorBuffer.length() == 0) {
|
|
||||||
authorBuffer.append("Not defined");
|
|
||||||
}
|
|
||||||
|
|
||||||
return authorBuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a string that describes the specified author.
|
|
||||||
*
|
|
||||||
* @param author The author.
|
|
||||||
*
|
|
||||||
* @return The string description.
|
|
||||||
*/
|
|
||||||
private String getAuthorDetails(Author author) {
|
|
||||||
// process author
|
|
||||||
StringBuffer authorBuffer = new StringBuffer();
|
|
||||||
authorBuffer.append(author.getName());
|
|
||||||
authorBuffer.append(" (email: '");
|
|
||||||
authorBuffer.append(author.getEmail());
|
|
||||||
authorBuffer.append("', uri: '");
|
|
||||||
authorBuffer.append(author.getUri());
|
|
||||||
authorBuffer.append("')<br>");
|
|
||||||
|
|
||||||
return authorBuffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the deposit response and insert the details into the tree. If the url
|
|
||||||
* matches one of the collections in the tree, the deposit is added as a child
|
|
||||||
* node. Otherwise, the node is added as a child of the root.
|
|
||||||
*
|
|
||||||
* @param url The url of the collection that the file was posted to.
|
|
||||||
*
|
|
||||||
* @param response The details of the deposit.
|
|
||||||
*/
|
|
||||||
public void processDepositResponse(String url,
|
|
||||||
DepositResponse response) {
|
|
||||||
SWORDEntry entry = response.getEntry();
|
|
||||||
Object title = entry.getTitle();
|
|
||||||
if (title == null) {
|
|
||||||
title = "Undefined";
|
|
||||||
} else {
|
|
||||||
title = entry.getTitle().getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeNodeWrapper wrapper = new TreeNodeWrapper(title.toString(), entry);
|
|
||||||
DefaultMutableTreeNode entryNode = new DefaultMutableTreeNode(wrapper);
|
|
||||||
|
|
||||||
DefaultMutableTreeNode newParentNode = top;
|
|
||||||
List<DefaultMutableTreeNode> nodes = getCollectionNodes();
|
|
||||||
for (DefaultMutableTreeNode node : nodes) {
|
|
||||||
Object o = node.getUserObject();
|
|
||||||
if (o instanceof TreeNodeWrapper) {
|
|
||||||
TreeNodeWrapper collectionWrapper = (TreeNodeWrapper) o;
|
|
||||||
Object data = collectionWrapper.getData();
|
|
||||||
if (data instanceof Collection) {
|
|
||||||
Collection col = (Collection) data;
|
|
||||||
String location = col.getLocation();
|
|
||||||
if (location != null && location.equals(url)) {
|
|
||||||
newParentNode = node;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
treeModel.insertNodeInto(entryNode, newParentNode, newParentNode.getChildCount());
|
|
||||||
services.scrollPathToVisible(new TreePath(entryNode.getPath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of all current collections displayed in the tree.
|
|
||||||
*
|
|
||||||
* @return An array of the URLs for the collections.
|
|
||||||
*/
|
|
||||||
public String[] getCollectionLocations() {
|
|
||||||
List<DefaultMutableTreeNode> nodes = getCollectionNodes();
|
|
||||||
String[] locations = new String[nodes.size()];
|
|
||||||
|
|
||||||
DefaultMutableTreeNode node;
|
|
||||||
for (int i = 0; i < nodes.size(); i++) {
|
|
||||||
node = nodes.get(i);
|
|
||||||
Object o = node.getUserObject();
|
|
||||||
if (o instanceof TreeNodeWrapper) {
|
|
||||||
TreeNodeWrapper collectionWrapper = (TreeNodeWrapper) o;
|
|
||||||
Object data = collectionWrapper.getData();
|
|
||||||
if (data instanceof Collection) {
|
|
||||||
Collection col = (Collection) data;
|
|
||||||
String location = col.getLocation();
|
|
||||||
if (location != null) {
|
|
||||||
locations[i] = location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of nodes that contain collections.
|
|
||||||
*
|
|
||||||
* @return A vector of the collection nodes.
|
|
||||||
*/
|
|
||||||
private List<DefaultMutableTreeNode> getCollectionNodes() {
|
|
||||||
List<DefaultMutableTreeNode> nodes = new ArrayList<DefaultMutableTreeNode>();
|
|
||||||
|
|
||||||
DefaultMutableTreeNode node;
|
|
||||||
Enumeration treeNodes = top.depthFirstEnumeration();
|
|
||||||
|
|
||||||
while (treeNodes.hasMoreElements()) {
|
|
||||||
node = (DefaultMutableTreeNode) treeNodes.nextElement();
|
|
||||||
Object o = node.getUserObject();
|
|
||||||
if (o instanceof TreeNodeWrapper) {
|
|
||||||
TreeNodeWrapper wrapper = (TreeNodeWrapper) o;
|
|
||||||
Object data = wrapper.getData();
|
|
||||||
if (data instanceof Collection) {
|
|
||||||
nodes.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for any objects that want to be notified when a collection has been selected in the
|
|
||||||
* ServicePanel.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public interface ServiceSelectedListener {
|
|
||||||
/**
|
|
||||||
* Called to provide an update on whether the selected node is a Collection.
|
|
||||||
*
|
|
||||||
* @param collection The location of the collection. <code>null</code>, otherwise.
|
|
||||||
*/
|
|
||||||
public void selected(String collection);
|
|
||||||
}
|
|
@@ -1,455 +0,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/
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copyright (c) 2008, 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.client;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.apache.commons.fileupload.FileItem;
|
|
||||||
import org.apache.commons.fileupload.FileItemFactory;
|
|
||||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
|
||||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
|
||||||
import org.purl.sword.base.DepositResponse;
|
|
||||||
import org.purl.sword.base.SWORDEntry;
|
|
||||||
import org.purl.sword.base.ServiceDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example client that runs as a Servlet.
|
|
||||||
*
|
|
||||||
* @author Stuart Lewis
|
|
||||||
*/
|
|
||||||
public class ServletClient extends HttpServlet {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The user agent name of this library
|
|
||||||
*/
|
|
||||||
public static final String userAgent = "SWORDAPP Java Client: SWORD version 1.3 compatible (http://sourceforge" +
|
|
||||||
".net/projects/sword-app/)";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporary directory.
|
|
||||||
*/
|
|
||||||
private String tempDirectory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of urls for the destination services to access.
|
|
||||||
*/
|
|
||||||
private String[] urls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to determine if a proxy value should be set.
|
|
||||||
*/
|
|
||||||
private boolean useProxy = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The proxy host name.
|
|
||||||
*/
|
|
||||||
private String pHost;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The proxy port name.
|
|
||||||
*/
|
|
||||||
private int pPort;
|
|
||||||
|
|
||||||
/** Counter used during Deposit information. */
|
|
||||||
private static int counter = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the servlet.
|
|
||||||
*/
|
|
||||||
public void init() {
|
|
||||||
tempDirectory = getServletContext().getInitParameter(
|
|
||||||
"upload-temp-directory");
|
|
||||||
if ((tempDirectory == null) || (tempDirectory.equals(""))) {
|
|
||||||
tempDirectory = System.getProperty("java.io.tmpdir");
|
|
||||||
}
|
|
||||||
String lots = getServletContext().getInitParameter("client-urls");
|
|
||||||
urls = lots.split(",");
|
|
||||||
|
|
||||||
pHost = getServletContext().getInitParameter("proxy-host");
|
|
||||||
String pPortstr = getServletContext().getInitParameter("proxy-port");
|
|
||||||
if (((pHost != null) && (!pHost.equals("")))
|
|
||||||
&& ((pPortstr != null) && (!pPortstr.equals("")))) {
|
|
||||||
try {
|
|
||||||
pPort = Integer.parseInt(pPortstr);
|
|
||||||
useProxy = true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Port number not numeric
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a get request. Simply show the default form (form.jsp)
|
|
||||||
*
|
|
||||||
* @param request The request details
|
|
||||||
* @param response The response to write to.
|
|
||||||
*
|
|
||||||
* @throws ServletException
|
|
||||||
* An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws IOException
|
|
||||||
* A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
|
||||||
protected void doGet(HttpServletRequest request,
|
|
||||||
HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
// Get request, so show the default page
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("form.jsp").forward(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the post. Determine if the request is for a post or service
|
|
||||||
* document. Then, dispatch the request to the appropriate handler.
|
|
||||||
*
|
|
||||||
* @param request The request details.
|
|
||||||
* @param response The response to write to.
|
|
||||||
*
|
|
||||||
* @throws ServletException
|
|
||||||
* An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws IOException
|
|
||||||
* A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
protected void doPost(HttpServletRequest request,
|
|
||||||
HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
if (request.getParameter("servicedocument") != null) {
|
|
||||||
this.doServiceDocument(request, response);
|
|
||||||
} else if (request.getParameter("deposit") != null) {
|
|
||||||
request.setAttribute("url", request.getParameter("url"));
|
|
||||||
request.setAttribute("u", request.getParameter("u"));
|
|
||||||
request.setAttribute("p", request.getParameter("p"));
|
|
||||||
request.setAttribute("obo", request.getParameter("obo"));
|
|
||||||
request.setAttribute("abstract", request.getParameter("abstract"));
|
|
||||||
request.setAttribute("policy", request.getParameter("policy"));
|
|
||||||
request.setAttribute("treatment", request.getParameter("treatment"));
|
|
||||||
request.setAttribute("mediation", request.getParameter("mediation"));
|
|
||||||
request.setAttribute("accepts", request.getParameter("accepts"));
|
|
||||||
request.setAttribute("acceptsp", request.getParameter("acceptsp"));
|
|
||||||
request.setAttribute("maxuploadsize", request.getParameter("maxuploadsize"));
|
|
||||||
request.getRequestDispatcher("depositform.jsp").forward(request, response);
|
|
||||||
} else if (ServletFileUpload.isMultipartContent(request)) {
|
|
||||||
this.doDeposit(request, response);
|
|
||||||
} else {
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("form.jsp").forward(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process the request for a service document.
|
|
||||||
*
|
|
||||||
* @param request The request details.
|
|
||||||
* @param response The response to write to.
|
|
||||||
*
|
|
||||||
* @throws ServletException
|
|
||||||
* An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws IOException
|
|
||||||
* A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private void doServiceDocument(HttpServletRequest request,
|
|
||||||
HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
// Get the service document
|
|
||||||
Client client = new Client();
|
|
||||||
// Which URL do we want?
|
|
||||||
URL url = new URL(request.getParameter("url"));
|
|
||||||
String theUrl = request.getParameter("url");
|
|
||||||
|
|
||||||
if ((request.getParameter("ownurl") != null)
|
|
||||||
&& (!request.getParameter("ownurl").equals(""))) {
|
|
||||||
url = new URL(request.getParameter("ownurl"));
|
|
||||||
theUrl = request.getParameter("ownurl");
|
|
||||||
}
|
|
||||||
|
|
||||||
int port = url.getPort();
|
|
||||||
if (port == -1) {
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the server
|
|
||||||
client.setServer(url.getHost(), port);
|
|
||||||
client.setCredentials(request.getParameter("u"), request.getParameter("p"));
|
|
||||||
if (useProxy) {
|
|
||||||
client.setProxy(pHost, pPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ServiceDocument sd = client.getServiceDocument(theUrl,
|
|
||||||
request.getParameter("obo"));
|
|
||||||
|
|
||||||
// Set the status
|
|
||||||
Status status = client.getStatus();
|
|
||||||
request.setAttribute("status", status.toString());
|
|
||||||
if (status.getCode() == 200) {
|
|
||||||
// Set the debug response
|
|
||||||
String xml = sd.marshall();
|
|
||||||
|
|
||||||
String validateXml = xml;
|
|
||||||
validateXml = validateXml.replaceAll("&", "&");
|
|
||||||
validateXml = validateXml.replaceAll("<", "<");
|
|
||||||
validateXml = validateXml.replaceAll(">", ">");
|
|
||||||
validateXml = validateXml.replaceAll("\"", """);
|
|
||||||
validateXml = validateXml.replaceAll("'", "'");
|
|
||||||
request.setAttribute("xmlValidate", validateXml); // for passing to validation
|
|
||||||
|
|
||||||
xml = xml.replaceAll("<", "<");
|
|
||||||
xml = xml.replaceAll(">", ">");
|
|
||||||
request.setAttribute("xml", xml);
|
|
||||||
|
|
||||||
// Set the ServiceDocument and associated values
|
|
||||||
request.setAttribute("sd", sd);
|
|
||||||
request.setAttribute("sdURL", theUrl);
|
|
||||||
request.setAttribute("u", request.getParameter("u"));
|
|
||||||
request.setAttribute("p", request.getParameter("p"));
|
|
||||||
request.setAttribute("sdOBO", request.getParameter("obo"));
|
|
||||||
request.getRequestDispatcher("servicedocument.jsp").forward(
|
|
||||||
request, response);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
request.setAttribute("error", status.getCode() + " "
|
|
||||||
+ status.getMessage());
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("form.jsp").forward(request,
|
|
||||||
response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (SWORDClientException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
request.setAttribute("error", e.toString());
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("form.jsp").forward(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a deposit.
|
|
||||||
*
|
|
||||||
* @param request The request details.
|
|
||||||
* @param response The response to output to.
|
|
||||||
*
|
|
||||||
* @throws ServletException
|
|
||||||
* An exception that provides information on a database access error or other errors.
|
|
||||||
* @throws IOException
|
|
||||||
* A general class of exceptions produced by failed or interrupted I/O operations.
|
|
||||||
*/
|
|
||||||
private void doDeposit(HttpServletRequest request,
|
|
||||||
HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
// Do the deposit
|
|
||||||
Client client = new Client();
|
|
||||||
try {
|
|
||||||
PostMessage message = new PostMessage();
|
|
||||||
message.setUserAgent(ClientConstants.SERVICE_NAME);
|
|
||||||
|
|
||||||
// Get the file
|
|
||||||
FileItemFactory factory = new DiskFileItemFactory();
|
|
||||||
|
|
||||||
// Create a new file upload handler
|
|
||||||
ServletFileUpload upload = new ServletFileUpload(factory);
|
|
||||||
|
|
||||||
// Parse the request
|
|
||||||
List<FileItem> items = upload.parseRequest(request);
|
|
||||||
Iterator<FileItem> iter = items.iterator();
|
|
||||||
String u = null;
|
|
||||||
String p = null;
|
|
||||||
String contentDisposition = null;
|
|
||||||
String filetype = null;
|
|
||||||
boolean useMD5 = false;
|
|
||||||
boolean errorMD5 = false;
|
|
||||||
boolean verbose = false;
|
|
||||||
boolean noOp = false;
|
|
||||||
boolean login = false;
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
FileItem item = iter.next();
|
|
||||||
if (item.isFormField()) {
|
|
||||||
String name = item.getFieldName();
|
|
||||||
String value = item.getString();
|
|
||||||
if (name.equals("url")) {
|
|
||||||
message.setDestination(value);
|
|
||||||
URL url = new URL(value);
|
|
||||||
int port = url.getPort();
|
|
||||||
if (port == -1) {
|
|
||||||
port = 80;
|
|
||||||
}
|
|
||||||
client.setServer(url.getHost(), port);
|
|
||||||
} else if (name.equals("usemd5")) {
|
|
||||||
useMD5 = true;
|
|
||||||
} else if (name.equals("errormd5")) {
|
|
||||||
errorMD5 = true;
|
|
||||||
} else if (name.equals("verbose")) {
|
|
||||||
verbose = true;
|
|
||||||
} else if (name.equals("noop")) {
|
|
||||||
noOp = true;
|
|
||||||
} else if (name.equals("obo")) {
|
|
||||||
message.setOnBehalfOf(value);
|
|
||||||
} else if (name.equals("slug")) {
|
|
||||||
if ((value != null) && (!value.trim().equals(""))) {
|
|
||||||
message.setSlug(value);
|
|
||||||
}
|
|
||||||
} else if (name.equals("cd")) {
|
|
||||||
contentDisposition = value;
|
|
||||||
} else if (name.equals("filetype")) {
|
|
||||||
filetype = value;
|
|
||||||
} else if (name.equals("formatnamespace")) {
|
|
||||||
if ((value != null) && (!value.trim().equals(""))) {
|
|
||||||
message.setFormatNamespace(value);
|
|
||||||
}
|
|
||||||
} else if (name.equals("u")) {
|
|
||||||
u = value;
|
|
||||||
login = true;
|
|
||||||
request.setAttribute("u", value);
|
|
||||||
} else if (name.equals("p")) {
|
|
||||||
p = value;
|
|
||||||
login = true;
|
|
||||||
}
|
|
||||||
request.setAttribute(name, value);
|
|
||||||
} else {
|
|
||||||
String fname = tempDirectory + File.separator +
|
|
||||||
"ServletClient-" + counter++;
|
|
||||||
if ((contentDisposition != null) && (!contentDisposition.equals(""))) {
|
|
||||||
fname = tempDirectory + File.separator + contentDisposition;
|
|
||||||
}
|
|
||||||
|
|
||||||
File uploadedFile = new File(fname);
|
|
||||||
item.write(uploadedFile);
|
|
||||||
message.setFilepath(fname);
|
|
||||||
|
|
||||||
if ((filetype == null) || (filetype.trim().equals(""))) {
|
|
||||||
message.setFiletype(item.getContentType());
|
|
||||||
} else {
|
|
||||||
message.setFiletype(filetype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (login) {
|
|
||||||
client.setCredentials(u, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useProxy) {
|
|
||||||
client.setProxy(pHost, pPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
message.setUseMD5(useMD5);
|
|
||||||
message.setChecksumError(errorMD5);
|
|
||||||
message.setVerbose(verbose);
|
|
||||||
message.setNoOp(noOp);
|
|
||||||
|
|
||||||
// Post the file
|
|
||||||
DepositResponse resp = client.postFile(message);
|
|
||||||
|
|
||||||
// Set the status
|
|
||||||
Status status = client.getStatus();
|
|
||||||
request.setAttribute("status", status.toString());
|
|
||||||
if ((status.getCode() == 201) || (status.getCode() == 202)) {
|
|
||||||
// Set the debug response
|
|
||||||
String xml = resp.marshall();
|
|
||||||
|
|
||||||
String validateXml = xml;
|
|
||||||
validateXml = validateXml.replaceAll("&", "&");
|
|
||||||
validateXml = validateXml.replaceAll("<", "<");
|
|
||||||
validateXml = validateXml.replaceAll(">", ">");
|
|
||||||
validateXml = validateXml.replaceAll("\"", """);
|
|
||||||
validateXml = validateXml.replaceAll("'", "'");
|
|
||||||
request.setAttribute("xmlValidate", validateXml); // for passing to validation
|
|
||||||
|
|
||||||
xml = xml.replaceAll("<", "<");
|
|
||||||
xml = xml.replaceAll(">", ">");
|
|
||||||
request.setAttribute("xml", xml);
|
|
||||||
SWORDEntry se = resp.getEntry();
|
|
||||||
request.setAttribute("id", se.getId());
|
|
||||||
request.setAttribute("authors", se.getAuthors());
|
|
||||||
request.setAttribute("contributors", se.getContributors());
|
|
||||||
request.setAttribute("title", se.getTitle().getContent());
|
|
||||||
request.setAttribute("updated", se.getUpdated());
|
|
||||||
request.setAttribute("categories", se.getCategories());
|
|
||||||
request.setAttribute("treatment", se.getTreatment());
|
|
||||||
request.setAttribute("summary", se.getSummary().getContent());
|
|
||||||
request.setAttribute("generator", se.getGenerator().getContent());
|
|
||||||
request.setAttribute("userAgent", se.getUserAgent());
|
|
||||||
request.setAttribute("packaging", se.getPackaging());
|
|
||||||
request.setAttribute("links", se.getLinks());
|
|
||||||
request.setAttribute("location", resp.getLocation());
|
|
||||||
|
|
||||||
// Set the ServiceDocument and associated values
|
|
||||||
request.getRequestDispatcher("deposit.jsp").forward(request, response);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
String error = status.getCode() + " " + status.getMessage() + " - ";
|
|
||||||
try {
|
|
||||||
error += resp.getEntry().getSummary().getContent();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Do nothing - we have default error message
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
request.setAttribute("error", error);
|
|
||||||
|
|
||||||
// Try and get an error document in xml
|
|
||||||
String xml = resp.marshall();
|
|
||||||
xml = xml.replaceAll("<", "<");
|
|
||||||
xml = xml.replaceAll(">", ">");
|
|
||||||
request.setAttribute("xml", xml);
|
|
||||||
|
|
||||||
request.getRequestDispatcher("depositform.jsp").forward(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
request.setAttribute("error", "value: " + e.toString());
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("depositform.jsp").forward(request, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
request.setAttribute("error", "value: " + e.toString());
|
|
||||||
request.setAttribute("urls", urls);
|
|
||||||
request.getRequestDispatcher("depositform.jsp").forward(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,61 +0,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/
|
|
||||||
*/
|
|
||||||
package org.purl.sword.client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Representation of the status code and message.
|
|
||||||
*
|
|
||||||
* @author Neil Taylor
|
|
||||||
*/
|
|
||||||
public class Status {
|
|
||||||
/**
|
|
||||||
* The status code.
|
|
||||||
*/
|
|
||||||
private int code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The status message.
|
|
||||||
*/
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new status message.
|
|
||||||
*
|
|
||||||
* @param code The code.
|
|
||||||
* @param message The message.
|
|
||||||
*/
|
|
||||||
public Status(int code, String message) {
|
|
||||||
this.code = code;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the code.
|
|
||||||
*
|
|
||||||
* @return The code.
|
|
||||||
*/
|
|
||||||
public int getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the message.
|
|
||||||
*
|
|
||||||
* @return The message.
|
|
||||||
*/
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string representation of the status.
|
|
||||||
*/
|
|
||||||
public String toString() {
|
|
||||||
return "Code: " + code + ", Message: '" + message + "'";
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user