04c956167b417cb58a2fadbf15c51c8327c158d9
[jalview.git] / src / jalview / ws / rest / RestClient.java
1 /**
2  * 
3  */
4 package jalview.ws.rest;
5
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.util.Hashtable;
9 import java.util.Vector;
10
11 import javax.swing.JMenu;
12 import javax.swing.JMenuItem;
13 import javax.swing.JOptionPane;
14 import javax.swing.event.MenuEvent;
15 import javax.swing.event.MenuListener;
16
17 import com.sun.org.apache.bcel.internal.generic.ISHL;
18
19 import jalview.datamodel.AlignmentView;
20 import jalview.datamodel.SequenceGroup;
21 import jalview.gui.AlignFrame;
22 import jalview.gui.AlignViewport;
23 import jalview.gui.AlignmentPanel;
24 import jalview.gui.Desktop;
25 import jalview.gui.WebserviceInfo;
26 import jalview.io.packed.DataProvider.JvDataType;
27 import jalview.ws.WSClient;
28 import jalview.ws.WSClientI;
29 import jalview.ws.WSMenuEntryProviderI;
30
31 /**
32  * @author JimP
33  * 
34  */
35 public class RestClient extends WSClient implements WSClientI,
36         WSMenuEntryProviderI
37 {
38   RestServiceDescription service;
39
40   public RestClient(RestServiceDescription rsd)
41   {
42     service = rsd;
43   }
44
45   /**
46    * parent alignframe for this job
47    */
48   AlignFrame af;
49
50   /**
51    * alignment view which provides data for job.
52    */
53   AlignViewport av;
54
55   /**
56    * get the alignFrame for the associated input data if it exists.
57    * 
58    * @return
59    */
60   protected AlignFrame recoverAlignFrameForView()
61   {
62     return jalview.gui.Desktop.getAlignFrameFor(av);
63   }
64
65   public RestClient(RestServiceDescription service2, AlignFrame alignFrame)
66   {
67     service = service2;
68     af = alignFrame;
69     av = alignFrame.getViewport();
70     constructJob();
71   }
72
73   public void setWebserviceInfo(boolean headless)
74   {
75     WebServiceJobTitle = service.details.Action + " using "
76             + service.details.Name;
77     WebServiceName = service.details.Name;
78     WebServiceReference = "No reference - go to url for more info";
79     if (service.details.description != null)
80     {
81       WebServiceReference = service.details.description;
82     }
83     if (!headless)
84     {
85       wsInfo = new WebserviceInfo(WebServiceJobTitle, WebServiceName + "\n"
86               + WebServiceReference);
87       wsInfo.setRenderAsHtml(true);
88     }
89
90   }
91
92   @Override
93   public boolean isCancellable()
94   {
95     // TODO define process for cancelling rsbws jobs
96     return false;
97   }
98
99   @Override
100   public boolean canMergeResults()
101   {
102     // TODO process service definition to identify if the results might be
103     // mergeable
104     // TODO: change comparison for annotation merge
105     return false;
106   }
107
108   @Override
109   public void cancelJob()
110   {
111     System.err.println("Cannot cancel this job type: " + service);
112   }
113
114   @Override
115   public void attachWSMenuEntry(final JMenu wsmenu,
116           final AlignFrame alignFrame)
117   {
118     JMenuItem submit = new JMenuItem(service.details.Name);
119     submit.setToolTipText(service.details.Action+" using "+service.details.Name);
120     submit.addActionListener(new ActionListener()
121     {
122
123       @Override
124       public void actionPerformed(ActionEvent e)
125       {
126         new RestClient(service, alignFrame);
127       }
128
129     });
130     wsmenu.add(submit);
131     // TODO: menu listener should enable/disable entry depending upon selection
132     // state of the alignment
133     wsmenu.addMenuListener(new MenuListener()
134     {
135
136       @Override
137       public void menuSelected(MenuEvent e)
138       {
139         // TODO Auto-generated method stub
140
141       }
142
143       @Override
144       public void menuDeselected(MenuEvent e)
145       {
146         // TODO Auto-generated method stub
147
148       }
149
150       @Override
151       public void menuCanceled(MenuEvent e)
152       {
153         // TODO Auto-generated method stub
154
155       }
156
157     });
158
159   }
160
161   /**
162    * record of initial undoredo hash for the alignFrame providing data for this
163    * job.
164    */
165   long[] undoredo = null;
166
167   /**
168    * Compare the original input data to the data currently presented to the
169    * user. // LOGIC: compare undo/redo - if same, merge regardless (coping with
170    * any changes in hidden columns as normal) // if different undo/redo then
171    * compare region that was submitted // if same, then merge as before, if
172    * different then prompt user to open a new window.
173    * 
174    * @return
175    */
176   protected boolean isAlignmentModified()
177   {
178     if (undoredo == null)
179     {
180       return true;
181     }
182     if (av.isUndoRedoHashModified(undoredo))
183     {
184
185     }
186     return false;
187
188   }
189
190   /**
191    * TODO: combine to form a dataset+alignment+annotation context
192    */
193   AlignmentView _input;
194
195   /**
196    * input data context
197    */
198   jalview.io.packed.JalviewDataset jds;
199
200   protected void constructJob()
201   {
202     service.setInvolvesFlags();
203     
204     // record all aspects of alignment view so we can merge back or recreate
205     // later
206     undoredo = av.getUndoRedoHash();
207     /**
208      * delete ? Vector sgs = av.getAlignment().getGroups(); if (sgs!=null) {
209      * _sgs = new SequenceGroup[sgs.size()]; sgs.copyInto(_sgs); } else { _sgs =
210      * new SequenceGroup[0]; }
211      */
212     boolean selExists = (av.getSelectionGroup() != null)
213             && (av.getSelectionGroup().getSize() > 1);
214     // TODO: revise to full focus+context+dataset input data staging model
215     if (selExists)
216     {
217       if (service.partitiondata)
218       {
219         if (av.getAlignment().getGroups()!=null && av.getAlignment().getGroups().size() > 0)
220         {
221           // intersect groups with selected region
222           _input = new AlignmentView(av.getAlignment(), 
223                   av.getColumnSelection(), 
224                   av.getSelectionGroup(), 
225                   av.hasHiddenColumns(), 
226                   true, 
227                   true);
228         }
229         else
230         {
231           // use selected region to partition alignment
232           _input = new AlignmentView(av.getAlignment(), 
233                   av.getColumnSelection(), 
234                   av.getSelectionGroup(), 
235                   av.hasHiddenColumns(), 
236                   false, 
237                   true);
238         }
239         // TODO: verify that some kind of partition can be constructed from input
240       }
241       else
242       {
243         // just take selected region intersection
244         _input = new AlignmentView(av.getAlignment(), 
245                 av.getColumnSelection(), 
246                 av.getSelectionGroup(), 
247                 av.hasHiddenColumns(), 
248                 true, 
249                 true);
250       }
251     } else {
252       // standard alignment view without selection present
253       _input = new AlignmentView(av.getAlignment(), 
254               av.getColumnSelection(), 
255               null, 
256               av.hasHiddenColumns(), 
257               false, 
258               true);
259     }
260     
261     RestJobThread jobsthread = new RestJobThread(this);
262     
263     if (jobsthread.isValid())
264     {
265       setWebserviceInfo(false);
266       wsInfo.setthisService(this);
267       jobsthread.setWebServiceInfo(wsInfo);
268       jobsthread.start();
269     }
270     else
271     {
272       // TODO: try to tell the user why the job couldn't be started.
273       JOptionPane.showMessageDialog(Desktop.desktop,
274               "Unable to start web service analysis",
275               "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
276     }
277   }
278
279   public static RestClient makeShmmrRestClient()
280   {
281     String action = "Analyse", description = "Sequence Harmony and Multi-Relief", name = "SHMR";
282     Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
283     jalview.ws.rest.params.JobConstant toolp;
284     //toolp = new jalview.ws.rest.JobConstant("tool","jalview");
285     //iparams.put(toolp.token, toolp);
286     toolp = new jalview.ws.rest.params.JobConstant("mbjob[method]","shmr");
287     iparams.put(toolp.token, toolp);
288     toolp = new jalview.ws.rest.params.JobConstant("mbjob[description]","step 1");
289     iparams.put(toolp.token, toolp);
290     toolp = new jalview.ws.rest.params.JobConstant("start_search","1");
291     iparams.put(toolp.token, toolp);
292     toolp = new jalview.ws.rest.params.JobConstant("blast","0");
293     iparams.put(toolp.token, toolp);
294     
295     jalview.ws.rest.params.Alignment aliinput = new jalview.ws.rest.params.Alignment();
296     aliinput.token = "ali_file";
297     aliinput.writeAsFile=true;
298     iparams.put("ali_file", aliinput);
299     jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
300     iparams.put("groups", sgroups);
301     sgroups.token = "groups";
302     sgroups.sep = " ";
303     RestServiceDescription shmrService = new RestServiceDescription(
304             action,
305             description,
306             name,
307             "http://www.ibi.vu.nl/programs/shmrwww/index.php?tool=jalview",// ?tool=jalview&mbjob[method]=shmr&mbjob[description]=step1",
308             "?tool=jalview", iparams, true, false, '-');
309     // a priori knowledge of the data returned from the service
310     shmrService.addResultDatatype(JvDataType.ANNOTATION);
311     return new RestClient(shmrService);
312   }
313
314   public AlignmentPanel recoverAlignPanelForView()
315   {
316     AlignmentPanel[] aps = Desktop.getAlignmentPanels(av.getSequenceSetId());
317     for (AlignmentPanel alp:aps)
318     {
319       if (alp.av == av)
320       {
321         return alp;
322       }
323     }
324     return null;
325   }
326
327   public boolean isShowResultsInNewView()
328   {
329     // TODO make this a property of the service
330     return true;
331   }
332
333 }