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