1 /* Copyright (c) 2009 Peter Troshin
\r
3 * JAva Bioinformatics Analysis Web Services (JABAWS) @version: 1.0
\r
5 * This library is free software; you can redistribute it and/or modify it under the terms of the
\r
6 * Apache License version 2 as published by the Apache Software Foundation
\r
8 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
\r
9 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache
\r
10 * License for more details.
\r
12 * A copy of the license is in apache_license.txt. It is also available here:
\r
13 * @see: http://www.apache.org/licenses/LICENSE-2.0.txt
\r
15 * Any republication or derived work distributed in source code form
\r
16 * must include this copyright and license notice.
\r
19 package compbio.metadata;
\r
21 import java.net.MalformedURLException;
\r
22 import java.net.URL;
\r
23 import java.util.ArrayList;
\r
24 import java.util.HashSet;
\r
25 import java.util.List;
\r
26 import java.util.Set;
\r
27 import java.util.TreeSet;
\r
29 import javax.xml.bind.ValidationException;
\r
30 import javax.xml.bind.annotation.XmlAccessType;
\r
31 import javax.xml.bind.annotation.XmlAccessorType;
\r
32 import javax.xml.bind.annotation.XmlAttribute;
\r
33 import javax.xml.bind.annotation.XmlElement;
\r
34 import javax.xml.bind.annotation.XmlTransient;
\r
36 import compbio.util.SysPrefs;
\r
37 import compbio.util.Util;
\r
40 * Command line option/flag or multiple exclusive options with no value. Example
\r
41 * -protein, -dna, -auto
\r
45 * @version 1.0 October 2009
\r
47 * type of executable
\r
49 @XmlAccessorType(XmlAccessType.FIELD)
\r
50 public class Option<T> implements Argument<T> {
\r
52 @XmlElement(required = true)
\r
53 protected String description;
\r
55 @XmlElement(required = true)
\r
56 Set<String> optionNames = new HashSet<String>();
\r
58 @XmlElement(required = true)
\r
59 protected String name;
\r
62 protected boolean isRequired;
\r
64 protected String furtherDetails;
\r
66 protected String defaultValue;
\r
68 private URL basicURL;
\r
71 // Has to have no arg constructor for JAXB
\r
74 public Option(String name, String description) throws MalformedURLException {
\r
76 this.description = description;
\r
80 * Human readable name of the option
\r
82 public String getName() {
\r
86 public void setName(String name) {
\r
90 public void setBasicURL(URL url) {
\r
91 this.basicURL = url;
\r
93 public URL getBasicURL() throws MalformedURLException {
\r
94 URL out = new URL ("http://unknown.jabaws.server.ac.uk");
\r
95 if (null != basicURL) {
\r
101 * A long description of the Option
\r
103 public String getDescription() {
\r
104 return description;
\r
107 public void setDescription(String description) {
\r
108 this.description = description;
\r
112 * The URL where further details about the option can be found
\r
113 * @throws MalformedURLException
\r
115 public String getFurtherDetails() {
\r
116 return furtherDetails;
\r
119 public void setFurtherDetails(String furtherDetails) {
\r
120 this.furtherDetails = furtherDetails;
\r
124 * A default value of the option. Defaults to command line argument name
\r
127 public String getDefaultValue() {
\r
128 return defaultValue;
\r
132 * Sets one of the values defined in optionList as default. Attempting set
\r
133 * the value not listed there will result in WrongParameter exception
\r
135 * @param defaultVal
\r
136 * @throws WrongParameterException
\r
137 * is thrown if the defaultValue is not found in optionList
\r
139 public void setDefaultValue(String defaultVal)
\r
140 throws WrongParameterException {
\r
141 if (optionNames.isEmpty()) {
\r
142 throw new IllegalStateException("Please define optionNames first!");
\r
144 if (!valueExist(defaultVal, getOptionNames())) {
\r
145 throw new WrongParameterException(
\r
146 "Attempting to set illegal defaultValue '" + defaultVal
\r
147 + "' which is not defined optionNames for option: "
\r
150 this.defaultValue = defaultVal;
\r
153 static boolean valueExist(String testValue, List<String> values) {
\r
154 assert !Util.isEmpty(testValue);
\r
155 for (String val : values) {
\r
156 if (testValue.equalsIgnoreCase(val)) {
\r
164 * Flag that indicated that this option must be specified in the command
\r
165 * line for an executable to run
\r
167 * @return true is the option is required, false otherwise
\r
169 public boolean isRequired() {
\r
173 public void setRequired(boolean isRequired) {
\r
174 this.isRequired = isRequired;
\r
179 * @return List of option names
\r
181 public List<String> getOptionNames() {
\r
182 return new ArrayList<String>(optionNames);
\r
185 public void setOptionNames(Set<String> optionNames) {
\r
186 this.optionNames = new HashSet<String>(optionNames);
\r
190 * Adds an option to the optionName list
\r
193 * @return modified optionName list
\r
195 public Set<String> addOptionNames(String... value) {
\r
196 for (String v : value) {
\r
197 boolean added = this.optionNames.add(v);
\r
198 assert added : "Duplicated optionName is detected!";
\r
200 return this.optionNames;
\r
204 public String toString() {
\r
205 String value = "Option name: " + this.name + SysPrefs.newlinechar;
\r
206 value += "Description: " + this.description + SysPrefs.newlinechar;
\r
207 if (!Util.isEmpty(defaultValue)) {
\r
208 value += "Default value: " + this.defaultValue + SysPrefs.newlinechar;
\r
210 if (null != this.furtherDetails) {
\r
211 if (null != this.basicURL) {
\r
212 value += "URL: " + this.basicURL + this.furtherDetails + SysPrefs.newlinechar;
\r
214 value += "Relative URL: " + this.furtherDetails + SysPrefs.newlinechar;
\r
217 value += "URL: unknown URL" + SysPrefs.newlinechar;
\r
219 value += "Is required: " + this.isRequired + SysPrefs.newlinechar;
\r
220 if (!this.optionNames.isEmpty()) {
\r
221 Set<String> sortedPosval = new TreeSet<String>(this.optionNames);
\r
222 value += "Option(s): ";
\r
224 for (String val : sortedPosval) {
\r
225 value += delim + val;
\r
228 value += SysPrefs.newlinechar;
\r
234 * Convert the option to the command string.
\r
236 * @return If only one optionName is defined, than it is returned, if many
\r
237 * option names are defined, then the defaultValue is returned.
\r
238 * Option must have a default value if there are many optionNames to
\r
241 public String toCommand(String nameValueSeparator) {
\r
242 if (optionNames.size() == 1) {
\r
243 return optionNames.iterator().next();
\r
245 return getDefaultValue();
\r
249 public boolean equals(Object obj) {
\r
253 Option<?> objArg = null;
\r
254 if (obj instanceof Option<?>) {
\r
255 objArg = (Option<?>) obj;
\r
259 if (!Util.isEmpty(objArg.name) && !Util.isEmpty(name)) {
\r
260 if (!objArg.name.equals(this.name)) {
\r
264 if (!Util.isEmpty(objArg.description) && !Util.isEmpty(description)) {
\r
265 if (!objArg.description.equals(this.description)) {
\r
269 if (objArg.isRequired != this.isRequired) {
\r
272 if (!Util.isEmpty(objArg.defaultValue) && !Util.isEmpty(defaultValue)) {
\r
273 if (!objArg.defaultValue.equals(this.defaultValue)) {
\r
277 if (objArg.optionNames.size() != this.optionNames.size()) {
\r
280 int matchCount = 0;
\r
281 for (String oname : objArg.optionNames) {
\r
282 if (Util.isEmpty(oname)) {
\r
285 for (String thisoname : this.optionNames) {
\r
286 if (oname.equals(thisoname)) {
\r
292 if (matchCount != objArg.optionNames.size()) {
\r
299 public int hashCode() {
\r
300 int code = this.name.hashCode() * this.description.hashCode();
\r
301 if (this.isRequired) {
\r
302 code += this.furtherDetails.hashCode() * 3;
\r
304 if (defaultValue != null) {
\r
305 code += this.defaultValue.hashCode() * 2;
\r
308 if (this.description != null) {
\r
309 code += this.description.hashCode() * 4;
\r
316 * List of possible optionNames
\r
319 public List<String> getPossibleValues() {
\r
320 return new ArrayList<String>(optionNames);
\r
324 public void setValue(String dValue) throws WrongParameterException {
\r
325 this.setDefaultValue(dValue);
\r
329 * Validate the option
\r
331 * @throws ValidationException
\r
332 * is the option is invalid. This happens if option does not
\r
333 * have a default value but have multiple option names, or no
\r
334 * option names is defined
\r
336 void validate() throws ValidationException {
\r
337 if (optionNames == null) {
\r
338 throw new ValidationException(
\r
339 "Option names are not defined for option: " + this);
\r
341 if (optionNames.size() > 1 && Util.isEmpty(getDefaultValue())) {
\r
342 throw new ValidationException(
\r
343 "Default value is required as multiple optionNames are defined for option: "
\r
346 if (Util.isEmpty(name)) {
\r
347 throw new ValidationException("No name is defined for option: "
\r