applied LGPLv3 and source code formatting.
[vamsas.git] / src / uk / ac / vamsas / test / simpleclient / simpleapp / VamsasClient.java
1 /*\r
2  * This file is part of the Vamsas Client version 0.1. \r
3  * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, \r
4  *  Andrew Waterhouse and Dominik Lindner.\r
5  * \r
6  * Earlier versions have also been incorporated into Jalview version 2.4 \r
7  * since 2008, and TOPALi version 2 since 2007.\r
8  * \r
9  * The Vamsas Client is free software: you can redistribute it and/or modify\r
10  * it under the terms of the GNU Lesser General Public License as published by\r
11  * the Free Software Foundation, either version 3 of the License, or\r
12  * (at your option) any later version.\r
13  *  \r
14  * The Vamsas Client is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU Lesser General Public License for more details.\r
18  * \r
19  * You should have received a copy of the GNU Lesser General Public License\r
20  * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.\r
21  */\r
22 package uk.ac.vamsas.test.simpleclient.simpleapp;\r
23 \r
24 import java.io.File;\r
25 import java.io.FileOutputStream;\r
26 import java.io.OutputStreamWriter;\r
27 import java.io.PrintWriter;\r
28 import java.util.Hashtable;\r
29 import java.util.IdentityHashMap;\r
30 import java.util.Vector;\r
31 import java.util.jar.JarOutputStream;\r
32 \r
33 import javax.swing.JInternalFrame;\r
34 \r
35 import uk.ac.vamsas.client.UserHandle;\r
36 import uk.ac.vamsas.client.simpleclient.FileWatcher;\r
37 import uk.ac.vamsas.client.simpleclient.VamsasArchive;\r
38 import uk.ac.vamsas.client.simpleclient.VamsasFile;\r
39 import uk.ac.vamsas.objects.core.Entry;\r
40 import uk.ac.vamsas.objects.core.VamsasDocument;\r
41 import uk.ac.vamsas.test.simpleclient.ArchiveClient;\r
42 import uk.ac.vamsas.test.simpleclient.ClientDoc;\r
43 \r
44 /**\r
45  * @author jimp\r
46  * \r
47  */\r
48 public class VamsasClient extends ArchiveClient {\r
49   org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory\r
50       .getLog(VamsasClient.class);\r
51 \r
52   /**\r
53    * create a new vamsas client session from the archive at sessionPath.\r
54    * \r
55    * @param sessionPath\r
56    */\r
57   public VamsasClient(File sessionPath) {\r
58     super(System.getProperty("user.name"), System.getProperty("host.name"),\r
59         "SimpleVamsasClientApp", "0.1", sessionPath);\r
60   }\r
61 \r
62   /**\r
63    * Called by gui to read anything from the vamsas session into the apps\r
64    * datamodel after it has started up.\r
65    * \r
66    */\r
67   public void initial_update() {\r
68     log.info("Jalview loading the Vamsas Session.");\r
69     // load in the vamsas archive for the first time\r
70     ClientDoc cdoc = this.getUpdateable();\r
71     updateJalview(cdoc);\r
72     // TODO: flush any new VorbaIds to the document : updateVamsasClient may\r
73     // actually generate new Vamsas Document data in the form of vamsas element\r
74     // ids - these should be written back to the document.\r
75     // doUpdate(cdoc); // JBPNote: this should flush new VorbaIds but I've not\r
76     // tested it yet.\r
77     cdoc.closeDoc();\r
78     // then tell app to update its display based on the datamodel changes.\r
79   }\r
80 \r
81   VamsasClientWatcher watcher = null;\r
82 \r
83   /**\r
84    * Called by app when internal datamodel should exported (syncrhonised\r
85    * outwards) to vamsas document\r
86    * \r
87    */\r
88   public void push_update() {\r
89 \r
90     watchForChange = false; // this makes any watch(long) loops return.\r
91     // we should also wait arount for this.WATCH_SLEEP to really make sure the\r
92     // watcher thread has stopped.\r
93     try {\r
94       Thread.sleep(WATCH_SLEEP);\r
95     } catch (Exception e) {\r
96 \r
97     }\r
98     ;\r
99 \r
100     ClientDoc cdoc = getUpdateable();\r
101     updateVamsasDocument(cdoc);\r
102     doUpdate(cdoc);\r
103     cdoc.closeDoc();\r
104     cdoc = null;\r
105     watchForChange = true;\r
106     startWatcher();\r
107   }\r
108 \r
109   public void end_session() {\r
110     watchForChange = false; // this makes any watch(long) loops return.\r
111     // we should also wait arount for this.WATCH_SLEEP to really make sure the\r
112     // watcher thread has stopped.\r
113     try {\r
114       Thread.sleep(WATCH_SLEEP);\r
115     } catch (Exception e) {\r
116 \r
117     }\r
118     ;\r
119 \r
120     // stop any update/watcher thread.\r
121     log.info("VamsasClientApplication disconnecting from the Vamsas Session.");\r
122   }\r
123 \r
124   public void updateJalview(ClientDoc cdoc) {\r
125     ensureVamsasBindings();\r
126     VamsasDatastore vds = new VamsasDatastore(cdoc, vobj2jv, jv2vobj,\r
127         baseProvEntry());\r
128     vds.updateToJalview();\r
129   }\r
130 \r
131   private void ensureVamsasBindings() {\r
132     if (jv2vobj == null) {\r
133       jv2vobj = new IdentityHashMap();\r
134       vobj2jv = new Hashtable();\r
135     }\r
136   }\r
137 \r
138   /**\r
139    * App's object binding to VorbaIds\r
140    */\r
141   IdentityHashMap jv2vobj = null;\r
142 \r
143   Hashtable vobj2jv = null;\r
144 \r
145   /**\r
146    * called with a vamsas document which will be updated with new data from the\r
147    * app\r
148    * \r
149    * @param doc\r
150    */\r
151   public void updateVamsasDocument(ClientDoc doc) {\r
152     ensureVamsasBindings();\r
153     VamsasDatastore vds = new VamsasDatastore(doc, vobj2jv, jv2vobj,\r
154         baseProvEntry());\r
155     // wander through frames\r
156     vds.storeVAMSAS(new Object()); // Object is the apps datamodel ;)\r
157   }\r
158 \r
159   /**\r
160    * \r
161    * @return a base provenance entry used by the VamsasDatastore object to get\r
162    *         attributes from. this isn't particularly elegant either.\r
163    */\r
164   private Entry baseProvEntry() {\r
165     uk.ac.vamsas.objects.core.Entry pentry = new uk.ac.vamsas.objects.core.Entry();\r
166     pentry.setUser(this.getProvenanceUser());\r
167     pentry.setApp(this.getClientHandle().getClientName());\r
168     pentry.setDate(new java.util.Date());\r
169     pentry.setAction("created");\r
170     return pentry;\r
171   }\r
172 \r
173   protected class VamsasClientWatcher extends Thread implements Runnable {\r
174     /*\r
175      * (non-Javadoc)\r
176      * \r
177      * @see java.lang.Thread#run()\r
178      */\r
179     VamsasClient client = null;\r
180 \r
181     VamsasClientWatcher(VamsasClient client) {\r
182       this.client = client;\r
183     }\r
184 \r
185     boolean running = false;\r
186 \r
187     public void run() {\r
188       running = true;\r
189       while (client.watchForChange) {\r
190         ClientDoc docio = client.watch(0);\r
191         if (docio != null) {\r
192           // VamsasClient GUI bits should be disabled whilst an update is in\r
193           // progress so the user doesn't screw anything up.\r
194           client.disableGui(true);\r
195           log.debug("Updating VamsasClient app from changed vamsas document.");\r
196           client.updateJalview(docio);\r
197           log.debug("Finished updating from document change.");\r
198           docio.closeDoc();\r
199           docio = null;\r
200           client.disableGui(false);\r
201         }\r
202       }\r
203       running = false;\r
204 \r
205     }\r
206 \r
207   }\r
208 \r
209   /**\r
210    * @param args\r
211    */\r
212   public static void main(String[] args) {\r
213     // TODO Auto-generated method stub\r
214 \r
215   }\r
216 \r
217   /**\r
218    * disable (if b is true) or enable (if b is true) the VamsasClient's vamsas\r
219    * session gui bits whilst a document change is being updated to the app.\r
220    * \r
221    * @param b\r
222    */\r
223   public void disableGui(boolean b) {\r
224     // in jalview, we turn off the VAMSAS Session menu :\r
225     // Desktop.instance.setVamsasUpdate(b);\r
226   }\r
227 \r
228   /**\r
229    * spawn a new thread to start the VamsasClientWatcher.\r
230    * \r
231    */\r
232   public void startWatcher() {\r
233     if (watcher == null)\r
234       watcher = new VamsasClientWatcher(this);\r
235     Thread thr = new Thread() {\r
236       public void run() {\r
237         watcher.start();\r
238       }\r
239     };\r
240     thr.start();\r
241   }\r
242 \r
243 }\r