--- /dev/null
+
+package uk.ac.vamsas.client.simpleclient;
+
+
+public class ClientSessionFileWatcherElement extends SessionFileWatcherElement {
+
+ private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(VamsasFileWatcherElement.class);
+
+ /**
+ * count of watch cycle before considering there is no other active client.
+ */
+ private int timeoutBeforeLastCycle = -1;
+
+ private boolean isTimeOutEnable = false;
+
+ /**
+ * @param watcher
+ * @param handler
+ */
+ public ClientSessionFileWatcherElement(SessionFile watcher,
+ WatcherCallBack handler) {
+ super(watcher, handler);
+ }
+
+ /**
+ * @param watcher
+ * @param handler
+ * @param enableWatching
+ */
+ public ClientSessionFileWatcherElement(SessionFile watcher,
+ WatcherCallBack handler, boolean enableWatching) {
+ super(watcher, handler, enableWatching);
+ }
+
+ /**
+ * @see uk.ac.vamsas.client.simpleclient.WatcherElement#doWatch()
+ * * @return true if the handler was called for a changeEvent
+ */
+ public boolean doWatch()
+ {
+ if (!watchForChange || handler==null)
+ { //log.debug("!watchForChange || handler==null");
+ return false;
+ }
+ if (watcher==null)
+ initWatch(); // somehow not done the first time
+ handlerCalled=false;
+ Lock doclock=null;
+ try
+ {
+ doclock=watcher.getChangedState();
+ }
+ catch (Exception e) {
+ log.error("Whilst watching "+watcher.getSubject(), e);
+ }
+ if (doclock==null)
+ {//no change detected
+ this.cycleCountSinceModif ++;
+ if (this.isTimeOutEnable && cycleCountSinceModif > timeoutBeforeLastCycle)
+ {
+ if(this.handler != null )
+ synchronized (this.handler)
+ {
+ this.callHandler(doclock);
+ }
+ }
+ //log.debug("no modification");
+ return false;
+ }
+ this.cycleCountSinceModif =0; //change detected
+ if(this.handler != null )
+ synchronized (this.handler)
+ {
+ this.callHandler(doclock);
+ }
+
+ return true;
+ }
+
+
+ /**
+ * count of cycles since last modification on the file
+ */
+ protected int cycleCountSinceModif =0;
+
+ /**
+ * resets count of watch cycles (default value : 0)
+ *
+ */
+ protected void resetCycleCount ()
+ {
+ this.cycleCountSinceModif = 0;
+ }
+
+ /**
+ * Increases the count of cycles
+ *
+ */
+ protected void increaseCycleCount ()
+ {
+ this.cycleCountSinceModif ++;
+ }
+
+ /**
+ * Enable the time out if the timeout is greater than zero
+ * @param timeoutBeforeLastCycle the timeoutBeforeLastCycle to set
+ */
+ public void setTimeoutBeforeLastCycle(int timeoutBeforeLastCycle) {
+
+ this.timeoutBeforeLastCycle = timeoutBeforeLastCycle;
+ if (this.timeoutBeforeLastCycle>0)
+ isTimeOutEnable = true;
+ }
+
+ /**
+ * Disables the checking on the count of cycles
+ *
+ */
+ public void disableCycleTimeOut ()
+ {
+ this.isTimeOutEnable = false;
+ }
+}
*/
package uk.ac.vamsas.client.simpleclient;
-import java.beans.EventHandler;
-import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.util.Hashtable;
import java.util.Vector;
import uk.ac.vamsas.client.SessionHandle;
import uk.ac.vamsas.client.UserHandle;
import uk.ac.vamsas.client.picking.IPickManager;
-import uk.ac.vamsas.objects.core.ApplicationData;
import uk.ac.vamsas.objects.core.Entry;
-import uk.ac.vamsas.objects.core.LockFile;
import uk.ac.vamsas.objects.core.VamsasDocument;
-import uk.ac.vamsas.objects.utils.AppDataReference;
import uk.ac.vamsas.objects.utils.ProvenanceStuff;
-import uk.ac.vamsas.objects.utils.document.VersionEntries;
/**
* @author jimp
// deregister listeners.
log.debug("Stopping pickManager");
haltPickmanager();
- log.debug("Stopping EventGenerator..");
- evgen.stopWatching();
- SimpleClient.log.debug("EventGenerator halted.");
+
log.debug("Deregistering Client");
_session.removeClient(this);
+ //log.debug("Stopping EventGenerator..");
+ //evgen.stopWatching();
+ SimpleClient.log.debug("EventGenerator halted.");
+ this.cdocument = null;
log.debug("finalization Complete.");
}
// Events.DOCUMENT_FINALIZEAPPDATA
try {
_session.writeVamsasDocument(location, vamlock);
- _session.clearUnsavedFlag();
+ _session.clearUnsavedFlag();
} catch (Exception e) {
log.warn("Exception whilst trying to store document in "+location,e);
}
-
vamlock.release();
}
public void importDocument(File location) {
// TODO LATER: implement SimpleClient.importDocument()
log.error("importDocument is not yet implemented for a SimpleClient Session.");
+
+ /* try {
+ this._session.setVamsasDocument(location);
+ } catch (IOException e) {
+ log.error("importDocument failed.");
+ }*/
}
public IObjectUpdate getUpdateHandler(Class rootObject) {
import java.io.File;
import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
import java.io.RandomAccessFile;
-import java.io.Writer;
-import java.util.Enumeration;
-import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.log4j.Appender;
-import org.apache.log4j.Logger;
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.IClient;
import uk.ac.vamsas.client.UserHandle;
/**
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 = 2 ;
+
+ /**
+ * time between checking
+ */
+ public int WATCH_SLEEP=30;
+
+ /**
* called to clear update flag after a successful offline storage event
*/
protected void clearUnsavedFlag() {
clist.addClient(client.getClientHandle());
getClientWatcherElement().enableWatch();
log.debug("Added.");
+ log.debug("Register Client as Active.");
+
+ //tracks modification to the client list and readds client to the list
+ getClientWatcherElement().setHandler(new AddClientWatchCallBack(client));
}
}
+ /**
+ * 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 IClient client ;
+
+ /**
+ *Inits the handler with the client to check in the list
+ * @param client client to monitor in the client list
+ */
+ protected AddClientWatchCallBack (IClient 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 (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());
+ }
+ } else
+ if (! found)
+ {
+ if( log.isDebugEnabled())
+ log.debug("the client has not been found in the list. Adding it again :"+cl);
+ addClient(client);
+ }
+
+ }
+
+ return isWatchEnable;
+ }
+ }
+
/**
*
* removes a client from the current session
*
* @param client client to remove
*/
- protected void removeClient(IClient client)
+ protected void removeClient(SimpleClient client)//IClient client)
{
if (client == null)
{
log.error("Null client passed to removeClient");
return;
}
- SessionFileWatcherElement cwe=getClientWatcherElement();
+ ClientSessionFileWatcherElement cwe=getClientWatcherElement();
if (cwe!=null && cwe.isWatchEnabled()) {
cwe.haltWatch();
};
- clist.removeClient(client.getClientHandle(),null);
+ //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");
+ clist.clearList();
+ if (cwe!=null) {
+ cwe.enableWatch();
+ }
+
+
+
+ /*clist.removeClient(client.getClientHandle(),null);
if (this.clist.retrieveClientList() == null|| this.clist.retrieveClientList().length<1)
{//assume it is the last client has been removed shutting down session
slog.info("last client removed: removing session");
this.getSessionManager().removeSession(client.getSessionHandle());
}
else
- {
- int active=clist.retrieveClientList().length;
- log.debug("Still "+active+" active clients");
- slog.info("Still "+active+" active clients");
- }
- if (cwe!=null) {
- cwe.enableWatch();
- }
+ {
+ int active=clist.retrieveClientList().length;
+ log.debug("Still "+active+" active clients");
+ slog.info("Still "+active+" active clients");
+ }*/
+
}
+
+ /**
+ * 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 ;
+
+ /**
+ *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)
+ {
+ // boolean isWatchEnable = watcher.isWatchEnabled();
+ if (client != null)
+ {
+
+ //checks if the client is not already in the lists
+ ClientHandle[] cl = clist.retrieveClientList(lock);//clist.retrieveClientList();
+// ask to the client to cpoy application data into the document
+ client.evgen._raise(Events.DOCUMENT_FINALIZEAPPDATA, null, client,null);
+
+ if(cl == null || cl.length<1 )
+ {//no client has registered as active
+ //the client is the last one, so close current session
+ log.info("last client removed: closing session");
+
+// close document
+ client.evgen._raise(Events.DOCUMENT_REQUESTTOCLOSE, null, client,null);
+ log.debug("close document request done");
+
+ getSessionManager().removeSession(client.getSessionHandle());
+ log.debug("Session removed");
+ }
+ 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);
+
+ }
+ // watcher.haltWatch();
+ log.debug("Stopping EventGenerator..");
+ client.evgen.stopWatching();
+
+
+ }
+ watcher.setHandler(null);//Do not check if the client is the last client. watcher will shutdown anyway
+
+ return false;
+ }
+ }
+
/**
* @return the sessionManager
*/
}
return storedocfile;
}
-SessionFileWatcherElement clistWatchElement=null;
-public SessionFileWatcherElement getClientWatcherElement() {
+
+ClientSessionFileWatcherElement clistWatchElement=null;
+public ClientSessionFileWatcherElement getClientWatcherElement() {
if (clistWatchElement==null) {
- clistWatchElement=new SessionFileWatcherElement(clist,null);
+ clistWatchElement=new ClientSessionFileWatcherElement(clist,null);
}
return clistWatchElement;
}