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