62e2d21f4e53bad9b4b6e89377c73eef604c8d9c
[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     return getClientFactory().getCurrentSessions();
65   }
66   /**
67    * initialise, possibly with e valid session url
68    * @param sess
69    * @return
70    */
71   private boolean initClientSession(String sess) {
72     try {
73       // Only need to tell the library what the application is here
74       app = new ClientHandle("jalview.bin.Jalview", jalview.bin.Cache.getProperty("VERSION"));
75       uk.ac.vamsas.client.IClientFactory clientfactory = getClientFactory();
76       if (sess==null)
77       {
78         vclient = clientfactory.getIClient(app);
79       }
80       else
81       {
82         vclient = clientfactory.getIClient(app,sess);
83       }
84       
85       user = vclient.getUserHandle();
86       
87     } catch (NoDefaultSessionException e)
88     {
89       return false;
90     }
91     catch (Exception e)
92     {
93       jalview.bin.Cache.log.error("Couldn't instantiate vamsas client !",e);
94       return false;
95     }
96     return true;
97   }
98   /**
99    * 
100    * @return true if we are registered in a vamsas session
101    */
102   public boolean inSession()
103   {
104     return (vclient!=null);
105   }
106   /**
107    * called to connect to session
108    * inits handlers, does an initial document update.
109    */
110   public void initial_update()
111   {
112     if (!inSession())
113     {
114       throw new Error("Impementation error! Vamsas Operations when client not initialised and connected.");
115     }
116     addDocumentUpdateHandler();
117     startSession();
118     Cache.log.debug("Jalview loading the Vamsas Session for the first time.");
119     dealWithDocumentUpdate();
120     Cache.log.debug("... finished update for the first time.");
121   }
122   /**
123    * Update all windows after a vamsas datamodel change.
124    * this could go on the desktop object!
125    * 
126    */
127   protected void updateJalviewGui() 
128   {
129     JInternalFrame[] frames = jdesktop.getAllFrames();
130
131     if (frames == null)
132     {
133       return;
134     }
135
136     try
137     {
138       //REVERSE ORDER
139       for (int i = frames.length - 1; i > -1; i--)
140       {
141         if (frames[i] instanceof AlignFrame)
142         {
143           AlignFrame af = (AlignFrame) frames[i];
144           af.alignPanel.alignmentChanged();
145         }
146       }
147     }
148     catch (Exception e)
149     {
150       Cache.log.warn(
151           "Exception whilst refreshing jalview windows after a vamsas document update.",
152           e);
153     }
154   }
155   public void push_update()
156   {
157     Cache.log.info("Jalview updating to the Vamsas Session.");
158     dealWithDocumentUpdate();
159     /*
160     IClientDocument cdoc=null;
161     try
162     {
163       cdoc = vclient.getClientDocument();
164     }
165     catch (Exception e)
166     {
167       Cache.log.error("Failed to get client document for update.");
168       // RAISE A WARNING DIALOG
169       disableGui(false);
170       return;
171     }
172     updateVamsasDocument(cdoc);
173     updateJalviewGui();
174     cdoc.setVamsasRoots(cdoc.getVamsasRoots()); // propagate update flags back
175     vclient.updateDocument(cdoc);
176     */
177     Cache.log.info("Jalview finished updating to the Vamsas Session.");
178   }
179
180   public void end_session()
181   {
182     if (!inSession())
183       throw new Error("Jalview not connected to Vamsas session.");
184     Cache.log.info("Jalview disconnecting from the Vamsas Session.");
185     try
186     {
187       if (joinedSession) {
188         vclient.finalizeClient();
189         Cache.log.info("Jalview has left the session.");
190       } else {
191         Cache.log.warn("JV Client leaving a session that's its not joined yet.");
192       }
193       joinedSession=false;
194       vclient = null;
195       app=null; user = null;
196       jv2vobj = null;
197       vobj2jv = null;
198     }
199     catch (Exception e)
200     {
201       Cache.log.error("Vamsas Session finalization threw exceptions!",e);
202     }
203   }
204
205   public void updateJalview(IClientDocument cdoc)
206   {
207     Cache.log.debug("Jalview updating from sesion document ..");
208     ensureJvVamsas();
209     VamsasAppDatastore vds = new VamsasAppDatastore(cdoc, vobj2jv, jv2vobj,
210                                               baseProvEntry());
211     vds.updateToJalview();
212     Cache.log.debug(".. finished updating from sesion document.");
213     
214   }
215   private void ensureJvVamsas()
216   {
217     if (jv2vobj == null)
218     {
219       jv2vobj = new IdentityHashMap();
220       vobj2jv = new Hashtable();
221     }
222   }
223
224   /**
225    * jalview object binding to VorbaIds
226    */
227   IdentityHashMap jv2vobj = null;
228   Hashtable vobj2jv = null;
229   public void updateVamsasDocument(IClientDocument doc)
230   {
231     ensureJvVamsas();
232     VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
233                                               baseProvEntry());
234     // wander through frames
235     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
236
237     if (frames == null)
238     {
239       return;
240     }
241
242     try
243     {
244       //REVERSE ORDER
245       for (int i = frames.length - 1; i > -1; i--)
246       {
247         if (frames[i] instanceof AlignFrame)
248         {
249           AlignFrame af = (AlignFrame) frames[i];
250
251           // update alignment and root from frame.
252           vds.storeVAMSAS(af.getViewport(), af.getTitle());
253         }
254       }
255     }
256     catch (Exception e)
257     {
258       Cache.log.error("Vamsas Document store exception", e);
259     }
260   }
261
262   private Entry baseProvEntry()
263   {
264     uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();
265     pentry.setUser(user.getFullName());
266     pentry.setApp(app.getClientUrn());
267     pentry.setDate(new org.exolab.castor.types.Date(new java.util.Date()));
268     pentry.setAction("created");
269     return pentry;
270   }
271   protected void dealWithDocumentUpdate()
272   {
273     // called by update handler for document update.
274     Cache.log.debug("Updating jalview from changed vamsas document.");
275     disableGui(true);
276     try {
277       IClientDocument cdoc = vclient.getClientDocument();
278       updateJalview(cdoc);
279       // cdoc.setVamsasRoots(cdoc.getVamsasRoots());
280       vclient.updateDocument(cdoc);
281       cdoc=null;
282     } catch (Exception ee) {
283       System.err.println("Exception whilst updating :");
284       ee.printStackTrace(System.err);
285     }
286     Cache.log.debug("Finished updating from document change.");
287     disableGui(false);
288   }
289   private void addDocumentUpdateHandler()
290   {
291     final VamsasApplication client = this;
292     vclient.addDocumentUpdateHandler(new PropertyChangeListener() {
293       public void propertyChange(PropertyChangeEvent evt)
294       {
295         Cache.log.debug("Dealing with document update event.");
296         client.dealWithDocumentUpdate();
297         Cache.log.debug("finished dealing with event.");
298       }
299     });
300     Cache.log.debug("Added Jalview handler for vamsas document updates.");
301   }
302   public void disableGui(boolean b)
303   {
304     Desktop.instance.setVamsasUpdate(b);
305   }
306   private boolean joinedSession=false;
307   private void startSession()
308   {
309     if (inSession())
310     {
311       try {
312         vclient.joinSession();
313         joinedSession=true;
314       }
315       catch (Exception e)
316       {
317         // Complain to GUI
318         Cache.log.error("Failed to join vamsas session.",e);
319         vclient=null;
320       }
321     }
322   }
323 }