Web service stubs are regenerated to incorporate new the methods. Excveption handling...
[jabaws.git] / webservices / compbio / ws / client / AAConClient.java
1 /* Copyright (c) 2010 Peter Troshin\r
2  *  \r
3  *  Amino Acid Conservation Web Service client @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.ws.client;\r
20 \r
21 import static compbio.ws.client.Constraints.inputkey;\r
22 import static compbio.ws.client.Constraints.limitList;\r
23 import static compbio.ws.client.Constraints.outputkey;\r
24 import static compbio.ws.client.Constraints.paramFile;\r
25 import static compbio.ws.client.Constraints.paramList;\r
26 import static compbio.ws.client.Constraints.presetList;\r
27 import static compbio.ws.client.Constraints.presetkey;\r
28 import static compbio.ws.client.Constraints.pseparator;\r
29 \r
30 import java.io.Closeable;\r
31 import java.io.File;\r
32 import java.io.IOException;\r
33 import java.io.OutputStream;\r
34 import java.net.MalformedURLException;\r
35 import java.net.URL;\r
36 import java.util.List;\r
37 import java.util.logging.Level;\r
38 import java.util.logging.Logger;\r
39 \r
40 import javax.xml.namespace.QName;\r
41 import javax.xml.ws.Service;\r
42 import javax.xml.ws.WebServiceException;\r
43 \r
44 import compbio.data.msa.SequenceAnnotation;\r
45 import compbio.data.sequence.FastaSequence;\r
46 import compbio.data.sequence.ScoreManager;\r
47 import compbio.data.sequence.SequenceUtil;\r
48 import compbio.data.sequence.UnknownFileFormatException;\r
49 import compbio.metadata.JobSubmissionException;\r
50 import compbio.metadata.Option;\r
51 import compbio.metadata.Preset;\r
52 import compbio.metadata.ResultNotAvailableException;\r
53 import compbio.metadata.WrongParameterException;\r
54 import compbio.ws.server.AAConWS;\r
55 \r
56 /**\r
57  * A command line client for AACon web service\r
58  * \r
59  * @author pvtroshin\r
60  * @version 1.0\r
61  */\r
62 public class AAConClient {\r
63 \r
64         /*\r
65          * Use java.util.Logger instead of log4j logger to reduce the size of the\r
66          * client package\r
67          */\r
68         private static final Logger log = Logger.getLogger(AAConClient.class\r
69                         .getCanonicalName());\r
70 \r
71         /**\r
72          * The fully qualified web service namespace\r
73          */\r
74         static final String QUALIFIED_SERVICE_NAME = "http://msa.data.compbio/01/12/2010/";\r
75 \r
76         /**\r
77          * Web service host\r
78          */\r
79         static final String hostname = "http://www.compbio.dundee.ac.uk/aacon";\r
80         // static final String hostname = "http://localhost:8080/jabaws";\r
81 \r
82         /**\r
83          * Web service name\r
84          */\r
85         static final String serviceName = "AAConWS";\r
86 \r
87         /**\r
88          * Connects to the service and do the job as requested, if something goes\r
89          * wrong reports or/and prints usage help.\r
90          * \r
91          * @param cmd\r
92          *            command line options\r
93          * @throws IOException\r
94          *             if the system cannot read/write from/into the file system\r
95          */\r
96         @SuppressWarnings("unchecked")\r
97         AAConClient(String[] cmd) throws IOException {\r
98 \r
99                 File inputFile = IOHelper.getFile(cmd, inputkey, true);\r
100                 File outFile = IOHelper.getFile(cmd, outputkey, false);\r
101                 File parametersFile = IOHelper.getFile(cmd, paramFile, true);\r
102                 String presetName = CmdHelper.getPresetName(cmd);\r
103 \r
104                 SequenceAnnotation<AAConWS> msaws = connect();\r
105                 Preset<AAConWS> preset = null;\r
106                 if (presetName != null) {\r
107                         preset = MetadataHelper.getPreset(msaws, presetName);\r
108                 }\r
109                 List<Option<AAConWS>> customOptions = null;\r
110                 if (parametersFile != null) {\r
111                         List<String> prms = IOHelper.loadParameters(parametersFile);\r
112                         customOptions = MetadataHelper.processParameters(prms,\r
113                                         msaws.getRunnerOptions());\r
114                 }\r
115                 ScoreManager result = null;\r
116                 if (inputFile != null) {\r
117                         System.out.println("Calculating conservation...");\r
118                         result = analize(inputFile, msaws, preset, customOptions);\r
119                         OutputStream outStream = null;\r
120                         if (outFile != null) {\r
121                                 outStream = IOHelper.getOutStream(outFile);\r
122                         } else {\r
123                                 // this stream is going to be closed later which is fine as\r
124                                 // std.out will not be\r
125                                 outStream = System.out;\r
126                         }\r
127                         writeOut(outStream, result);\r
128                         // stream is closed in the method no need to close it here\r
129                 }\r
130 \r
131                 boolean listParameters = CmdHelper.listParameters(cmd);\r
132                 if (listParameters) {\r
133                         System.out.println(MetadataHelper.getParametersList(msaws));\r
134                 }\r
135                 boolean listPreset = CmdHelper.listPresets(cmd);\r
136                 if (listPreset) {\r
137                         System.out.println(MetadataHelper.getPresetList(msaws));\r
138                 }\r
139                 boolean listLimits = CmdHelper.listLimits(cmd);\r
140                 if (listLimits) {\r
141                         System.out.println(MetadataHelper.getLimits(msaws));\r
142                 }\r
143                 log.fine("Disconnecting...");\r
144                 ((Closeable) msaws).close();\r
145                 log.fine("Disconnected successfully!");\r
146         }\r
147 \r
148         /**\r
149          * Outputs AAcon results into the file represented by the outStream\r
150          * \r
151          * @param outStream\r
152          * @param result\r
153          *            the AACon scores to output\r
154          */\r
155         static void writeOut(OutputStream outStream, ScoreManager result) {\r
156                 try {\r
157                         result.writeOut(outStream);\r
158                 } catch (IOException e) {\r
159                         System.err\r
160                                         .println("Problems writing output file! Stack trace is below: ");\r
161                         e.printStackTrace();\r
162                 } finally {\r
163                         if (outStream != null) {\r
164                                 try {\r
165                                         outStream.close();\r
166                                 } catch (IOException ignored) {\r
167                                         // e.printStackTrace();\r
168                                 }\r
169                         }\r
170                 }\r
171         }\r
172 \r
173         /**\r
174          * Connects to a AACon web service by the host and the service name\r
175          * \r
176          * \r
177          * @return {@link AlignmentAnnotation}\r
178          * @throws WebServiceException\r
179          *             if cannot connect to a web service\r
180          */\r
181         public static SequenceAnnotation<AAConWS> connect()\r
182                         throws WebServiceException {\r
183                 URL url = null;\r
184                 log.log(Level.FINE, "Attempting to connect...");\r
185                 try {\r
186                         url = new URL(hostname + "/" + "AAConWS" + "?wsdl");\r
187                 } catch (MalformedURLException e) {\r
188                         e.printStackTrace();\r
189                         // ignore as the host name is already verified\r
190                 }\r
191                 QName qname = new QName(QUALIFIED_SERVICE_NAME, "AAConWS");\r
192                 Service serv = Service.create(url, qname);\r
193                 QName portName = new QName(QUALIFIED_SERVICE_NAME, "AAConWS" + "Port");\r
194 \r
195                 @SuppressWarnings("unchecked")\r
196                 SequenceAnnotation<AAConWS> serviceIF = serv.getPort(portName,\r
197                                 SequenceAnnotation.class);\r
198 \r
199                 log.log(Level.FINE, "Connected successfully!");\r
200                 return serviceIF;\r
201         }\r
202 \r
203         /**\r
204          * Calculate conservation for sequences loaded from the file\r
205          * \r
206          * @param wsproxy\r
207          *            a web service proxy\r
208          * @param file\r
209          *            the file to read the results from\r
210          * @param preset\r
211          *            Preset to use optional\r
212          * @param customOptions\r
213          *            the list of options\r
214          * @return Set<Score> the conservation scores\r
215          * @throws UnknownFileFormatException\r
216          */\r
217         static ScoreManager analize(File file, SequenceAnnotation<AAConWS> wsproxy,\r
218                         Preset<AAConWS> preset, List<Option<AAConWS>> customOptions) {\r
219 \r
220                 List<FastaSequence> fastalist = null;\r
221                 ScoreManager scores = null;\r
222                 try {\r
223                         fastalist = SequenceUtil.openInputStream(file.getAbsolutePath());\r
224 \r
225                         String jobId = null;\r
226                         if (customOptions != null && preset != null) {\r
227                                 System.out\r
228                                                 .println("WARN: Parameters (-f) are defined together with a preset (-r) ignoring preset!");\r
229                         }\r
230                         if (customOptions != null) {\r
231                                 jobId = wsproxy.customAnalize(fastalist, customOptions);\r
232                         } else if (preset != null) {\r
233                                 jobId = wsproxy.presetAnalize(fastalist, preset);\r
234                         } else {\r
235                                 jobId = wsproxy.analize(fastalist);\r
236                         }\r
237                         Thread.sleep(1000);\r
238                         scores = wsproxy.getAnnotation(jobId);\r
239 \r
240                 } catch (IOException e) {\r
241                         System.err\r
242                                         .println("Exception while reading the input file. "\r
243                                                         + "Check that the input file contains a list of fasta formatted sequences! "\r
244                                                         + "Exception details are below:");\r
245                         e.printStackTrace();\r
246                 } catch (JobSubmissionException e) {\r
247                         System.err\r
248                                         .println("Exception while submitting job to a web server. "\r
249                                                         + "Exception details are below:");\r
250                         e.printStackTrace();\r
251                 } catch (ResultNotAvailableException e) {\r
252                         System.err.println("Exception while waiting for results. "\r
253                                         + "Exception details are below:");\r
254                         e.printStackTrace();\r
255                 } catch (InterruptedException ignored) {\r
256                         // ignore and propagate an interruption\r
257                         Thread.currentThread().interrupt();\r
258                 } catch (WrongParameterException e) {\r
259                         System.err\r
260                                         .println("Exception while parsing the web method input parameters. "\r
261                                                         + "Exception details are below:");\r
262                         e.printStackTrace();\r
263                 } catch (UnknownFileFormatException e) {\r
264                         System.err\r
265                                         .println("Exception while attempting to read the input file "\r
266                                                         + "Exception details are below:");\r
267                         System.out.println(e.getMessage());\r
268                         e.printStackTrace();\r
269                 }\r
270                 return scores;\r
271         }\r
272 \r
273         /**\r
274          * Prints AAConClient usage information to standard out\r
275          * \r
276          * @param exitStatus\r
277          */\r
278         static void printUsage(int exitStatus) {\r
279                 System.out.println();\r
280                 System.out.println("Usage: <Class or Jar file name> "\r
281                                 + " ACTION [OPTIONS] ");\r
282                 System.out.println();\r
283                 System.out.println("ACTIONS: ");\r
284                 System.out\r
285                                 .println(inputkey\r
286                                                 + pseparator\r
287                                                 + "<inputFile> - full path to fasta or Clustal formatted alignment file ");\r
288                 System.out.println(paramList\r
289                                 + " - lists parameters supported by web service");\r
290                 System.out.println(presetList\r
291                                 + " - lists presets supported by web service");\r
292                 System.out.println(limitList + " - lists web services limits");\r
293                 System.out\r
294                                 .println("Please note that if input file is specified other actions are ignored");\r
295 \r
296                 System.out.println();\r
297                 System.out.println("OPTIONS (only for use with -i action):");\r
298 \r
299                 System.out.println(presetkey + pseparator\r
300                                 + "<presetName> - name of the preset to use");\r
301                 System.out\r
302                                 .println(outputkey\r
303                                                 + pseparator\r
304                                                 + "<outputFile> - full path to the file where to write the result");\r
305                 System.out\r
306                                 .println("-f=<parameterInputFile> - the name of the file with the list of parameters to use.");\r
307                 System.out\r
308                                 .println("Please note that -r and -f options cannot be used together. "\r
309                                                 + "Conservation is calculated with either a preset or "\r
310                                                 + "the parameters from the file, but not both!");\r
311 \r
312                 System.exit(exitStatus);\r
313         }\r
314 \r
315         /**\r
316          * Starts command line client, if no parameters are supplied prints help.\r
317          * \r
318          * @param args\r
319          *            Usage: <Class or Jar file name> ACTION [OPTIONS]\r
320          * \r
321          *            -i=<inputFile> - full path to fasta or Clustal formatted\r
322          *            alignment file\r
323          * \r
324          *            -parameters - lists parameters supported by web service\r
325          * \r
326          *            -presets - lists presets supported by web service\r
327          * \r
328          *            -limits - lists web services limits. Please note that if input\r
329          *            file is specified other actions are ignored\r
330          * \r
331          *            OPTIONS: (only for use with -i action):\r
332          * \r
333          *            -r=<presetName> - name of the preset to use\r
334          * \r
335          *            -o=<outputFile> - full path to the file where to write results\r
336          *            -f=<parameterInputFile> - the name of the file with the list\r
337          *            of parameters to use. Please note that -r and -f options\r
338          *            cannot be used together. Conservation is calculated with\r
339          *            either a preset or parameters from the file, but not both!\r
340          * \r
341          */\r
342         public static void main(String[] args) {\r
343 \r
344                 if (args == null) {\r
345                         printUsage(1);\r
346                 }\r
347                 if (args.length < 1) {\r
348                         System.out.println("No options is specified! ");\r
349                         printUsage(1);\r
350                 }\r
351 \r
352                 try {\r
353                         new AAConClient(args);\r
354                 } catch (IOException e) {\r
355                         log.log(Level.SEVERE, "IOException in client! " + e.getMessage(),\r
356                                         e.getCause());\r
357                         System.err.println("Cannot write output file! Stack trace: ");\r
358                         e.printStackTrace();\r
359                 }\r
360         }\r
361 }\r