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
6 * Earlier versions have also been incorporated into Jalview version 2.4
\r
7 * since 2008, and TOPALi version 2 since 2007.
\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
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
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
22 package uk.ac.vamsas.test.simpleclient;
\r
24 import java.io.File;
\r
25 import java.io.IOException;
\r
26 import java.util.Date;
\r
27 import java.util.Hashtable;
\r
28 import java.util.Vector;
\r
30 import org.apache.commons.logging.Log;
\r
31 import org.apache.commons.logging.LogFactory;
\r
32 import org.exolab.castor.xml.MarshalException;
\r
33 import org.exolab.castor.xml.ValidationException;
\r
35 import uk.ac.vamsas.client.AppDataOutputStream;
\r
36 import uk.ac.vamsas.client.ClientHandle;
\r
37 import uk.ac.vamsas.client.IVorbaIdFactory;
\r
38 import uk.ac.vamsas.client.SessionHandle;
\r
39 import uk.ac.vamsas.client.UserHandle;
\r
40 import uk.ac.vamsas.client.Vobject;
\r
41 import uk.ac.vamsas.client.VorbaId;
\r
42 import uk.ac.vamsas.client.simpleclient.FileWatcher;
\r
43 import uk.ac.vamsas.client.simpleclient.IdFactory;
\r
44 import uk.ac.vamsas.client.simpleclient.SessionFile;
\r
45 import uk.ac.vamsas.client.simpleclient.SimpleDocBinding;
\r
46 import uk.ac.vamsas.client.simpleclient.SimpleDocument;
\r
47 import uk.ac.vamsas.client.simpleclient.VamsasArchive;
\r
48 import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;
\r
49 import uk.ac.vamsas.client.simpleclient.VamsasFile;
\r
50 import uk.ac.vamsas.objects.core.AppData;
\r
51 import uk.ac.vamsas.objects.core.ApplicationData;
\r
52 import uk.ac.vamsas.objects.core.User;
\r
53 import uk.ac.vamsas.objects.core.VamsasDocument;
\r
54 import uk.ac.vamsas.objects.utils.AppDataReference;
\r
55 import uk.ac.vamsas.objects.utils.DocumentStuff;
\r
56 import uk.ac.vamsas.objects.utils.ProvenanceStuff;
\r
57 import uk.ac.vamsas.objects.utils.SeqSet;
\r
58 import uk.ac.vamsas.objects.utils.document.VersionEntries;
\r
59 import uk.ac.vamsas.test.objects.Core;
\r
62 * @author jimp test the VamsasFile routines for watching, reading and updating
\r
63 * a vamsas document jar file. simple document access base class.
\r
65 public class ArchiveClient extends IdFactory {
\r
67 private Log log = LogFactory.getLog(ArchiveClient.class);
\r
69 // protected UserHandle user=null;
\r
70 // protected ClientHandle me = new ClientHandle("ArchiveClient","0.01");
\r
77 public ArchiveClient(UserHandle user, VamsasFile vsess) {
\r
78 super(new SessionHandle("vamsasfile://" + vsess.getVamsasFile()),
\r
79 new ClientHandle("ArchiveClient", "0.01"), user);
\r
84 private void _openVsess(File vsess) {
\r
86 this.vsess = new VamsasFile(vsess);
\r
87 } catch (Exception e) {
\r
88 log.error("Couldn't open session for file " + vsess, e);
\r
93 public ArchiveClient(String username, String organization, File vsess) {
\r
94 super(new SessionHandle("vamsasfile://" + vsess), new ClientHandle(
\r
95 "ArchiveClient", "0.01"), new UserHandle(username, organization));
\r
100 public ArchiveClient(String username, String organization, String clientName,
\r
101 String clientVersion, File vsess) {
\r
102 super(new SessionHandle("vamsasfile://" + vsess), new ClientHandle(
\r
103 clientName, clientVersion), new UserHandle(username, organization));
\r
108 public void valid() {
\r
110 throw new Error("ArchiveClient instance is invalid!.");
\r
114 * set this to false if watch loop should end immediately
\r
116 protected boolean watchForChange = true;
\r
118 public static int WATCH_SLEEP = 300;
\r
121 * watch the document file for updates.
\r
124 * - length of time to watch for.
\r
125 * @return read only IO interface for session document.
\r
127 public ClientDoc watch(long time) {
\r
129 vsess.unLock(); // doh.
\r
130 FileWatcher watcher = new FileWatcher(vsess.getVamsasFile());
\r
131 // watcher.setState();
\r
132 watchForChange = true;
\r
133 long endtime = System.currentTimeMillis() + time;
\r
135 uk.ac.vamsas.client.simpleclient.Lock doclock;
\r
137 doclock = watcher.getChangedState();
\r
138 if (doclock == null)
\r
139 Thread.sleep(WATCH_SLEEP);
\r
140 } while (watchForChange && doclock == null
\r
141 && (time == 0 || endtime > System.currentTimeMillis())); // tuning.
\r
142 if (doclock == null)
\r
145 return getUpdateable(vsess.getLock(doclock));
\r
147 * VamsasArchiveReader varc = new
\r
148 * VamsasArchiveReader(vsess.getVamsasFile()); return
\r
149 * _getReadonly(varc);
\r
152 } catch (Exception e) {
\r
153 log.error("Whilst watching file " + vsess.getVamsasFile(), e);
\r
158 // from ClientDocument.getClientAppdata
\r
159 private AppData[] getAppData(VamsasDocument doc) {
\r
160 // TODO: codefest - not yet tested or merged in to SimpleClient
\r
162 log.debug("extractAppData called for null document object");
\r
165 AppData appsGlobal = null, usersData = null;
\r
166 Vector apldataset = AppDataReference.getUserandApplicationsData(doc, this
\r
167 .getUserHandle(), this.getClientHandle());
\r
168 if (apldataset != null) {
\r
169 if (apldataset.size() > 0) {
\r
170 AppData clientdat = (AppData) apldataset.get(0);
\r
171 if (clientdat instanceof ApplicationData) {
\r
172 appsGlobal = (ApplicationData) clientdat;
\r
173 if (apldataset.size() > 1) {
\r
174 clientdat = (AppData) apldataset.get(1);
\r
175 if (clientdat instanceof User) {
\r
176 usersData = (User) clientdat;
\r
178 if (apldataset.size() > 2)
\r
179 log.info("Ignoring additional (" + (apldataset.size() - 2)
\r
180 + ") AppDatas returned by document appdata query.");
\r
183 log.warn("Unexpected entry in AppDataReference query: id="
\r
184 + clientdat.getVorbaId() + " type="
\r
185 + clientdat.getClass().getName());
\r
187 apldataset.removeAllElements(); // destroy references.
\r
190 return new AppData[] { appsGlobal, usersData };
\r
193 protected ClientDoc _getReadonly(VamsasArchiveReader vreader)
\r
194 throws IOException, ValidationException, MarshalException {
\r
196 if (vreader != null) {
\r
197 SimpleDocBinding docb = new SimpleDocBinding();
\r
198 docb.setVorba(this);
\r
200 d = docb.getVamsasDocument(vreader);
\r
203 ClientDoc creader = new ClientDoc(d, null, vreader, getClientHandle()
\r
204 .getClientUrn(), getProvenanceUser(), getVorbaIdHash());
\r
212 * from SimpleClient
\r
214 * @return user field for a provenance entry
\r
216 protected String getProvenanceUser() {
\r
217 return new String(getUserHandle().getFullName() + " ["
\r
218 + getClientHandle().getClientUrn() + "]");
\r
221 public ClientDoc getUpdateable() {
\r
222 return getUpdateable(null);
\r
225 public ClientDoc getUpdateable(uk.ac.vamsas.client.simpleclient.Lock lock) {
\r
226 getVorbaIdHash().clear();
\r
229 // patiently wait for a lock on the document.
\r
231 while (lock == null
\r
232 && ((lock = vsess.getLock()) == null || !lock.isLocked())
\r
234 // Thread.sleep(1);
\r
235 log.debug("Trying to get a document lock for the " + tries
\r
238 VamsasArchive varc = new VamsasArchive(vsess, true, false); // read
\r
245 varc.setVorba(this);
\r
246 VamsasDocument d = varc.getVamsasDocument(getProvenanceUser(),
\r
247 "Created new document.", VersionEntries.latestVersion()); // VAMSAS:
\r
255 .warn("Backing out from opening a VamsasArchive writable IO session");
\r
256 varc.cancelArchive();
\r
259 ClientDoc cdoc = new ClientDoc(d, varc, varc.getOriginalArchiveReader(),
\r
260 getClientHandle().getClientUrn(), getProvenanceUser(),
\r
264 } catch (Exception e) {
\r
265 log.error("Failed to get Updateable version of " + vsess.getVamsasFile(),
\r
272 * trust client to not do anything stupid to the document roots which will now
\r
273 * be written to the archive.
\r
276 * @return true if write was a success.
\r
278 public boolean doUpdate(ClientDoc cdoc) {
\r
280 if (cdoc == null) {
\r
282 .warn("Invalid ClientDoc passed to uk.ac.vamsas.test.simpleclient.doUpdate()");
\r
285 if (cdoc.iohandler == null) {
\r
287 .warn("Read only ClientDoc object passed to uk.ac.vamsas.test.simpleclient.doUpdate()");
\r
290 if (cdoc.iohandler.getVorba() != this) {
\r
292 .error("Mismatch between ClientDoc instances and ArchiveClient instances!");
\r
296 // do any appDatas first.
\r
297 if (cdoc.iohandler.transferRemainingAppDatas())
\r
298 log.debug("Remaining appdatas were transfered.");
\r
299 cdoc.updateDocumentRoots();
\r
300 cdoc.iohandler.putVamsasDocument(cdoc.doc);
\r
301 cdoc.iohandler.closeArchive();
\r
302 this.extantids.clear();// we forget our ids after we close the document.
\r
303 cdoc.iohandler = null;
\r
306 } catch (Exception e) {
\r
307 log.warn("While updating archive in " + vsess.getVamsasFile(), e);
\r
316 public static void usage() {
\r
317 throw new Error("Usage: Username Organization VamsasFile [command,args]*");
\r
320 public static void main(String[] args) {
\r
322 if (args.length < 3)
\r
325 ArchiveClient client = new ArchiveClient(args[0], args[1],
\r
326 new File(args[2]));
\r
327 ClientDoc cdoc = null;
\r
330 cdoc = client.getUpdateable();
\r
331 // ArchiveReports.reportDocument(cdoc.doc, cdoc.getReader(), true,
\r
333 System.out.println("Report Roots :");
\r
334 ArchiveReports.rootReport(cdoc.getVamsasRoots(), true, System.out);
\r
335 cdoc.addVamsasRoot(Core.getDemoVamsas());
\r
336 System.out.println("Doing update.");
\r
337 client.doUpdate(cdoc);
\r
342 System.out.println("Watch for more... (" + u + " left)");
\r
343 ClientDoc ucdoc = client.watch(0000);
\r
344 if (ucdoc != null) {
\r
345 System.out.println("****\nUpdate detected at " + new Date());
\r
346 ArchiveReports.reportDocument(ucdoc.doc, ucdoc.getReader(), true,
\r
351 System.out.println("!!!! Null document update detected at "
\r
355 } catch (Exception e) {
\r
356 client.log.error("Broken!", e);
\r
358 System.out.println("Finished at " + new Date());
\r
361 public uk.ac.vamsas.client.Vobject getObject(VorbaId id) {
\r
362 Hashtable idhash = this.getVorbaIdHash();
\r
363 if (idhash != null && idhash.containsKey(id))
\r
364 return (Vobject) idhash.get(id);
\r