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