Next version of JABA
[jabaws.git] / datamodel / compbio / metadata / RunnerConfig.java
1 /* Copyright (c) 2009 Peter Troshin\r
2  *  \r
3  *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 1.0\r
4  * \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
7  * \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
11  * \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
14  * \r
15  * Any republication or derived work distributed in source code form\r
16  * must include this copyright and license notice.\r
17  */\r
18 \r
19 package compbio.metadata;\r
20 \r
21 import java.security.InvalidParameterException;\r
22 import java.util.ArrayList;\r
23 import java.util.List;\r
24 \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
29 \r
30 import compbio.util.SysPrefs;\r
31 import compbio.util.annotation.NotThreadSafe;\r
32 \r
33 /**\r
34  * The list of {@link Parameter}s and {@link Option}s supported by executable.\r
35  * \r
36  * @author pvtroshin\r
37  * \r
38  *         Date October 2009\r
39  * @param <T>\r
40  *            type of an Executable\r
41  */\r
42 @XmlRootElement\r
43 @NotThreadSafe\r
44 public class RunnerConfig<T> {\r
45 \r
46     /**\r
47      * Please note that the order of the fields is important to generate xml\r
48      * compliant to the hand written schema!!!\r
49      */\r
50     /**\r
51      * The class name of a runnable e.g. T\r
52      */\r
53     private String runnerClassName;\r
54     List<Option<T>> options = new ArrayList<Option<T>>();\r
55     String prmSeparator;\r
56     List<Parameter<T>> parameters = new ArrayList<Parameter<T>>();\r
57 \r
58     @XmlTransient\r
59     List<Option<T>> arguments;\r
60 \r
61     public RunnerConfig() {\r
62         // JAXB default constructor\r
63     }\r
64 \r
65     public RunnerConfig<T> copyAndValidateRConfig(RunnerConfig<?> runnerConf) {\r
66         if (this.runnerClassName != runnerConf.runnerClassName) {\r
67             throw new InvalidParameterException("Wrong runner configuration! ");\r
68         }\r
69         RunnerConfig<T> newrconfig = new RunnerConfig<T>();\r
70         newrconfig.runnerClassName = runnerConf.runnerClassName;\r
71         newrconfig.options = new ArrayList<Option<T>>(options);\r
72         return newrconfig;\r
73     }\r
74 \r
75     /**\r
76      * \r
77      * @return list of {@link Option} supported by type T\r
78      */\r
79     public List<Option<T>> getOptions() {\r
80         return options;\r
81     }\r
82 \r
83     public void addParameter(Parameter<T> param) {\r
84         assert param != null;\r
85         parameters.add(param);\r
86     }\r
87 \r
88     public void addOption(Option<T> option) {\r
89         assert option != null;\r
90         options.add(option);\r
91     }\r
92 \r
93     /**\r
94      * \r
95      * @return list of {@link Option} and {@link Parameter} supported by type T\r
96      */\r
97     @XmlTransient\r
98     public List<Option<T>> getArguments() {\r
99         arguments = new ArrayList<Option<T>>(options);\r
100         arguments.addAll(parameters);\r
101         return arguments;\r
102     }\r
103 \r
104     /**\r
105      * \r
106      * @return name value separator character\r
107      */\r
108     public String getPrmSeparator() {\r
109         return prmSeparator;\r
110     }\r
111 \r
112     public void setPrmSeparator(String prmSeparator) {\r
113         this.prmSeparator = prmSeparator;\r
114     }\r
115 \r
116     public void setOptions(List<Option<T>> parameters) {\r
117         this.options = parameters;\r
118     }\r
119 \r
120     /**\r
121      * \r
122      * @return fully qualified class name for type T\r
123      */\r
124     @XmlElement(required = true)\r
125     public String getRunnerClassName() {\r
126         return runnerClassName;\r
127     }\r
128 \r
129     public void setRunnerClassName(String runnerClassName) {\r
130         this.runnerClassName = runnerClassName;\r
131     }\r
132 \r
133     public void setParameters(List<Parameter<T>> parameters) {\r
134         this.parameters = parameters;\r
135     }\r
136 \r
137     /**\r
138      * \r
139      * @return List of {@link Parameter} supported by type T.\r
140      */\r
141     public List<Parameter<T>> getParameters() {\r
142         return parameters;\r
143     }\r
144 \r
145     @Override\r
146     public String toString() {\r
147         String value = "Runner: " + this.runnerClassName + SysPrefs.newlinechar;\r
148         for (Option<T> par : this.getArguments()) {\r
149             value += par;\r
150         }\r
151         return value;\r
152     }\r
153 \r
154     /*\r
155      * Cast is safe as runnerClassNames equality checked (non-Javadoc)\r
156      * \r
157      * @see java.lang.Object#equals(java.lang.Object)\r
158      */\r
159     @SuppressWarnings("unchecked")\r
160     @Override\r
161     public boolean equals(Object obj) {\r
162         if (obj == null) {\r
163             return false;\r
164         }\r
165         RunnerConfig<?> rconf = null;\r
166         if (obj instanceof RunnerConfig) {\r
167             rconf = (RunnerConfig) obj;\r
168         }\r
169         if (!rconf.runnerClassName.equals(this.runnerClassName)) {\r
170             return false;\r
171         }\r
172         if (this.options.size() != rconf.options.size()) {\r
173             return false;\r
174         }\r
175         if (this.parameters.size() != rconf.parameters.size()) {\r
176             return false;\r
177         }\r
178         if (!this.prmSeparator.equals(rconf.prmSeparator)) {\r
179             return false;\r
180         }\r
181         // Size of option list is the same at that point\r
182         for (Option<T> op : options) {\r
183             Option<T> roption = (Option<T>) rconf.getArgument(op.getName());\r
184             if (roption == null) {\r
185                 return false;\r
186             }\r
187             if (!op.equals(roption)) {\r
188                 return false;\r
189             }\r
190         }\r
191         // Size of parameters list is the same at that point\r
192         for (Parameter<T> par : parameters) {\r
193             Parameter<T> rpar = (Parameter<T>) rconf.getArgument(par.getName());\r
194             if (rpar == null) {\r
195                 return false;\r
196             }\r
197             if (!par.equals(rpar)) {\r
198                 return false;\r
199             }\r
200         }\r
201         return true;\r
202     }\r
203 \r
204     /**\r
205      * Returns the argument by its name if found, NULL otherwise\r
206      * \r
207      * @param name\r
208      * @return {@link Argument}\r
209      */\r
210     public Option<T> getArgument(String name) {\r
211         for (Option<T> par : getArguments()) {\r
212             if (par.getName().equalsIgnoreCase(name)) {\r
213                 return par;\r
214             }\r
215         }\r
216         return null;\r
217     }\r
218 \r
219     /**\r
220      * Removes the argument {@link Argument} if found.\r
221      * \r
222      * @param name\r
223      *            of the argument\r
224      * @return true if argument was removed, false otherwise\r
225      */\r
226     @SuppressWarnings("unchecked")\r
227     // Just use raw type in instanceof this is safe\r
228     public boolean removeArgument(String name) {\r
229         Option<T> par = getArgument(name);\r
230         if (par != null) {\r
231             if (par instanceof Parameter) {\r
232                 parameters.remove(par);\r
233                 return true;\r
234             } else {\r
235                 this.options.remove(par);\r
236                 return true;\r
237             }\r
238         }\r
239         return false;\r
240     }\r
241 \r
242     /**\r
243      * Returns the argument by option name, NULL if the argument is not found\r
244      * \r
245      * @param optionName\r
246      *            - the name of the option\r
247      * @return Option\r
248      */\r
249     public Option<T> getArgumentByOptionName(String optionName) {\r
250         for (Option<T> opt : getArguments()) {\r
251             for (String val : opt.getOptionNames()) {\r
252                 if (val.equalsIgnoreCase(optionName)) {\r
253                     return opt;\r
254                 }\r
255             }\r
256         }\r
257 \r
258         return null;\r
259     }\r
260 \r
261     /**\r
262      * Removes the argument\r
263      * \r
264      * @param optionName\r
265      * @return true if argument with optionName exists and was removed, false\r
266      *         otherwise\r
267      */\r
268     @SuppressWarnings("unchecked")\r
269     // Just use raw type in instanceof this is safe\r
270     public boolean removeArgumentByOptionName(String optionName) {\r
271         Option<T> par = getArgumentByOptionName(optionName);\r
272         if (par != null) {\r
273             if (par instanceof Parameter) {\r
274                 this.parameters.remove(par);\r
275                 return true;\r
276             } else {\r
277                 this.options.remove(par);\r
278                 return true;\r
279             }\r
280         }\r
281         return false;\r
282     }\r
283 \r
284     /**\r
285      * Validate the arguments\r
286      * \r
287      * @throws ValidationException\r
288      *             if any of the arguments found invalid which is when\r
289      *             <dl>\r
290      *             <li>Parameter value outside {@link ValueConstrain} boundary</li>\r
291      *             <li>Parameter name is not listed in possible values</li>\r
292      *             </dl>\r
293      */\r
294     public void validate() throws ValidationException {\r
295         for (Option<?> option : getArguments()) {\r
296             option.validate();\r
297         }\r
298     }\r
299 }\r