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