/*
* 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.client.simpleclient;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.OverlappingFileLockException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import uk.ac.vamsas.client.ClientHandle;
import uk.ac.vamsas.client.Events;
import uk.ac.vamsas.client.UserHandle;
/**
* Does all the IO operations for a SimpleClient instance accessing a
* SimpleClient vamsas session.
*
* Basically, it defines the various standard names for the files in the session
* directory (that maps to the sessionUrn), provides constructors for the file
* handlers and watchers of those file entities, and some higher level methods
* to check and change the state flags for the session.
*
* TODO: move the stuff below to the SimpleClientFactory documentation. much may
* not be valid now : Vamsas client is intialised with a path to create live
* session directories. This path may contain a vamsas.properties file that sets
* additional parameters (otherwise client just uses the one on the classpath).
*
* A vamsas session consists of : SessionDir - translates to urn of a live
* session. Contains: Vamsas Document (as a jar), Session client list file, both
* of which may be locked, and additional temporary versions of these files when
* write operations are taking place.
*
* Zip file entries - vamsasdocument.xml : core info one or more: -
* .version.sessionnumber.raw (string given in
* vamsasdocument.xml applicationData entry)
*
* Lockfile - filename given in the vamsasdocument.xml. Should be checked for
* validity by any client and rewritten if necessary. The lockfile can point to
* the jar itself. Mode of operation. Initially - documentHandler either: -
* creates a zip for a new session for the client - connect to an existing
* session zip 1. reads session urn file 2. waits for lock 3. examines session -
* decide whether to create new application data slice or connect to one stored
* in session. 4. writes info into session file 5. releases lock and generates
* local client events. 6. Creates Watcher thread to generate events.
*
* During the session - Update watcher checks for file change -
*
* Procedures for file based session message exchange - session document
* modification flag
*
*/
public class VamsasSession {
/**
* indicator file for informing other processes that they should finalise
* their vamsas datasets for storing into a vamsas archive.
*/
public static final String CLOSEANDSAVE_FILE = "stored.log";
/**
* session file storing the last_stored_stat data
*/
public static final String MODIFIEDDOC_FILE = "modified";
private SimpleSessionManager sessionManager = null;
/**
* Count of cycles before considering the current client as the last one of
* the session (if no other client registered as active )
*/
private final int watchCycleCountBeforeLastClient = 1220;
/**
* time between checking
*/
public int WATCH_SLEEP = 30;
protected String clientFileDirectory = "clients";
/**
* called to clear update flag after a successful offline storage event
*/
protected void clearUnsavedFlag() {
SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir,
MODIFIEDDOC_FILE));
if (!laststored.clearFlag())
log.warn("Unsaved flag was not cleared for " + sessionDir);
}
/**
* called to indicate session document has been modified.
*
*/
protected void setUnsavedFlag() {
SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir,
MODIFIEDDOC_FILE));
if (!laststored.setFlag())
log.warn("Couldn't set the Unsaved flag for " + sessionDir);
}
/**
*
* @return true if session document has been modified since last offline
* storage event
*/
protected boolean getUnsavedFlag() {
SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir,
MODIFIEDDOC_FILE));
return laststored.checkFlag();
}
/**
* log file location
*/
public static final String SESSION_LOG = "Log.txt";
private static Log log = LogFactory.getLog(VamsasSession.class);
protected Logger slog = Logger.getLogger("uk.ac.vamsas.client.SessionLog");
/**
* the appender that writes to the log file inside the session's directory.
*/
private FileAppender slogAppender = null;
/**
* setup the sessionLog using Log4j.
*
* @throws IOException
*/
private void initLog() throws IOException {
// TODO: fix session event logging
// LATER: make dedicated appender format for session log.
/*
* Appender app = slog.getAppender("log4j.appender.SESSIONLOG"); //
* slog.addAppender(new FileAppender(app.getLayout(), new File(sessionDir,
* SESSION_LOG).getAbsolutePath())); // slog.addAppender(new
* FileAppender(app.getLayout(), new File(sessionDir,
* SESSION_LOG).getAbsolutePath())); for (Enumeration e =
* slog.getAllAppenders() ; e.hasMoreElements() ;) {
* System.out.println(e.nextElement()); }
*/
if (slog != null) {
File sessionLogFile = new File(this.sessionDir, SESSION_LOG);
slog.addAppender(slogAppender = new FileAppender(new PatternLayout(
"%-4r [%t] %-5p %c %x - %m%n"), sessionLogFile.getAbsolutePath(),
true));
} else {
log.info("No appender for SessionLog");
}
}
private void closeSessionLog() {
if (slog != null) {
if (slogAppender != null) {
slog.removeAppender(slogAppender);
slogAppender.close();
slogAppender = null;
}
}
}
/**
* the sessionDir is given as the session location for new clients.
*/
protected File sessionDir;
/**
* holds the list of attached clients
*/
ClientsFile clist;
public static final String CLIENT_LIST = "Clients.obj";
/**
* holds the data
*/
VamsasFile vamArchive;
public static final String VAMSAS_OBJ = "VamDoc.jar";
/**
* sets up the vamsas session files and watchers in sessionDir1
*
* @param sessionDir1
*/
protected VamsasSession(File sessionDir1) throws IOException {
this(sessionDir1, null);
}
private SimpleSessionHandle sessionHandle = null;
/**
* sets up the vamsas session files and watchers in sessionDir1
*
* @param sessionDir1
* @param extVamDoc
* null or an existing archive to initialise the session with
* @throws any
* IOExceptions from creating session directory and files.
* @throws error
* if both extVamDoc and sessionDir1 already exist (cannot import
* new data into session in this way)
*/
protected VamsasSession(File sessionDir1, File extVamDoc) throws IOException {
// TODO: refactor to separate extVamDoc path from session URN - enables non-local URLs to be locally bound to sessions.
if (sessionDir1 == null)
throw new Error("Null directory for VamsasSession.");
if (!sessionDir1.exists() && !sessionDir1.mkdir()) {
throw new IOException("Failed to make VamsasSession directory in "
+ sessionDir1);
}
if (!sessionDir1.isDirectory() || !sessionDir1.canWrite()
|| !sessionDir1.canRead()) {
throw new IOException("Cannot access '" + sessionDir1
+ "' as a read/writable Directory.");
}
boolean existingSession = checkSessionFiles(sessionDir1);
if (existingSession) {
if (extVamDoc != null) {
throw new Error(
"Client Initialisation Error: Cannot join an existing session directory with an existing vamsas document to import.");
} else {
log.debug("Joining an existing session.");
}
}
this.sessionDir = sessionDir1;
if (extVamDoc==null) {
sessionHandle = new SimpleSessionHandle(new SessionUrn(sessionDir).getSessionUrn(),sessionDir);
} else {
// Construct Session URN from the original vamsas document.
sessionHandle = new SimpleSessionHandle(new SessionUrn(extVamDoc).getSessionUrn(),sessionDir);
}
initSessionObjects();
if (existingSession) {
slog.debug("Initialising additional VamsasSession instance");
} else {
slog.debug("Founding client has joined VamsasSession instance");
}
log.debug("Attached to VamsasSession in " + sessionDir1);
if (extVamDoc != null) {
setVamsasDocument(extVamDoc);
}
slog.debug("Session directory created.");
log.debug("Initialised VamsasSession in " + sessionDir1);
}
/**
* tests presence of existing sessionfiles files in dir
*
* @param dir
* @return
*/
private boolean checkSessionFiles(File dir) throws IOException {
File c_file = new File(dir, CLIENT_LIST);
File v_doc = new File(dir, VAMSAS_OBJ);
if (c_file.exists() && v_doc.exists())
return true;
return false;
}
/**
* create new empty files in dir
*
*/
private void createSessionFiles() throws IOException {
if (sessionDir == null)
throw new IOException(
"Invalid call to createSessionFiles() with null sessionDir");
File c_file = new File(sessionDir, CLIENT_LIST);
File v_doc = new File(sessionDir, VAMSAS_OBJ);
if (!c_file.exists() && c_file.createNewFile())
log.debug("Created new ClientFile " + c_file); // don't care if this
// works or not
if (!v_doc.exists()) {
if (v_doc.createNewFile()) {
log.debug("Created new Vamsas Session Document File " + v_doc);
} else {
log.warn("Didn't create Vamsas Session Document file in " + v_doc);
}
}
}
/**
* construct SessionFile objects and watchers for each
*/
private void initSessionObjects() throws IOException {
createSessionFiles();
if (clist != null || vamArchive != null)
throw new IOException(
"initSessionObjects called for initialised VamsasSession object.");
clist = new ClientsFile(new File(sessionDir, CLIENT_LIST));
vamArchive = new VamsasFile(new File(sessionDir, VAMSAS_OBJ));
storedocfile = new ClientsFile(new File(sessionDir, CLOSEANDSAVE_FILE));
initLog();
}
/**
* make a new watcher object for the clientFile
*
* @return new ClientFile watcher instance
*/
public FileWatcher getClientWatcher() {
return new FileWatcher(clist.sessionFile);
}
/**
* make a new watcher object for the vamsas Document
*
* @return new ClientFile watcher instance
*/
public FileWatcher getDocWatcher() {
return new FileWatcher(vamArchive.sessionFile);
}
FileWatcher store_doc_file = null;
public ClientsFile storedocfile = null;
/**
* make a new watcher object for the messages file
*
* @return new watcher instance
*/
public FileWatcher getStoreWatcher() {
return new FileWatcher(new File(sessionDir, CLOSEANDSAVE_FILE));
}
/**
* write to the StoreWatcher file to indicate that a storeDocumentRequest has
* been made. The local client's storeWatcher FileWatcher object is updated so
* the initial change is not registered.
*
* @param client
* @param user
* @return
*/
public void addStoreDocumentRequest(ClientHandle client, UserHandle user)
throws IOException {
// TODO: replace this with clientsFile mechanism
SessionFile sfw = new SessionFile(new File(sessionDir, CLOSEANDSAVE_FILE));
while (!sfw.lockFile())
log.debug("Trying to get lock for " + CLOSEANDSAVE_FILE);
RandomAccessFile sfwfile = sfw.fileLock.getRaFile();
sfwfile.setLength(0); // wipe out any old info.
// TODO: rationalise what gets written to this file (ie do we want other
// clients to read the id of the requestor?)
sfwfile.writeUTF(client.getClientUrn() + ":" + user.getFullName() + "@"
+ user.getOrganization());
sfw.unlockFile();
if (store_doc_file != null)
store_doc_file.setState();
slog.info("FinalizeAppData request from " + user.getFullName() + " using "
+ client.getClientUrn() + "");
}
/**
* create a new session with an existing vamsas Document - by copying it into
* the session.
*
* @param archive
*/
public void setVamsasDocument(File archive) throws IOException {
log.debug("Transferring vamsas data from " + archive + " to session:"
+ vamArchive.sessionFile);
SessionFile xtantdoc = new SessionFile(archive);
while (!vamArchive.lockFile())
log.info("Trying to get lock for " + vamArchive.sessionFile);
vamArchive.updateFrom(null, xtantdoc);
xtantdoc.unlockFile();
unlockVamsasDocument();
// TODO: session archive provenance should be updated to reflect import from
// external source
log.debug("Transfer complete.");
}
/**
* write session as a new vamsas Document (this will overwrite any existing
* file without warning) TODO: test TODO: verify that lock should be released
* for vamsas document.
*
* @param destarchive
*/
protected void writeVamsasDocument(File destarchive, Lock extlock)
throws IOException {
log.debug("Transferring vamsas data from " + vamArchive.sessionFile
+ " to session:" + destarchive);
SessionFile newdoc = new SessionFile(destarchive);
if (extlock == null && !vamArchive.lockFile())
while (!vamArchive.lockFile())
log.info("Trying to get lock for " + vamArchive.sessionFile);
// TODO: LATER: decide if a provenance entry should be written in the
// exported document recording the export from the session
newdoc.updateFrom(null, vamArchive);
// LATER: LATER: fix use of updateFrom for file systems where locks cannot
// be made (because they don't have a lockManager, ie NFS/Unix, etc).
vamArchive.unLock();
newdoc.unlockFile();
log.debug("Transfer complete.");
}
/**
* extant archive IO handler
*/
VamsasArchive _va = null;
/**
* Creates a VamsasArchive Vobject for accessing and updating document Note:
* this will lock the Vamsas Document for exclusive access to the client.
*
* @return session vamsas document
* @throws IOException
* if locks fail or vamsas document read fails.
*/
protected VamsasArchive getVamsasDocument() throws IOException {
// check we haven't already done this once - probably should be done by
// caller
if (_va != null)
return _va;
// patiently wait for a lock on the document. (from
// ArchiveClient.getUpdateable())
long tries = 5000;
while (vamArchive.getLock() == null && --tries > 0) {
// Thread.sleep(1);
log.debug("Trying to get a document lock for the " + tries + "'th time.");
}
if (tries == 0)
throw new IOException("Failed to get lock for vamsas archive.");
VamsasArchive va = new VamsasArchive(vamArchive.sessionFile, false, true,
vamArchive);
return va;
}
/**
* Unlocks the vamsas archive session document after it has been closed.
*
* @throws IOException
*/
protected void unlockVamsasDocument() throws IOException {
if (_va != null)
_va.closeArchive();
_va = null;
if (vamArchive != null)
vamArchive.unLock();
}
/**
* create a uniquely named
* uk.ac.vamsas.client.simpleclient.ClientsFile.addClient(ClientHandle)ile in
* the session Directory
*
* @see java.io.File.createTempFile
* @param pref
* Prefix for name
* @param suff
* Suffix for name
* @return SessionFile object configured for the new file (of length zero)
* @throws IOException
*/
protected SessionFile getTempSessionFile(String pref, String suff)
throws IOException {
File tfile = File.createTempFile(pref, suff, sessionDir);
SessionFile tempFile = new SessionFile(tfile);
return tempFile;
}
/**
* add a IClient to the session
*
* add the client to the client list file
*
* @param client
* client to add to the session
*/
protected void addClient(SimpleClient client) {
if (client == null)
slog.error("Try to add a null client to the session ");
else {
log.debug("Adding client " + client.getClientHandle().getClientUrn());
getClientWatcherElement().haltWatch();
clist.addClient(client.getClientHandle());
log.debug("Added.");
log.debug("Register Client as Active.");
try {
client.createActiveClientFile();
} catch (IOException e) {
log.debug("Error during active client file creation.");
}
// tracks modification to the client list and readds client to the list
getClientWatcherElement().setHandler(new AddClientWatchCallBack(client));
getClientWatcherElement().enableWatch();
}
}
/**
* Handler for the client watcher.
*
* If (the current client is not in the client list, it is added again;)
*/
private class AddClientWatchCallBack implements WatcherCallBack {
private SimpleClient client;
/**
* Inits the handler with the client to check in the list
*
* @param client
* client to monitor in the client list
*/
protected AddClientWatchCallBack(SimpleClient client) {
this.client = client;
}
/**
* If the client list is modified, checks if the current is still in the
* list. otherwise, readds ti.
*
* @return true to enable watcher, or false to disable it in future
* WatcherThread cycles.
*/
public boolean handleWatchEvent(WatcherElement watcher, Lock lock) {
boolean isWatchEnable = watcher.isWatchEnabled();
if (lock == null)// no update on the list
return isWatchEnable;
log.debug("change on the client list ");
if (client != null) {
// checks if the client is not already in the lists
ClientHandle[] cl = clist.retrieveClientList(lock);// clist.retrieveClientList();
boolean found = false;
if (cl != null) {
for (int chi = cl.length - 1; !found && chi > -1; chi--) {
found = cl[chi].equals(this.client.getClientHandle());
}
}
if (!found) {
log.debug("client not in the list ");
if (log.isDebugEnabled())
log
.debug("the client has not been found in the list. Adding it again :"
+ cl);
addClient(client);
} else
log.debug("client is in the list");
}
log.debug("isWatchEnable " + isWatchEnable);
return isWatchEnable;
}
}
/**
*
* removes a client from the current session removes the client from the
* session client list if the client is the last one from the session
* (ClientList), the current session is removed from active session list.
*
* The active should add them self to the client list. To insure to close the
* session,when the current client is the lact active client, clears the list
* of clients and when two cycles to insure there is no more active client,
* that otherwise would have readd themself to the list
*
* @param client
* client to remove
*/
protected void removeClient(SimpleClient client)// IClient client)
{
if (client == null) {
log.error("Null client passed to removeClient");
return;
}
// ClientSessionFileWatcherElement cwe=getClientWatcherElement();
// if (cwe!=null && cwe.isWatchEnabled()) {
// cwe.haltWatch();
// };
// set handler to check is the the last active client of the session
// Wait for several watchers cycle to see if the current client was the last
// client active in the session.
// if yes, close the session
// getClientWatcherElement().setHandler(new RemoveClientWatchCallBack
// (client));
// getClientWatcherElement().setTimeoutBeforeLastCycle(this.watchCycleCountBeforeLastClient);
log.info("remove client from list");
if (clistWatchElement != null) {
clistWatchElement.haltWatch();
clistWatchElement.watched.unlockFile();
}
// clist.clearList();
// clist.unlockFile();
log.info("list cleared");
// if (cwe!=null) {
// cwe.enableWatch();
log.debug("Stopping EventGenerator..");
client.evgen.stopWatching();
// cwe.setHandler(null);
// ask to the client to copy application data into the document
client.evgen._raise(Events.DOCUMENT_FINALIZEAPPDATA, null, client, null);
boolean closeSession = isLastActiveClient(client);
if (closeSession) {
if (client.get_session().getUnsavedFlag()) {
log.debug("Raising request-to-save event");
client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null);
}
log.debug("Raising session shutdown event");
client.evgen._raise(Events.SESSION_SHUTDOWN, null, client
.getSessionHandle(), null);
log.debug("All events raised for finalising session "
+ client.getSessionHandle().toString());
}
// cwe.haltWatch();
client.evgen.stopWatching();
try {
log.debug("Attempting to release active client locks");
client.releaseActiveClientFile();
} catch (IOException e) {
log.error("error during active file client release");
}
tidyUp();
if (closeSession) {
log.debug("Last active client: closing session");
log.info("Closing session");
closeSession(client.getSessionHandle());
}
}
/**
* close every file and stop.
*/
private void tidyUp() {
if (clist != null)
clist.unlockFile();
clist = null;
storedocfile.unlockFile();
storedocfile = null;
closeSessionLog();
}
private boolean isLastActiveClient(SimpleClient client) {
log.debug("Testing if current client is the last one.");
log
.debug("current client lockfile is '" + client.getClientlockFile()
+ "'");
boolean noOtherActiveClient = true;
// create, if need, subdirectory to contain client files
File clientlockFileDir = new File(this.sessionDir, clientFileDirectory);
if (!clientlockFileDir.exists()) {
log
.error("Something wrong the active client file does not exits... should not happen");
return false;
}
try {
// no check every file in the directory and try to get lock on it.
File[] clientFiles = clientlockFileDir.listFiles();
if (clientFiles == null || clientFiles.length == 0) {// there is not file
// on the directory.
// the current
// client should be
// the last one.
return true;
}
for (int i = clientFiles.length - 1; i > -1 && noOtherActiveClient; i--) {
File clientFile = clientFiles[i];
log.debug("testing file for lock: " + clientFile.getAbsolutePath());
if (client.getClientLock().isTargetLockFile(clientFile)) {
log.debug("current client file found");
continue;
}
if (clientFile != null && clientFile.exists()) {
try {
log.debug("Try to acquire a lock on the file");
// Get a file channel for the file
FileChannel channel = new RandomAccessFile(clientFile, "rw")
.getChannel();
// Use the file channel to create a lock on the file.
// This method blocks until it can retrieve the lock.
// java.nio.channels.FileLock activeClientFilelock = channel.lock();
// Try acquiring the lock without blocking. This method returns
// null or throws an exception if the file is already locked.
try {
java.nio.channels.FileLock activeClientFilelock = channel
.tryLock();
// the lock has been acquired.
// the file was not lock and so the corresponding application
// seems to have die
if (activeClientFilelock != null) {
log
.debug("lock obtained : file must be from a crashed application");
activeClientFilelock.release();
log.debug("lock released");
channel.close();
log.debug("channel closed");
// delete file
clientFile.delete();
log.debug("crashed application file deleted");
} else {
noOtherActiveClient = false;
log.debug("lock not obtained : another application is active");
}
} catch (OverlappingFileLockException e) {
// File is already locked in this thread or virtual machine
// that the expected behaviour
log.debug("lock not accessible ", e);
}
} catch (Exception e) {
log.debug("error during lock testing ", e);
}
}
}
} catch (Exception e) {
log.error("error during counting active clients");
}
return noOtherActiveClient;
}
/**
* Handler for the client watcher. after a client have been removed
*
* Checks if the client is not the last active one.
*
* If (the current client is not in the client list readd it;)
*/
private class RemoveClientWatchCallBack implements WatcherCallBack {
private SimpleClient client;
private boolean manualCheckOfClientCount = false;
/**
* Inits the handler with the client to check in the list
*
* @param client
* client to monitor in the client list
*/
protected RemoveClientWatchCallBack(SimpleClient client) {
this.client = client;
}
/**
* If the client list is modified, checks if the current is still in the
* list. otherwise, readds ti.
*
* @return true to enable watcher, or false to disable it in future
* WatcherThread cycles.
*/
public boolean handleWatchEvent(WatcherElement watcher, Lock lock) {
// if lock is null, no client has been added since last, clear.
// the client is then the last client
if (client != null) {
if (lock == null) {
// checks if the client is not already in the lists
// ClientHandle[] cl =
// clist.retrieveClientList();//lock);//clist.retrieveClientList();
boolean islastClient = true;
if (manualCheckOfClientCount) {
log.debug("manual checking of count of client");
// checks if the client is not already in the lists
ClientHandle[] cl = clist.retrieveClientList();// lock);//clist.retrieveClientList();
if (cl == null || cl.length < 1)
// {//no client has registered as active
{
islastClient = true;
log.debug("list is empty");
} else
islastClient = false;
log.debug("list is not empty");
}
// if(cl == null || cl.length<1 )
// {//no client has registered as active
if (islastClient) {
// the client is the last one, so close current session
log
.info("FROMCLIENTLIST WATCHER: last client removed: closing session");
closeSession(client);
}
} else {
log.debug("not the last client found ");
// ask to the client to cpoy application data into the document
// client.evgen._raise(Events.DOCUMENT_FINALIZEAPPDATA, null,
// client,null);
// / }
}
log.debug("Stopping EventGenerator..");
// TODO: ensure ClientsFile lock is really released!!
// clist.unlockFile();
client.evgen.stopWatching();
}
watcher.setHandler(null);// Do not check if the client is the last
// client. watcher will shutdown anyway
// watcher.haltWatch();
// watcher.
return false;
}
}
/**
* closes the current session, and send an event to the last client to close
* the document
*
* @param client
* the last client of the client
*/
private void closeSession(SimpleClient client) {
// close document
client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null);
log.debug("close document request done");
closeSession(client.getSessionHandle());
}
/**
* CLoses the current session
*
* @param sessionHandle
* sessionHandle of the session to remove
*/
private void closeSession(uk.ac.vamsas.client.SessionHandle sessionHandle) {
//if (sessionHandle instanceof SimpleSessionHandle)
//{
getSessionManager().removeSession(sessionHandle);
log.debug("Session removed");
//} else {
// log.error("Cannot close a sessionHandle (URN="+sessionHandle.getSessionUrn()+") which is of type "+sessionHandle.getClass());
// throw new Error("Tried to close a non-SimpleClient vamsas sessionHandle");
//}
}
/**
* @return the sessionManager
*/
protected SimpleSessionManager getSessionManager() {
return sessionManager;
}
/**
* @param sessionManager
* the sessionManager to set
*/
protected void setSessionManager(SimpleSessionManager sessionManager) {
this.sessionManager = sessionManager;
}
public ClientsFile getStoreDocFile() {
if (storedocfile == null) {
}
return storedocfile;
}
ClientSessionFileWatcherElement clistWatchElement = null;
/**
* get or create a watcher on clist.
*
* @return the contents of clistWatchElement or initialise it
*/
public ClientSessionFileWatcherElement getClientWatcherElement() {
if (clistWatchElement == null) {
clistWatchElement = new ClientSessionFileWatcherElement(clist, null);
}
return clistWatchElement;
}
public uk.ac.vamsas.client.simpleclient.SimpleSessionHandle getSessionUrn() {
return sessionHandle;
}
}