/** * 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.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; /** * Filetype. */ 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 Logger log = Logger.getLogger(ClientOptions.class); /** * List of multiple destination items. Used if the mode is set to multipost. */ private List<PostDestination> multiPost = new ArrayList<PostDestination>(); /** * Pattern string to extract the data from a destination parameter in multipost mode. */ private static final Pattern multiPattern = 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 ) { try { // iterate over the args for ( int i = 0; i < args.length; i++ ) { if ( "-md5".equals(args[i])) { md5 = true; } if ( "-noOp".equals(args[i])) { noOp = true; } if ( "-verbose".equals(args[i])) { verbose = true; } if ( "-cmd".equals(args[i]) ) { guiMode = false; } if ( "-gui".equals(args[i]) ) { guiMode = true; } if ( "-host".equals(args[i]) ) { i++; proxyHost = args[i]; } if ( "-port".equals(args[i]) ) { i++; proxyPort = Integer.parseInt(args[i]); } if ( "-u".equals(args[i]) ) { i++; username = args[i]; } if ( "-p".equals(args[i])) { i++; password = args[i]; } if ( "-href".equals(args[i])) { i++; href = args[i]; } if ( "-help".equals(args[i]) ) { // force the calling code to display the usage information return false; } if ( "-t".equals(args[i])) { i++; accessType = args[i]; } if ( "-file".equals(args[i])) { i++; filename = args[i]; } if ( "-filetype".equals(args[i])) { i++; filetype = args[i]; } if ( "-slug".equals(args[i])) { i++; slug = args[i]; } if ( "-onBehalfOf".equals(args[i])) { i++; onBehalfOf = args[i]; } if ( "-formatNamespace".equals(args[i])) { i++; formatNamespace = args[i]; } if ( "-checksumError".equals(args[i])) { i++; checksumError = true; } if ( "-dest".equals(args[i])) { i++; Matcher m = multiPattern.matcher(args[i]); if ( ! m.matches() ) { log.debug("Error with dest parameter. Ignoring value: " + args[i]); } else { int numGroups = m.groupCount(); for ( int g = 0; g <= numGroups; g++ ) { log.debug("Group (" + g + ") is: " + m.group(g)); } String username = m.group(1); String onBehalfOf = m.group(3); String password = m.group(5); String url = m.group(6); PostDestination destination = new PostDestination(url, username, password, onBehalfOf); multiPost.add(destination); } } if ( "-nocapture".equals(args[i]) ) { i++; noCapture = true; } } // apply any settings if ( href == null && "service".equals(accessType) ) { log.error( "No href specified."); return false; } if ( multiPost.size() == 0 && "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; } }