Better treatment of error states and cancellability in wsclient.
[jalview.git] / src / jalview / ws / MsaWSClient.java
1 package jalview.ws;\r
2 \r
3 import org.apache.axis.client.*;\r
4 import javax.xml.namespace.QName;\r
5 import java.util.*;\r
6 import jalview.datamodel.*;\r
7 import jalview.gui.*;\r
8 import javax.swing.*;\r
9 import java.util.*;\r
10 import java.awt.*;\r
11 import jalview.analysis.AlignSeq;\r
12 import ext.vamsas.*;\r
13 import vamsas.objects.*;\r
14 \r
15 public class MsaWSClient\r
16 {\r
17   int jobsRunning = 0;\r
18   ext.vamsas.MuscleWS server;\r
19   WebserviceInfo wsInfo;\r
20   /**\r
21    * MsaWSClient\r
22    *\r
23    * @param msa SequenceI[]\r
24    */\r
25   public MsaWSClient(SequenceI[] msa)\r
26   {\r
27     wsInfo = new jalview.gui.WebserviceInfo("Muscle Alignment job",\r
28                                 "Edgar, Robert C. (2004), MUSCLE: multiple sequence alignment with high accuracy and high throughput, Nucleic Acids Research 32(5), 1792-97.");\r
29 \r
30 \r
31     wsInfo.setProgressText("Job details\n");\r
32 \r
33 \r
34     MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default\r
35     try {\r
36       this.server = (MuscleWS) loc.getMuscleWS(); // JBPNote will be set from properties\r
37     }\r
38     catch (Exception ex) {\r
39       wsInfo.setProgressText("Serious! MuscleWS Service location failed\nfor URL :"\r
40                      +loc.getMuscleWSAddress()+"\n"+ex.getMessage());\r
41       ex.printStackTrace();\r
42     }\r
43 \r
44     MsaWSThread musclethread = new MsaWSThread(msa);\r
45     wsInfo.setthisService(musclethread);\r
46     musclethread.start();\r
47   }\r
48 \r
49 \r
50   protected class MsaWSThread extends Thread implements WSClientI\r
51   {\r
52     String ServiceName = "MuscleWS";\r
53     public boolean isCancellable()\r
54     {\r
55       return true;\r
56     }\r
57 \r
58     String OutputHeader;\r
59     vamsas.objects.simple.MsaResult result = null;\r
60     vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.\r
61         SequenceSet();\r
62     String jobId;\r
63     int allowedServerExceptions = 3; // thread dies if too many exceptions.\r
64     MsaWSThread(SequenceI[] msa)\r
65     {\r
66       OutputHeader = wsInfo.getProgressText();\r
67       vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple.\r
68           Sequence[msa.length];\r
69       for (int i = 0; i < msa.length; i++)\r
70       {\r
71         seqarray[i] = new vamsas.objects.simple.Sequence();\r
72         seqarray[i].setId(msa[i].getName());\r
73         seqarray[i].setSeq(AlignSeq.extractGaps("-. ", msa[i].getSequence()));\r
74       }\r
75       this.seqs = new vamsas.objects.simple.SequenceSet();\r
76       this.seqs.setSeqs(seqarray);\r
77     }\r
78 \r
79     boolean jobComplete = false;\r
80 \r
81     public void cancelJob() {\r
82       if (!jobComplete) {\r
83         String cancelledMessage="";\r
84         try {\r
85           vamsas.objects.simple.WsJobId cancelledJob = server.cancel(jobId);\r
86           if (cancelledJob.getStatus() == 2)\r
87           {\r
88             // CANCELLED_JOB\r
89             cancelledMessage = "Job cancelled.";\r
90             wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK);\r
91             jobComplete = true;\r
92             jobsRunning--;\r
93             result = null;\r
94           }\r
95           else\r
96           if (cancelledJob.getStatus() == 3)\r
97           {\r
98             // VALID UNSTOPPABLE JOB\r
99             cancelledMessage +=\r
100                 "Server cannot cancel this job. just close the window.\n";\r
101           }\r
102           if (cancelledJob.getJobId() != null)\r
103             cancelledMessage += "[" + cancelledJob.getJobId() + "]";\r
104           cancelledMessage +="\n";\r
105         } catch (Exception exc) {\r
106           cancelledMessage +="\nProblems cancelling the job : Exception received...\n"+exc+"\n";\r
107           exc.printStackTrace();\r
108         }\r
109         wsInfo.setProgressText(OutputHeader + cancelledMessage+"\n");\r
110       }\r
111     }\r
112 \r
113     public void run()\r
114     {\r
115 \r
116       StartJob();\r
117 \r
118       while (!jobComplete && (allowedServerExceptions > 0))\r
119       {\r
120         try\r
121         {\r
122           result = server.getResult(jobId);\r
123 \r
124          if( result.isRunning() )\r
125            wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);\r
126          else if( result.isQueued() )\r
127            wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);\r
128 \r
129           if (result.isFinished())\r
130           {\r
131             parseResult();\r
132             jobComplete = true;\r
133             jobsRunning--;\r
134           }\r
135           else\r
136           {\r
137             wsInfo.setProgressText(OutputHeader + "\n" + result.getStatus());\r
138             if (! (result.isJobFailed() || result.isServerError()))\r
139             {\r
140               Thread.sleep(5000);\r
141               //  System.out.println("I'm alive "+seqid+" "+jobid);\r
142             }\r
143           }\r
144         }\r
145         catch (Exception ex)\r
146         {\r
147           allowedServerExceptions--;\r
148           wsInfo.appendProgressText("\n"+ServiceName+" Server exception!\n" + ex.getMessage());\r
149           ex.printStackTrace();\r
150         }\r
151       }\r
152 \r
153       if (! (result!=null && (result.isJobFailed() || result.isServerError())))\r
154         wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
155       else\r
156         wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
157     }\r
158 \r
159     void StartJob()\r
160     {\r
161       try\r
162       {\r
163         vamsas.objects.simple.WsJobId jobsubmit = server.align(seqs);\r
164         if (jobsubmit.getStatus()==1) {\r
165           System.out.println(jobId=jobsubmit.getJobId());\r
166         } else {\r
167           throw new Exception(jobsubmit.getJobId());\r
168         }\r
169       }\r
170       catch (Exception e)\r
171       {\r
172         System.out.println(ServiceName + " Client: Failed to submit the prediction\n" +\r
173                            e.toString() + "\n");\r
174         e.printStackTrace();\r
175       }\r
176     }\r
177 \r
178     private void addFloatAnnotations(Alignment al, int[] gapmap, Vector values, String Symname, String Visname, float min, float max, int winLength) {\r
179 \r
180       Annotation[] annotations = new Annotation[al.getWidth()];\r
181       for (int j = 0; j < values.size(); j++)\r
182       {\r
183         float value = Float.parseFloat(values.get(j).toString());\r
184         annotations[gapmap[j]] = new Annotation("", value+"",' ',value);\r
185       }\r
186       al.addAnnotation(new AlignmentAnnotation(Symname, Visname, annotations, min, max, winLength));\r
187     }\r
188     private jalview.datamodel.Sequence[] getVamsasAlignment(vamsas.objects.simple.Alignment valign) {\r
189       vamsas.objects.simple.Sequence[] seqs = valign.getSeqs().getSeqs();\r
190       jalview.datamodel.Sequence[] msa = new jalview.datamodel.Sequence[seqs.length];\r
191       for (int i=0, j=seqs.length; i<j;i++)\r
192         msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i].getSeq());\r
193       return msa;\r
194     }\r
195     void parseResult()\r
196     {\r
197       SequenceI[] seqs=null;\r
198       try {\r
199         // OutputHeader = output.getText();\r
200         if (result.isFailed()) {\r
201           OutputHeader +="Job failed.\n";\r
202         }\r
203         if (result.getStatus()!=null) {\r
204           OutputHeader += "\n"+result.getStatus();\r
205         }\r
206         if (result.getMsa()!=null) {\r
207           OutputHeader += "\nAlignment Object Method Notes\n";\r
208           String lines[] = result.getMsa().getMethod();\r
209           for (int line=0;line<lines.length; line++)\r
210             OutputHeader+=lines[line]+"\n";\r
211 \r
212           // JBPNote The returned files from a webservice could be hidden behind icons in the monitor window that, when clicked, pop up their corresponding data\r
213           seqs = getVamsasAlignment(result.getMsa());\r
214         }\r
215 \r
216         wsInfo.setProgressText(OutputHeader);\r
217         if (seqs!=null) {\r
218           Alignment al;\r
219           al = new Alignment(seqs);\r
220 \r
221           // TODO: JBPNote Should also rename the query sequence sometime...\r
222           AlignFrame af = new AlignFrame(al);\r
223           Desktop.addInternalFrame(af,\r
224                                    ServiceName + " Alignment",\r
225                                    AlignFrame.NEW_WINDOW_WIDTH,\r
226                                    AlignFrame.NEW_WINDOW_HEIGHT);\r
227         }\r
228       }catch(Exception ex){ex.printStackTrace();}\r
229 \r
230     }\r
231 \r
232   }\r
233   }\r
234 \r