use of proper vamsas client API by Jalview
[jalview.git] / src / jalview / gui / VamsasApplication.java
1 /**
2  *
3  */
4 package jalview.gui;
5
6 import java.beans.PropertyChangeEvent;
7 import java.beans.PropertyChangeListener;
8 import java.io.File;
9 import java.io.IOException;
10 import java.io.OutputStreamWriter;
11 import java.io.PrintWriter;
12 import java.util.Hashtable;
13 import java.util.IdentityHashMap;
14 import java.util.Vector;
15 import java.util.jar.JarOutputStream;
16
17 import javax.swing.JInternalFrame;
18
19 import jalview.bin.Cache;
20 import jalview.io.VamsasAppDatastore;
21 import jalview.io.VamsasDatastore;
22
23 import uk.ac.vamsas.client.*;
24 import uk.ac.vamsas.*;
25 import uk.ac.vamsas.objects.*;
26 import uk.ac.vamsas.objects.core.Entry;
27 /**
28  * @author jimp
29  *
30  */
31 public class VamsasApplication
32 {
33   IClient vclient=null;
34   ClientHandle app=null;
35   UserHandle user=null;
36   
37   Desktop jdesktop = null; // our jalview desktop reference
38   
39   // Cache.preferences for vamsas client session arena
40   // preferences for check for default session at startup.
41   // user and organisation stuff.
42   public VamsasApplication(Desktop jdesktop,
43                       File sessionPath)
44   {
45     // JBPNote:
46     // we should create a session URI from the sessionPath and pass it to
47     // the clientFactory - but the vamsas api doesn't cope with that yet.
48     this(jdesktop);
49     throw new Error("Sorry - can't start from session file yet."); // make this a warning
50   }
51   private static uk.ac.vamsas.client.IClientFactory getClientFactory() throws IOException {
52     return new uk.ac.vamsas.client.simpleclient.SimpleClientFactory();
53   }
54   public VamsasApplication(Desktop jdesktop)
55   {
56     this.jdesktop = jdesktop; 
57     initClientSession(null);
58   }
59   /**
60    * @throws IOException or other if clientfactory instantiation failed.
61    * @return list of current sessions or null if no session exists.
62    */
63   public static String[] getSessionList() throws Exception {
64     uk.ac.vamsas.client.IClientFactory clientfactory = null;
65     clientfactory = getClientFactory();
66     return clientfactory.getCurrentSessions();
67   }
68   /**
69    * initialise, possibly with e valid session url
70    * @param sess
71    * @return
72    */
73   private boolean initClientSession(String sess) {
74     try {
75       // Only need to tell the library what the application is here
76       app = new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache.getProperty("VERSION"));
77       uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
78       if (sess==null)
79       {
80         vclient = clientfactory.getIClient(app);
81       }
82       else
83       {
84         vclient = clientfactory.getIClient(app,sess);
85       }
86       
87       user = vclient.getUserHandle();
88       
89     } catch (NoDefaultSessionException e)
90     {
91       return false;
92     }
93     catch (Exception e)
94     {
95       jalview.bin.Cache.log.error("Couldn't instantiate vamsas client !",e);
96       return false;
97     }
98     return true;
99   }
100   /**
101    * 
102    * @return true if we are registered in a vamsas session
103    */
104   public boolean inSession()
105   {
106     return (vclient!=null);
107   }
108   /**
109    * called to connect to session
110    * inits handlers, does an initial document update.
111    */
112   public void initial_update()
113   {
114     if (!inSession())
115     {
116       throw new Error("Impementation error! Vamsas Operations when client not initialised and connected.");
117     }
118     this.addDocumentUpdateHandler();
119     this.startSession();
120     Cache.log.info("Jalview loading the Vamsas Session.");
121     // load in the vamsas archive for the first time
122     IClientDocument cdoc=null;
123     try
124     {
125       cdoc = vclient.getClientDocument();
126     }
127     catch (IOException e)
128     {
129       Cache.log.error("Serious: Exception whilst getting vamsas document",e);
130       return;
131     }
132     updateJalview(cdoc);
133     updateJalviewGui();
134     cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags back
135     
136     try{
137       vclient.updateDocument(cdoc);
138     }
139     catch (Exception e)
140     {
141       Cache.log.error("Serious: Exception whilst updating vamsas document.",e);
142       return;
143     }
144     cdoc=null;
145   }
146   /**
147    * Update all windows after a vamsas datamodel change.
148    * this could go on the desktop object!
149    * 
150    */
151   protected void updateJalviewGui() 
152   {
153     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
154
155     if (frames == null)
156     {
157       return;
158     }
159
160     try
161     {
162       //REVERSE ORDER
163       for (int i = frames.length - 1; i > -1; i--)
164       {
165         if (frames[i] instanceof AlignFrame)
166         {
167           AlignFrame af = (AlignFrame) frames[i];
168           af.alignPanel.alignmentChanged();
169         }
170       }
171     }
172     catch (Exception e)
173     {
174       Cache.log.warn(
175           "Exception whilst refreshing jalview windows after a vamsas document update.",
176           e);
177     }
178   }
179   /**
180    * this will close all windows currently in Jalview.
181    *
182
183     protected void closeWindows() {
184      JInternalFrame[] frames = Desktop.desktop.getAllFrames();
185
186         if (frames == null)
187         {
188             return;
189         }
190
191         try
192         {
193             for (int i = frames.length - 1; i > -1; i--) {
194              frames[i].dispose();
195             }
196         } catch (Exception e) {
197          Cache.log.error("Whilst closing windows",e);
198         }
199
200     }
201
202     public void get_update(VamsasArchive doc) {
203      // Close windows - load update.
204      Cache.log.info("Jalview updating from Vamsas Session.");
205     }
206    */
207   public void push_update()
208   {
209     disableGui(true);
210     Cache.log.info("Jalview updating the Vamsas Session.");
211     IClientDocument cdoc=null;
212     try
213     {
214       cdoc = vclient.getClientDocument();
215     }
216     catch (Exception e)
217     {
218       Cache.log.error("Failed to get client document for update.");
219       // RAISE A WARNING DIALOG
220       disableGui(false);
221       return;
222     }
223     updateVamsasDocument(cdoc);
224     updateJalviewGui();
225     cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags back
226     vclient.updateDocument(cdoc);
227     disableGui(false);
228     cdoc = null;
229   }
230
231   public void end_session()
232   {
233     if (!inSession())
234       throw new Error("Jalview not connected to Vamsas session.");
235     Cache.log.info("Jalview disconnecting from the Vamsas Session.");
236     try
237     {
238       if (joinedSession) {
239         vclient.finalizeClient();
240         Cache.log.info("Jalview has left the session.");
241       } else {
242         Cache.log.warn("JV Client leaving a session that's its not joined yet.");
243       }
244       vclient = null;
245       app=null; user = null;
246       jv2vobj = null;
247       vobj2jv = null;
248     }
249     catch (Exception e)
250     {
251       Cache.log.error("Vamsas Session finalization threw exceptions!",e);
252     }
253   }
254
255   public void updateJalview(IClientDocument cdoc)
256   {
257     ensureJvVamsas();
258     VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
259                                               baseProvEntry());
260     vds.updateToJalview();
261   }
262   private void ensureJvVamsas()
263   {
264     if (jv2vobj == null)
265     {
266       jv2vobj = new IdentityHashMap();
267       vobj2jv = new Hashtable();
268     }
269   }
270
271   /**
272    * jalview object binding to VorbaIds
273    */
274   IdentityHashMap jv2vobj = null;
275   Hashtable vobj2jv = null;
276   public void updateVamsasDocument(IClientDocument doc)
277   {
278     ensureJvVamsas();
279     VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
280                                               baseProvEntry());
281     // wander through frames
282     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
283
284     if (frames == null)
285     {
286       return;
287     }
288
289     try
290     {
291       //REVERSE ORDER
292       for (int i = frames.length - 1; i > -1; i--)
293       {
294         if (frames[i] instanceof AlignFrame)
295         {
296           AlignFrame af = (AlignFrame) frames[i];
297
298           // update alignment and root from frame.
299           vds.storeVAMSAS(af.getViewport(), af.getTitle());
300         }
301       }
302     }
303     catch (Exception e)
304     {
305       Cache.log.error("Vamsas Document store exception", e);
306     }
307   }
308
309   private Entry baseProvEntry()
310   {
311     uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
312     pentry.setUser(user.getFullName());
313     pentry.setApp(app.getClientUrn());
314     pentry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));
315     pentry.setAction("created");
316     return pentry;
317   }
318
319   private void addDocumentUpdateHandler()
320   {
321     final IClient vorbaclient = vclient;
322     final VamsasApplication client = this;
323     vorbaclient.addDocumentUpdateHandler(new PropertyChangeListener() {
324       public void propertyChange(PropertyChangeEvent evt)
325       {
326         // update handler for document update.
327         Cache.log.debug("Updating jalview from changed vamsas document.");
328         client.disableGui(true);
329         try {
330           IClientDocument cdoc = vorbaclient.getClientDocument();
331           client.updateJalview(cdoc);
332           // cdoc.setVamsasRoots(cdoc.getVamsasRoots());
333           vorbaclient.updateDocument(cdoc);
334           cdoc=null;
335         } catch (Exception ee) {
336           System.err.println("Exception whilst updating :");
337           ee.printStackTrace(System.err);
338         }
339         Cache.log.debug("Finished updating from document change.");
340         client.disableGui(false);
341       }
342     });
343   }
344   public void disableGui(boolean b)
345   {
346     Desktop.instance.setVamsasUpdate(b);
347   }
348   private boolean joinedSession=false;
349   private void startSession()
350   {
351     if (inSession())
352     {
353       try {
354         vclient.joinSession();
355         joinedSession=true;
356       }
357       catch (Exception e)
358       {
359         // Complain to GUI
360         Cache.log.error("Failed to join vamsas session.",e);
361         vclient=null;
362       }
363     }
364   }
365 }