From f00ac568634ac58dcde08fa8f5ce554a84e46fd4 Mon Sep 17 00:00:00 2001 From: jprocter Date: Wed, 22 Aug 2007 16:15:06 +0000 Subject: [PATCH] Removed clientfile watcher elements in attempt to remove any locks after client is finalized (and formatting). git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@444 be28352e-c001-0410-b1a7-c7978e42abec --- .../vamsas/client/simpleclient/VamsasSession.java | 854 +++++++++++--------- 1 file changed, 453 insertions(+), 401 deletions(-) diff --git a/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java b/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java index 2ae181d..45766d4 100644 --- a/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java +++ b/src/uk/ac/vamsas/client/simpleclient/VamsasSession.java @@ -18,6 +18,7 @@ import uk.ac.vamsas.client.Events; import uk.ac.vamsas.client.IClient; import uk.ac.vamsas.client.SessionHandle; import uk.ac.vamsas.client.UserHandle; + /** * Does all the IO operations for a SimpleClient instance accessing * a SimpleClient vamsas session. @@ -75,59 +76,71 @@ public class VamsasSession { * they should finalise their vamsas datasets for * storing into a vamsas archive. */ - public static final String CLOSEANDSAVE_FILE="stored.log"; + public static final String CLOSEANDSAVE_FILE = "stored.log"; + /** * session file storing the last_stored_stat data */ - public static final String MODIFIEDDOC_FILE="modified"; + 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 ; - + private final int watchCycleCountBeforeLastClient = 1220; + /** * time between checking */ - public int WATCH_SLEEP=30; - + 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)); + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, + MODIFIEDDOC_FILE)); if (!laststored.clearFlag()) - log.warn("Unsaved flag was not cleared for "+sessionDir); + 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)); + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, + MODIFIEDDOC_FILE)); if (!laststored.setFlag()) - log.warn("Couldn't set the Unsaved flag for "+sessionDir); + 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)); + SessionFlagFile laststored = new SessionFlagFile(new File(sessionDir, + MODIFIEDDOC_FILE)); return laststored.checkFlag(); } + /** * log file location */ - public static final String SESSION_LOG="Log.txt"; + 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 */ @@ -141,102 +154,130 @@ public class VamsasSession { System.out.println(e.nextElement()); }*/ - - if (slog!= null ) { - File sessionLogFile = new File(this.sessionDir, SESSION_LOG); - slog.addAppender(new FileAppender(new PatternLayout("%-4r [%t] %-5p %c %x - %m%n"), sessionLogFile.getAbsolutePath(), true)); + + 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"; + + public static final String CLIENT_LIST = "Clients.obj"; + /** * holds the data */ - VamsasFile vamArchive; - public static final String VAMSAS_OBJ="VamDoc.jar"; - + VamsasFile vamArchive; + + public static final String VAMSAS_OBJ = "VamDoc.jar"; + /** * sets up the vamsas session files and watchers in sessionDir * @param sessionDir1 */ protected VamsasSession(File sessionDir1) throws IOException { - if (sessionDir1==null) + if (sessionDir1 == null) throw new Error("Null directory for VamsasSession."); if (sessionDir1.exists()) { - if (!sessionDir1.isDirectory() || !sessionDir1.canWrite() || !sessionDir1.canRead()) - throw new IOException("Cannot access '"+sessionDir1+"' as a read/writable Directory."); + if (!sessionDir1.isDirectory() || !sessionDir1.canWrite() + || !sessionDir1.canRead()) + throw new IOException("Cannot access '" + sessionDir1 + + "' as a read/writable Directory."); if (!checkSessionFiles(sessionDir1)) - log.warn("checkSessionFiles() returned false. Possible client implementation error"); - this.sessionDir = sessionDir1; + log + .warn("checkSessionFiles() returned false. Possible client implementation error"); + this.sessionDir = sessionDir1; initSessionObjects(); slog.debug("Initialising additional VamsasSession instance"); - log.debug("Attached to VamsasSession in "+sessionDir1); + log.debug("Attached to VamsasSession in " + sessionDir1); //} } else { // start from scratch if (!sessionDir1.mkdir()) - throw new IOException("Failed to make VamsasSession directory in "+sessionDir1); + throw new IOException("Failed to make VamsasSession directory in " + + sessionDir1); createSessionFiles(); initSessionObjects(); slog.debug("Session directory created."); - log.debug("Initialised VamsasSession in "+sessionDir1); + 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); + 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 (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 + log.debug("Created new ClientFile " + c_file); // don't care if this works or not if (!v_doc.exists() && v_doc.createNewFile()) - log.debug("Created new Vamsas Session Document File "+v_doc); + log.debug("Created new Vamsas Session Document File " + 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)); + 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() { + public FileWatcher getClientWatcher() { return new FileWatcher(clist.sessionFile); } + /** * make a new watcher object for the vamsas Document * @return new ClientFile watcher instance @@ -244,16 +285,20 @@ public class VamsasSession { public FileWatcher getDocWatcher() { return new FileWatcher(vamArchive.sessionFile); } - FileWatcher store_doc_file=null; - public ClientsFile storedocfile=null; + + 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)); + 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. @@ -261,44 +306,52 @@ public class VamsasSession { * @param user * @return */ - public void addStoreDocumentRequest(ClientHandle client, UserHandle user) throws IOException { + 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(); + 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()); + sfwfile.writeUTF(client.getClientUrn() + ":" + user.getFullName() + "@" + + user.getOrganization()); sfw.unlockFile(); - if (store_doc_file!=null) + if (store_doc_file != null) store_doc_file.setState(); - slog.info("FinalizeAppData request from "+user.getFullName()+" using "+client.getClientUrn()+""); + 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); + log.debug("Transferring vamsas data from " + archive + " to session:" + + vamArchive.sessionFile); SessionFile xtantdoc = new SessionFile(archive); vamArchive.updateFrom(null, xtantdoc); // LATER: decide if session archive provenance should be updated to reflect access. // TODO: soon! do a proper import objects from external file 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); + 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()) + if (extlock == null && !vamArchive.lockFile()) while (!vamArchive.lockFile()) - log.info("Trying to get lock for "+vamArchive.sessionFile); + 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(extlock, 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). @@ -306,10 +359,12 @@ public class VamsasSession { newdoc.unlockFile(); log.debug("Transfer complete."); } + /** - * extant archive IO handler - */ - VamsasArchive _va=null; + * 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. @@ -318,33 +373,36 @@ public class VamsasSession { */ protected VamsasArchive getVamsasDocument() throws IOException { // check we haven't already done this once - probably should be done by caller - if (_va!=null) + 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) + 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); + + 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) + if (_va != null) _va.closeArchive(); - _va=null; - if (vamArchive!=null) + _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 @@ -353,27 +411,27 @@ public class VamsasSession { * @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); + 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) - { + 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()); + log.debug("Adding client " + client.getClientHandle().getClientUrn()); getClientWatcherElement().haltWatch(); clist.addClient(client.getClientHandle()); - + log.debug("Added."); log.debug("Register Client as Active."); try { @@ -384,375 +442,369 @@ public class VamsasSession { //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 ; - + */ + private class AddClientWatchCallBack implements WatcherCallBack { + + private SimpleClient client; + /** - *Inits the handler with the client to check in the list + *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"); + 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()); + } - } - log.debug("isWatchEnable "+isWatchEnable); - return isWatchEnable; } + 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"); + } - -/** - * - * 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 - */ + 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(); - }; + 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); + + // getClientWatcherElement().setHandler(new RemoveClientWatchCallBack (client)); + // getClientWatcherElement().setTimeoutBeforeLastCycle(this.watchCycleCountBeforeLastClient); log.info("remove client from list"); - clist.clearList(); + 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) - { - log.debug("Raising request-to-save event"); - client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null); - client.evgen._raise(Events.SESSION_SHUTDOWN, null, client.getSessionHandle(), null); - } - try - { - log.debug("Attempting to release active client locks"); - client.releaseActiveClientFile(); - } - catch (IOException e) - { - log.error("error during active file client release"); - } - if (closeSession) - { - log.debug("Last active client: closing session"); - log.info("Closing session"); - getSessionManager().removeSession(client.getSessionHandle()); - } + //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) { + log.debug("Raising request-to-save event"); + client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client, null); + client.evgen._raise(Events.SESSION_SHUTDOWN, null, client + .getSessionHandle(), null); + } + //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"); + getSessionManager().removeSession(client.getSessionHandle()); } } - - - private boolean isLastActiveClient(SimpleClient client) - { + + /** + * 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; + 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; } - - 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); - } - } + 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; + + } 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 class RemoveClientWatchCallBack implements WatcherCallBack { + + private SimpleClient client; + private boolean manualCheckOfClientCount = false; + /** - *Inits the handler with the client to check in the list + *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 ) - { - + 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(); - - 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("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; + 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("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()); - } - + 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(SessionHandle sessionHandle) - { - getSessionManager().removeSession(sessionHandle); - log.debug("Session removed"); - } -/** - * @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) { - + private void closeSession(SessionHandle sessionHandle) { + getSessionManager().removeSession(sessionHandle); + log.debug("Session removed"); } - return storedocfile; -} -ClientSessionFileWatcherElement clistWatchElement=null; -public ClientSessionFileWatcherElement getClientWatcherElement() { - if (clistWatchElement==null) { - clistWatchElement=new ClientSessionFileWatcherElement(clist,null); + /** + * @return the sessionManager + */ + protected SimpleSessionManager getSessionManager() { + return sessionManager; } - return clistWatchElement; -} -/** - * writes a vector of vorba Ids to the session. - * @param modObjects -public void setModObjectList(Vector modObjects) { - log.debug("Writing "+modObjects.size()+" ids to ModObjectList"); - // TODO Auto-generated method stub -} -** - * get current list of modified objects. - * @return null or Vector of objects - * -public Vector getModObjectList() { - log.debug("Reading modObjectList"); - return null; -} -*/ -} + /** + * @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; + } + /** + * writes a vector of vorba Ids to the session. + * @param modObjects + public void setModObjectList(Vector modObjects) { + log.debug("Writing "+modObjects.size()+" ids to ModObjectList"); + // TODO Auto-generated method stub + } + ** + * get current list of modified objects. + * @return null or Vector of objects + * + public Vector getModObjectList() { + log.debug("Reading modObjectList"); + return null; + } + */ +} -- 1.7.10.2