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