/* * This file is part of the Vamsas Client version 0.1. * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, * Andrew Waterhouse and Dominik Lindner. * * Earlier versions have also been incorporated into Jalview version 2.4 * since 2008, and TOPALi version 2 since 2007. * * The Vamsas Client is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Vamsas Client is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Vamsas Client. If not, see . */ package uk.ac.vamsas.test.simpleclient; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.ValidationException; import uk.ac.vamsas.client.AppDataOutputStream; import uk.ac.vamsas.client.ClientHandle; import uk.ac.vamsas.client.IVorbaIdFactory; import uk.ac.vamsas.client.SessionHandle; import uk.ac.vamsas.client.UserHandle; import uk.ac.vamsas.client.Vobject; import uk.ac.vamsas.client.VorbaId; import uk.ac.vamsas.client.simpleclient.FileWatcher; import uk.ac.vamsas.client.simpleclient.IdFactory; import uk.ac.vamsas.client.simpleclient.SessionFile; import uk.ac.vamsas.client.simpleclient.SimpleDocBinding; import uk.ac.vamsas.client.simpleclient.SimpleDocument; import uk.ac.vamsas.client.simpleclient.VamsasArchive; import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader; import uk.ac.vamsas.client.simpleclient.VamsasFile; import uk.ac.vamsas.objects.core.AppData; import uk.ac.vamsas.objects.core.ApplicationData; import uk.ac.vamsas.objects.core.User; import uk.ac.vamsas.objects.core.VamsasDocument; import uk.ac.vamsas.objects.utils.AppDataReference; import uk.ac.vamsas.objects.utils.DocumentStuff; import uk.ac.vamsas.objects.utils.ProvenanceStuff; import uk.ac.vamsas.objects.utils.SeqSet; import uk.ac.vamsas.objects.utils.document.VersionEntries; import uk.ac.vamsas.test.objects.Core; /** * @author jimp test the VamsasFile routines for watching, reading and updating * a vamsas document jar file. simple document access base class. */ public class ArchiveClient extends IdFactory { private Log log = LogFactory.getLog(ArchiveClient.class); // protected UserHandle user=null; // protected ClientHandle me = new ClientHandle("ArchiveClient","0.01"); VamsasFile vsess; /** * @param user * @param vsess */ public ArchiveClient(UserHandle user, VamsasFile vsess) { super(new SessionHandle("vamsasfile://" + vsess.getVamsasFile()), new ClientHandle("ArchiveClient", "0.01"), user); this.vsess = vsess; valid(); } private void _openVsess(File vsess) { try { this.vsess = new VamsasFile(vsess); } catch (Exception e) { log.error("Couldn't open session for file " + vsess, e); this.vsess = null; } } public ArchiveClient(String username, String organization, File vsess) { super(new SessionHandle("vamsasfile://" + vsess), new ClientHandle( "ArchiveClient", "0.01"), new UserHandle(username, organization)); _openVsess(vsess); valid(); } public ArchiveClient(String username, String organization, String clientName, String clientVersion, File vsess) { super(new SessionHandle("vamsasfile://" + vsess), new ClientHandle( clientName, clientVersion), new UserHandle(username, organization)); _openVsess(vsess); valid(); } public void valid() { if (vsess == null) throw new Error("ArchiveClient instance is invalid!."); } /** * set this to false if watch loop should end immediately */ protected boolean watchForChange = true; public static int WATCH_SLEEP = 300; /** * watch the document file for updates. * * @param time * - length of time to watch for. * @return read only IO interface for session document. */ public ClientDoc watch(long time) { valid(); vsess.unLock(); // doh. FileWatcher watcher = new FileWatcher(vsess.getVamsasFile()); // watcher.setState(); watchForChange = true; long endtime = System.currentTimeMillis() + time; try { uk.ac.vamsas.client.simpleclient.Lock doclock; do { doclock = watcher.getChangedState(); if (doclock == null) Thread.sleep(WATCH_SLEEP); } while (watchForChange && doclock == null && (time == 0 || endtime > System.currentTimeMillis())); // tuning. if (doclock == null) return null; else { return getUpdateable(vsess.getLock(doclock)); /* * VamsasArchiveReader varc = new * VamsasArchiveReader(vsess.getVamsasFile()); return * _getReadonly(varc); */ } } catch (Exception e) { log.error("Whilst watching file " + vsess.getVamsasFile(), e); } return null; } // from ClientDocument.getClientAppdata private AppData[] getAppData(VamsasDocument doc) { // TODO: codefest - not yet tested or merged in to SimpleClient if (doc == null) { log.debug("extractAppData called for null document object"); return null; } AppData appsGlobal = null, usersData = null; Vector apldataset = AppDataReference.getUserandApplicationsData(doc, this .getUserHandle(), this.getClientHandle()); if (apldataset != null) { if (apldataset.size() > 0) { AppData clientdat = (AppData) apldataset.get(0); if (clientdat instanceof ApplicationData) { appsGlobal = (ApplicationData) clientdat; if (apldataset.size() > 1) { clientdat = (AppData) apldataset.get(1); if (clientdat instanceof User) { usersData = (User) clientdat; } if (apldataset.size() > 2) log.info("Ignoring additional (" + (apldataset.size() - 2) + ") AppDatas returned by document appdata query."); } } else { log.warn("Unexpected entry in AppDataReference query: id=" + clientdat.getVorbaId() + " type=" + clientdat.getClass().getName()); } apldataset.removeAllElements(); // destroy references. } } return new AppData[] { appsGlobal, usersData }; } protected ClientDoc _getReadonly(VamsasArchiveReader vreader) throws IOException, ValidationException, MarshalException { valid(); if (vreader != null) { SimpleDocBinding docb = new SimpleDocBinding(); docb.setVorba(this); VamsasDocument d; d = docb.getVamsasDocument(vreader); if (d != null) { ClientDoc creader = new ClientDoc(d, null, vreader, getClientHandle() .getClientUrn(), getProvenanceUser(), getVorbaIdHash()); return creader; } } return null; } /** * from SimpleClient * * @return user field for a provenance entry */ protected String getProvenanceUser() { return new String(getUserHandle().getFullName() + " [" + getClientHandle().getClientUrn() + "]"); } public ClientDoc getUpdateable() { return getUpdateable(null); } public ClientDoc getUpdateable(uk.ac.vamsas.client.simpleclient.Lock lock) { getVorbaIdHash().clear(); valid(); try { // patiently wait for a lock on the document. long tries = 5000; while (lock == null && ((lock = vsess.getLock()) == null || !lock.isLocked()) && --tries > 0) { // Thread.sleep(1); log.debug("Trying to get a document lock for the " + tries + "'th time."); } VamsasArchive varc = new VamsasArchive(vsess, true, false); // read // archive, // write as // vamsasDocument, // don't erase // original // contents. varc.setVorba(this); VamsasDocument d = varc.getVamsasDocument(getProvenanceUser(), "Created new document.", VersionEntries.latestVersion()); // VAMSAS: // provenance // user and // client // combined if (d == null) { log .warn("Backing out from opening a VamsasArchive writable IO session"); varc.cancelArchive(); return null; } ClientDoc cdoc = new ClientDoc(d, varc, varc.getOriginalArchiveReader(), getClientHandle().getClientUrn(), getProvenanceUser(), getVorbaIdHash()); return cdoc; // do appHandle? } catch (Exception e) { log.error("Failed to get Updateable version of " + vsess.getVamsasFile(), e); } return null; } /** * trust client to not do anything stupid to the document roots which will now * be written to the archive. * * @param cdoc * @return true if write was a success. */ public boolean doUpdate(ClientDoc cdoc) { valid(); if (cdoc == null) { log .warn("Invalid ClientDoc passed to uk.ac.vamsas.test.simpleclient.doUpdate()"); return false; } if (cdoc.iohandler == null) { log .warn("Read only ClientDoc object passed to uk.ac.vamsas.test.simpleclient.doUpdate()"); return false; } if (cdoc.iohandler.getVorba() != this) { log .error("Mismatch between ClientDoc instances and ArchiveClient instances!"); return false; } try { // do any appDatas first. if (cdoc.iohandler.transferRemainingAppDatas()) log.debug("Remaining appdatas were transfered."); cdoc.updateDocumentRoots(); cdoc.iohandler.putVamsasDocument(cdoc.doc); cdoc.iohandler.closeArchive(); this.extantids.clear();// we forget our ids after we close the document. cdoc.iohandler = null; cdoc = null; vsess.unLock(); } catch (Exception e) { log.warn("While updating archive in " + vsess.getVamsasFile(), e); return false; } return true; } /** * @param args */ public static void usage() { throw new Error("Usage: Username Organization VamsasFile [command,args]*"); } public static void main(String[] args) { // really simple. if (args.length < 3) usage(); ArchiveClient client = new ArchiveClient(args[0], args[1], new File(args[2])); ClientDoc cdoc = null; // sanity test. try { cdoc = client.getUpdateable(); // ArchiveReports.reportDocument(cdoc.doc, cdoc.getReader(), true, // System.out); System.out.println("Report Roots :"); ArchiveReports.rootReport(cdoc.getVamsasRoots(), true, System.out); cdoc.addVamsasRoot(Core.getDemoVamsas()); System.out.println("Doing update."); client.doUpdate(cdoc); cdoc.closeDoc(); cdoc = null; int u = 5; while (--u > 0) { System.out.println("Watch for more... (" + u + " left)"); ClientDoc ucdoc = client.watch(0000); if (ucdoc != null) { System.out.println("****\nUpdate detected at " + new Date()); ArchiveReports.reportDocument(ucdoc.doc, ucdoc.getReader(), true, System.out); ucdoc.closeDoc(); ucdoc = null; } else { System.out.println("!!!! Null document update detected at " + new Date()); } } } catch (Exception e) { client.log.error("Broken!", e); } System.out.println("Finished at " + new Date()); } public uk.ac.vamsas.client.Vobject getObject(VorbaId id) { Hashtable idhash = this.getVorbaIdHash(); if (idhash != null && idhash.containsKey(id)) return (Vobject) idhash.get(id); return null; } }