todo for importing stored session as a new session
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / SimpleClientFactory.java
index cd05e26..8cc74a1 100644 (file)
-/*
-* VAMSAS Project
-*
-
-* 
-* Dec 13, 2006 
-*
-*/
+/**
+ * 
+ * VAMSAS Project
+ *
+ * 
+ * Dec 13, 2006 
+ *
+ */
+
 package uk.ac.vamsas.client.simpleclient;
 
 import java.io.File;
 
 import java.io.IOException;
-
+import java.net.MalformedURLException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.vamsas.client.ClientHandle;
-import org.vamsas.client.IClient;
-import org.vamsas.client.IClientFactory;
-import org.vamsas.client.InvalidSessionUrnException;
-import org.vamsas.client.NoDefaultSessionException;
-import org.vamsas.client.SessionHandle;
-import org.vamsas.client.UserHandle;
+
+import uk.ac.vamsas.client.ClientHandle;
+import uk.ac.vamsas.client.IClient;
+import uk.ac.vamsas.client.IClientFactory;
+import uk.ac.vamsas.client.InvalidSessionUrnException;
+import uk.ac.vamsas.client.NoDefaultSessionException;
+import uk.ac.vamsas.client.SessionHandle;
+import uk.ac.vamsas.client.UserHandle;
 
 /**
  * 
- * 
+ * creates a session arena in the user home directory under .vamsas. Each
+ * session has its own subdirectory.
  */
 public class SimpleClientFactory implements IClientFactory {
 
   private static Log log = LogFactory.getLog(SimpleClientFactory.class);
 
   private File sessionArena = null;
-  
+
   private String vamsasSubdirectoryName = ".vamsas";
-  
-  private SessionsFile sessionFile = null;
-  private static final String SESSION_LIST="sessions.obj";
-  
-  //private   String[] currentlyAvailableDessions = null; 
-  
+
+  private SimpleSessionManager sessionManager = null;
+
+  private static final String SESSION_LIST = "sessions.obj";
+
+  // private String[] currentlyAvailableDessions = null;
+
   /**
    * default constructor - called by CreateClientFactory only.
-   *
-   *Inits the sessionarena to the directory .vamsas of the user home directory. 
-   *
+   * 
+   * Inits the sessionarena to the directory .vamsas of the user home directory.
+   * 
    */
-  public SimpleClientFactory() throws IOException
-  {
-   // sessionArena
-    
-    //retrieves user home directory
+  public SimpleClientFactory() throws IOException {
+    // sessionArena
+
+    // retrieves user home directory
     String userHomeDirectory = System.getProperty("user.home");
-    if (userHomeDirectory == null || userHomeDirectory.length()<1)
-      {
-        new IOException("Unable to detect user home directory");
-      }
-    String sessionArenaPath =  userHomeDirectory.concat(File.separator.concat(this.vamsasSubdirectoryName));
-    
+    if (userHomeDirectory == null || userHomeDirectory.length() < 1) {
+      new IOException("Unable to detect user home directory");
+    }
+    String sessionArenaPath = userHomeDirectory.concat(File.separator
+        .concat(this.vamsasSubdirectoryName));
+
     this.initSessionArena(sessionArenaPath);
-    this.initFactoryObjects();
+    // this.initFactoryObjects();
   }
-  
-  
+
   /**
-   * Create a client factory that works with sessions at the given
-   * path.
-   * @param path path to directory called  session arena, where will be created session directories and session files.
+   * Create a client factory that works with sessions at the given path.
+   * 
+   * @param path
+   *          path to directory called session arena, where will be created
+   *          session directories and session files.
    */
-  public SimpleClientFactory(String path) throws IOException
-  {
+  public SimpleClientFactory(String path) throws IOException {
     this.initSessionArena(path);
   }
+
   /**
-   * Inits sessionArena to a given path.
-   * checks if path is valid.
+   * Inits sessionArena to a given path. checks if path is valid.
    * 
-   * @param path path to a directory to use 
-   * @throws IOException if the path is incorrect
+   * @param path
+   *          path to a directory to use
+   * @throws IOException
+   *           if the path is incorrect
    */
-  private void  initSessionArena (String path) throws IOException
-  {
+  private void initSessionArena(String path) throws IOException {
     // Check path is valid and read/writeable.
-    File arenaFile = new File (path);
-    if (!arenaFile.exists())
-    {
-      if (! arenaFile.mkdirs())
-      {
+    File arenaFile = new File(path);
+    if (!arenaFile.exists()) {
+      if (!arenaFile.mkdirs()) {
         this.sessionArena = null;
-        throw(new IOException("Unable to create a directory called "+path));
+        throw (new IOException("Unable to create a directory called " + path));
       }
     }
-    if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead() && arenaFile.canWrite()) 
-      {
-        this.sessionArena = arenaFile;
-      } 
-    else
-      {
+    if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead()
+        && arenaFile.canWrite()) {
+      this.sessionArena = arenaFile;
+    } else {
       this.sessionArena = null;
-        throw(new IOException("Cannot read and write to a directory called "+path));
-      }
-  }
-  
-  /**
-   * construct SessionFile objects and watchers for each
-   */
-  private void initFactoryObjects() throws IOException {
-    if (this.sessionFile!=null )
-      throw new IOException("initFactoryObjects called for initialised ClientFactory object.");
-    this.sessionFile = new SessionsFile(new File(this.sessionArena,SESSION_LIST));
-
-  }
-  /**
-   * @see org.vamsas.client.IClientFactory#getCurrentSessions()
-   */
-  public String[] getCurrentSessions() 
-  { 
-    String[] sessions = null;
-    if (this.sessionFile!=null )
-      {
-        SessionHandle[] sessionHandles =  this.sessionFile.retrieveSessionsList();
-        if (sessionHandles != null)
-          {
-            sessions = new String[sessionHandles.length];
-            for (int i = sessionHandles.length -1; i > 0; i--)
-              {
-                SessionHandle sessionHandle = sessionHandles[i];
-                sessions [i] = sessionHandle.getSessionUrn();
-              }
-          }
-      }
-    return sessions;
-  }
-  
-  
-  private void discoverSession()
-  {
-   
+      throw (new IOException("Cannot read and write to a directory called "
+          + path));
+    }
   }
 
   /**
-   * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle)
+   * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle)
    * 
-   * Creates a IClient object, using default UserHandle with system variables:"user.name" or "USERNAME")),
-            "host.name" or "HOSTNAME" 
+   * Creates a IClient object, using default UserHandle with system
+   * variables:"user.name" or "USERNAME")), "host.name" or "HOSTNAME"
    */
   public IClient getIClient(ClientHandle applicationHandle)
       throws NoDefaultSessionException {
-    
+    // create a new session
+    // register new ClientHandle in session
+    // create SimpleClient instance
     return this.getIClient(applicationHandle, (UserHandle) null);
   }
 
   /**
-   * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, java.lang.String)
+   * the URN should be something like simpleclient:FILEPATH URL encoded
+   * 
+   * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
+   *      java.lang.String)
    */
   public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) {
-    // TODO Auto-generated method stub
-    return null;
+    // locate session from Urn
+    // check that clientHandle is unique (with default user) - if not update the
+    // clientHandle urn to make it unique.
+    // wait for lock and attach to session
+    // create SimpleClient instance
+    log.debug("Trying to create session with URN " + sessionUrn);
+    return this.getIClient(applicationHandle, null, sessionUrn);
+
+  }
+
+  private File convertSessionUrnToFile(String sessionUrn)
+      throws InvalidSessionUrnException {
+    if (sessionUrn == null) {
+      log.debug("Incorrect URN: can not open session.");
+      throw new InvalidSessionUrnException();
+    }
+
+    SessionUrn urn = new SessionUrn(sessionUrn);
+    return urn.asFile();
+
   }
 
   /**
-   * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, org.vamsas.client.UserHandle, java.lang.String)
+   * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
+   *      uk.ac.vamsas.client.UserHandle, java.lang.String)
    */
   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId,
       String sessionUrn) {
-    // TODO Auto-generated method stub
-    return null;
+    // locate session from Urn
+    // check Uniqueness of user + ClientHandle in the session. Update
+    // clientHandle urn accordingly.
+    // wait for lock, attach to session
+    // create client instance
+    IClient client = null;
+
+    // TODO: implement 'opening stored session' opening mechanism
+    // 1. existing session document URL is vdoc://... ?
+    // 2. check for sessionUrn being of this form.
+    // 3. if it is - locate the file and pass to new VamsasSession
+
+    try {
+      File sessionDirectory = this.convertSessionUrnToFile(sessionUrn);
+      // create session
+      log
+          .debug("found session directory "
+              + sessionDirectory.getAbsolutePath());
+      VamsasSession vamsasSession = new VamsasSession(sessionDirectory);
+      
+      /*
+       * if (userId == null) { //create a default userHandle //with current OS
+       * user and hostname userId = new UserHandle(System.getProperty("user.name",
+       * System.getProperty("USERNAME","Joe Doe")),
+       * System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown")
+       * ));// clientName, clientVersion, sessionPath); }
+       * 
+       * 
+       * //create simple client client = new SimpleClient(userId,
+       * applicationHandle, vamsasSession);
+       */
+      client = this.initClient(sessionDirectory, userId, applicationHandle);
+    } catch (MalformedURLException e) {
+      log.error("error while creating new IClient: incorrect session urn", e);
+      client = null;
+
+    } catch (InvalidSessionUrnException e) {
+      log.error("error while creating new IClient: incorrect session urn", e);
+      client = null;
+    } catch (IOException e) {
+      log.error("error while creating new IClient: file access error", e);
+      client = null;
+    }
+    return client;
+  }
+
+  private IClient initClient(File sessdir, UserHandle userId,
+      ClientHandle clientHandle) throws IOException, InvalidSessionUrnException {
+    IClient client = null;
+    // create session
+    VamsasSession vamsasSession = new VamsasSession(sessdir);
+
+    this.getSessionManager().addSession(
+        new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()));
+    if (userId == null) {
+      // create a default userHandle
+      // userId = new UserHandle(System.getProperty("user.name",
+      // System.getProperty("USERNAME","Joe Doe")),
+      // System.getProperty("host.name",System.getProperty("HOSTNAME",
+      // "Unknown") ));// clientName, clientVersion, sessionPath);
+      userId = new UserHandle(null, null);
+    }
+
+    // FullName and organisation should not be null (otherwise UserHandle equals
+    // method raises an java.lang.NullPointerException )
+    // use current OS user and hostname, if null
+    if (userId.getFullName() == null) {
+      userId.setFullName(System.getProperty("user.name", System.getProperty(
+          "USERNAME", "Joe Doe")));
+    }
+
+    if (userId.getOrganization() == null) {
+      userId.setOrganization(System.getProperty("host.name", System
+          .getProperty("HOSTNAME", "Unknown")));
+    }
+
+    if (clientHandle == null)
+      clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
+    else {
+      if (clientHandle.getClientName() == null) {
+        clientHandle.setClientName("SimpleVamsasClientApp");
+      }
+      if (clientHandle.getVersion() == null) {
+        clientHandle.setVersion("0.1");
+      }
+    }
+
+    // create simple client
+    client = new SimpleClient(userId, clientHandle, vamsasSession);
+    vamsasSession.addClient((SimpleClient) client);
+    vamsasSession.setSessionManager(this.getSessionManager());
+    return client;
   }
 
   /**
-   * @see org.vamsas.client.IClientFactory#getIClient(org.vamsas.client.ClientHandle, org.vamsas.client.UserHandle)
+   * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
+   *      uk.ac.vamsas.client.UserHandle)
    */
   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId)
       throws NoDefaultSessionException {
-    SimpleClient client = null;
-    if (this.sessionArena==null)
-      throw new Error("Improperly initialised SimpleClientFactory object - null sessionArena.");
-    
-    ClientHandle clientHandle =applicationHandle;
-    //create default clientHandle with "SimpleVamsasClientApp","0.1",
+    // create new session
+    // register SimpleClient and UserHandles in session
+    // create client instance
+    IClient client = null;
+    if (this.sessionArena == null)
+      throw new Error(
+          "Improperly initialised SimpleClientFactory object - null sessionArena.");
+
+    ClientHandle clientHandle = applicationHandle;
+    // create default clientHandle with "SimpleVamsasClientApp","0.1",
     if (clientHandle == null)
-     clientHandle = new ClientHandle("SimpleVamsasClientApp","0.1");
-    
-    //check if any available session(s)
-    String[] availableSessions = this.getCurrentSessions();
-    if (availableSessions != null) 
-      {//there are available sessions
-        if (availableSessions.length>1)
-          {//more than one session if available... can not choose
-          
-          //represents list of session as String
-            StringBuffer sessionURNs = new StringBuffer("");
-            for (int i = 0; i< availableSessions.length ; i++)
-              {
-                sessionURNs.append(availableSessions[i]+" ");
-              }
-            throw new  NoDefaultSessionException("Several sessions available, please pick one: "+sessionURNs);
-          }
-      
-        //check if only one session available. if yes, open it
-        if (availableSessions.length == 1)
-          {
-          //only one session available, open it.
-            return this.getIClient(clientHandle,  availableSessions[0]);
-          }
+      clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
+    else {
+      if (clientHandle.getClientName() == null) {
+        clientHandle.setClientName("SimpleVamsasClientApp");
       }
-    //no session available  - create a new one
-    
-    
-    try 
-      {
-        //create sessionDirectory
-        File sessdir = File.createTempFile("sess", ".simpleclient", this.sessionArena);
-        log.debug("Creating new session  directory");
-       if (!(sessdir.delete() && sessdir.mkdir()))
-          throw new IOException("Could not make session directory "+sessdir);
-      //create session
-        VamsasSession vamsasSession = new VamsasSession(sessdir);
-      
-        this.getSessionFile().addSession(new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()), false);
-        if (userId == null)
-          {
-      //create a default userHandle
-      //with current OS user and hostname
-            userId = new UserHandle(System.getProperty("user.name", System.getProperty("USERNAME","Joe Doe")),
-              System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown") ));// clientName, clientVersion,  sessionPath);
-          }
-     
-      
-      //create simple client
-         client = new SimpleClient(userId,  clientHandle,  vamsasSession);
-      } 
-    catch (IOException e) 
-      {
-        log.error("error while creating new IClient",e);
+
+      if (clientHandle.getVersion() == null) {
+        clientHandle.setVersion("0.1");
       }
-    catch (InvalidSessionUrnException e) 
-      {
-        log.error("Unable to create new IClient. The session urn is incorrect ",e);
+    }
+    // check if any available session(s)
+    String[] availableSessions = this.getCurrentSessions();
+    if (availableSessions != null) {// there are available sessions
+      if (availableSessions.length > 1) {// more than one session if available... can not choose
+
+        // represents list of session as String
+        StringBuffer sessionURNs = new StringBuffer("");
+        for (int i = 0; i < availableSessions.length; i++) {
+          sessionURNs.append(availableSessions[i] + " ");
+        }
+        throw new NoDefaultSessionException(
+            "Several sessions available, please pick one: " + sessionURNs);
       }
-   
-      return client;
+
+      // check if only one session available. if yes, open it
+      if (availableSessions.length == 1) {
+        // only one session available, open it.
+        return this.getIClient(clientHandle, availableSessions[0]);
+      } else {
+        log.debug("No active session found");
+      }
+    }
+    // no session available - create a new one
+
+    client = clientInNewSession(userId, clientHandle);
+    return client;
   }
 
+  /**
+   * 
+   * @param userId
+   * @param clientHandle
+   * @return
+   */
+  private IClient clientInNewSession(UserHandle userId,
+      ClientHandle clientHandle) {
+
+    IClient client = null;
+    try {
+      // create sessionDirectory
+      File sessdir = File.createTempFile("sess", ".simpleclient",
+          this.sessionArena);
+      log.debug("Creating new session  directory");
+      if (!(sessdir.delete() && sessdir.mkdir()))
+        throw new IOException("Could not make session directory " + sessdir);
+      client = this.initClient(sessdir, userId, clientHandle);
+    } catch (IOException e) {
+      log.error("error while creating new IClient", e);
+    } catch (InvalidSessionUrnException e) {
+      log.error("Unable to create new IClient. The session urn is incorrect ",
+          e);
+    }
+
+    return client;
+  }
+
+  /**
+   * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
+   */
+  public String[] getCurrentSessions() {
+    String[] sessions = null;
+    try {
+      sessions = this.getSessionManager().getCurrentSessions();
+    } catch (IOException e) {
+      log.error("Unable to get available sessions", e);
+      sessions = null;
+    }
+    return sessions;
+  }
 
   /**
    * @return the sessionFile
    */
-  private SessionsFile getSessionFile()  throws IOException
-    {
-      if (this.sessionFile == null)
-        {
-          this.sessionFile = new SessionsFile( new File (this.sessionArena, SESSION_LIST));
-        }
-      return this.sessionFile;
+  private SimpleSessionManager getSessionManager() throws IOException {
+    if (this.sessionManager == null) {
+      this.sessionManager = new SimpleSessionManager(new File(
+          this.sessionArena, SESSION_LIST));
     }
+    return this.sessionManager;
+  }
 
-  
+  public IClient getNewSessionIClient(ClientHandle applicationHandle) {
+    return clientInNewSession(null, applicationHandle);
+  }
+
+  public IClient getNewSessionIClient(ClientHandle applicationHandle,
+      UserHandle userId) {
+    return clientInNewSession(userId, applicationHandle);
+  }
 
 }