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.security.InvalidParameterException;
\r
22 import java.util.ArrayList;
\r
23 import java.util.List;
\r
25 import javax.xml.bind.ValidationException;
\r
26 import javax.xml.bind.annotation.XmlElement;
\r
27 import javax.xml.bind.annotation.XmlRootElement;
\r
28 import javax.xml.bind.annotation.XmlTransient;
\r
30 import compbio.util.SysPrefs;
\r
31 import compbio.util.annotation.NotThreadSafe;
\r
34 * The list of {@link Parameter}s and {@link Option}s supported by executable.
\r
35 * The lists is defined in and loaded from <ExecutableName>Parameters.xml file.
\r
39 * @version 1.0 October 2009
\r
41 * type of an Executable
\r
45 public class RunnerConfig<T> {
\r
48 * Please note that the order of the fields in this class is important to
\r
49 * generate xml compliant to the hand written schema!!!
\r
53 * The class name of a runnable e.g. T
\r
55 private String runnerClassName;
\r
56 List<Option<T>> options = new ArrayList<Option<T>>();
\r
57 String prmSeparator;
\r
58 List<Parameter<T>> parameters = new ArrayList<Parameter<T>>();
\r
61 List<Option<T>> arguments;
\r
63 public RunnerConfig() {
\r
64 // JAXB default constructor
\r
67 public RunnerConfig<T> copyAndValidateRConfig(RunnerConfig<?> runnerConf) {
\r
68 if (this.runnerClassName != runnerConf.runnerClassName) {
\r
69 throw new InvalidParameterException("Wrong runner configuration! ");
\r
71 RunnerConfig<T> newrconfig = new RunnerConfig<T>();
\r
72 newrconfig.runnerClassName = runnerConf.runnerClassName;
\r
73 newrconfig.options = new ArrayList<Option<T>>(options);
\r
78 * Returns the list of the Options supported by the executable of type T
\r
80 * @return list of {@link Option} supported by type T
\r
83 public List<Option<T>> getOptions() {
\r
88 * Adds parameter to the internal parameter list
\r
91 * the {@link Parameter} to add
\r
94 public void addParameter(Parameter<T> param) {
\r
95 assert param != null;
\r
96 parameters.add(param);
\r
100 * Adds Option to the internal list of options
\r
103 * the {@link Option} to add
\r
105 public void addOption(Option<T> option) {
\r
106 assert option != null;
\r
107 options.add(option);
\r
111 * Returns list of {@link Parameter} and {@link Option} supported by current
\r
114 * @return list of {@link Option} and {@link Parameter} supported by type T
\r
117 public List<Option<T>> getArguments() {
\r
118 arguments = new ArrayList<Option<T>>(options);
\r
119 arguments.addAll(parameters);
\r
125 * @return name value separator character
\r
127 public String getPrmSeparator() {
\r
128 return prmSeparator;
\r
132 * Sets name value separator character
\r
134 * @param prmSeparator
\r
135 * the separator char
\r
137 public void setPrmSeparator(String prmSeparator) {
\r
138 this.prmSeparator = prmSeparator;
\r
142 * Adds the list of options or parameters to the internal list of options
\r
144 * @param parameters
\r
145 * the list of parameters to add
\r
148 public void setOptions(List<Option<T>> parameters) {
\r
149 this.options = parameters;
\r
154 * @return fully qualified class name for type T
\r
156 @XmlElement(required = true)
\r
157 public String getRunnerClassName() {
\r
158 return runnerClassName;
\r
162 * Set the name of a runner class
\r
164 * @param runnerClassName
\r
165 * the name of the executable wrapping class
\r
167 public void setRunnerClassName(String runnerClassName) {
\r
168 this.runnerClassName = runnerClassName;
\r
172 * Sets the list of parameters as internal list
\r
174 * @param parameters
\r
175 * the list of parameters
\r
177 public void setParameters(List<Parameter<T>> parameters) {
\r
178 this.parameters = parameters;
\r
182 * Returns the list of parameters supported executable of type T. Where
\r
183 * {@link Parameter} is an {@link Option} with value.
\r
185 * @return List of {@link Parameter} supported by type T.
\r
187 public List<Parameter<T>> getParameters() {
\r
192 public String toString() {
\r
193 String value = "Runner: " + this.runnerClassName + SysPrefs.newlinechar;
\r
194 for (Option<T> par : this.getArguments()) {
\r
201 * Cast is safe as runnerClassNames equality checked (non-Javadoc)
\r
202 * @see java.lang.Object#equals(java.lang.Object)
\r
204 @SuppressWarnings("unchecked")
\r
206 public boolean equals(Object obj) {
\r
210 RunnerConfig<?> rconf = null;
\r
211 if (obj instanceof RunnerConfig) {
\r
212 rconf = (RunnerConfig) obj;
\r
214 if (!rconf.runnerClassName.equals(this.runnerClassName)) {
\r
217 if (this.options.size() != rconf.options.size()) {
\r
220 if (this.parameters.size() != rconf.parameters.size()) {
\r
223 if (!this.prmSeparator.equals(rconf.prmSeparator)) {
\r
226 // Size of option list is the same at that point
\r
227 for (Option<T> op : options) {
\r
228 Option<T> roption = (Option<T>) rconf.getArgument(op.getName());
\r
229 if (roption == null) {
\r
232 if (!op.equals(roption)) {
\r
236 // Size of parameters list is the same at that point
\r
237 for (Parameter<T> par : parameters) {
\r
238 Parameter<T> rpar = (Parameter<T>) rconf.getArgument(par.getName());
\r
239 if (rpar == null) {
\r
242 if (!par.equals(rpar)) {
\r
250 * Returns the argument by its name if found, NULL otherwise. Where the
\r
251 * Argument is a common interface for {@link Option} and {@link Parameter}
\r
252 * therefore this method can return either. If you need to retrieve the
\r
253 * Option by its optionNames use @link
\r
254 * {@link RunnerConfig#getArgumentByOptionName(String)} method. The
\r
255 * difference between option name and optionName is explained by the
\r
256 * following example:
\r
259 * <name>Sequence type</name>
\r
261 * --nuc - Assume the sequences are nucleotide.
\r
262 * --amino - Assume the sequences are amino acid. </description>
\r
263 * <optionNames>--amino</optionNames>
\r
264 * <optionNames>--nuc</optionNames>
\r
265 * <optionNames>--auto</optionNames>
\r
268 * In the example, the "Sequence type" is a name whereas --amino, --nuc and
\r
269 * --auto are all optionNames. This dichotomy only manifests in
\r
270 * <code>Option</code> never in <code>Parameters</code> as the latter can
\r
271 * only have single <optioNames> element
\r
274 * the Parameter of Option name
\r
275 * @return {@link Argument}
\r
277 public Option<T> getArgument(String name) {
\r
278 for (Option<T> par : getArguments()) {
\r
279 if (par.getName().equalsIgnoreCase(name)) {
\r
287 * Removes the argument {@link Argument} if found. Where Argument is either
\r
288 * {@link Option} or {@link Parameter}.
\r
292 * @return true if argument was removed, false otherwise
\r
294 @SuppressWarnings("unchecked")
\r
295 // Just use raw type in instanceof this is safe
\r
296 public boolean removeArgument(String name) {
\r
297 Option<T> par = getArgument(name);
\r
299 if (par instanceof Parameter) {
\r
300 parameters.remove(par);
\r
303 this.options.remove(par);
\r
311 * Returns the argument by option name, NULL if the argument is not found
\r
313 * @param optionName
\r
314 * - the optionName. This is not the same as an Option name.
\r
319 * <name>Output sequences order</name>
\r
320 * <description>--inputorder - Output order: same as input.
\r
321 * --reorder - Output order: aligned. Default: same as input</description>
\r
322 * <optionNames>--inputorder</optionNames>
\r
323 * <optionNames>--reorder</optionNames>
\r
326 * The name of the option in the example is
\r
327 * "Output sequences order" whereas optionNames are
\r
328 * "--inputorder" and "--reorder". If you need to retrieve the
\r
329 * Option or Parameter by its names use
\r
330 * {@link RunnerConfig#getArgument(String)} method
\r
333 public Option<T> getArgumentByOptionName(String optionName) {
\r
334 for (Option<T> opt : getArguments()) {
\r
335 for (String val : opt.getOptionNames()) {
\r
336 if (val.equalsIgnoreCase(optionName)) {
\r
346 * Removes the argument which can be a Parameter or an Option instance by
\r
347 * the value in <optionNames> element of the runner configuration
\r
350 * @param optionName
\r
351 * the optionName of the option, do not confuse with the name!
\r
352 * @return true if argument with optionName exists and was removed, false
\r
354 * @see RunnerConfig#getArgumentByOptionName(String) for destinctions
\r
355 * between optionNames and the name of the Option
\r
357 @SuppressWarnings("unchecked")
\r
358 // Just use raw type in instanceof this is safe
\r
359 public boolean removeArgumentByOptionName(String optionName) {
\r
360 Option<T> par = getArgumentByOptionName(optionName);
\r
362 if (par instanceof Parameter) {
\r
363 this.parameters.remove(par);
\r
366 this.options.remove(par);
\r
374 * Validate the value of the argument. Checks whether the argument value is
\r
375 * in the valid values range.
\r
377 * @throws ValidationException
\r
378 * if any of the arguments found invalid which is when
\r
380 * <li>Parameter value outside {@link ValueConstrain} boundary</li>
\r
381 * <li>Parameter name is not listed in possible values</li>
\r
384 public void validate() throws ValidationException {
\r
385 for (Option<?> option : getArguments()) {
\r