verson 0.2 LGPL licensed source and jars
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / SimpleClientFactory.java
index d709f5d..3d9a534 100644 (file)
@@ -1,12 +1,24 @@
-/**
+/*
+ * This file is part of the Vamsas Client version 0.2. 
+ * Copyright 2010 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.
  * 
- * VAMSAS Project
- *
+ * 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.
  * 
- * Dec 13, 2006 
- *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 package uk.ac.vamsas.client.simpleclient;
 
 import java.io.File;
@@ -20,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
 import uk.ac.vamsas.client.ClientHandle;
 import uk.ac.vamsas.client.IClient;
 import uk.ac.vamsas.client.IClientFactory;
+import uk.ac.vamsas.client.InvalidSessionDocumentException;
 import uk.ac.vamsas.client.InvalidSessionUrnException;
 import uk.ac.vamsas.client.NoDefaultSessionException;
 import uk.ac.vamsas.client.SessionHandle;
@@ -106,8 +119,8 @@ public class SimpleClientFactory implements IClientFactory {
   /**
    * @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 {
@@ -134,15 +147,40 @@ public class SimpleClientFactory implements IClientFactory {
 
   }
 
+  /**
+   * try to locate the sessionUrn within the simpleclient session arena
+   * @param sessionUrn
+   * @return
+   * @throws InvalidSessionUrnException
+   */
   private File convertSessionUrnToFile(String sessionUrn)
       throws InvalidSessionUrnException {
     if (sessionUrn == null) {
       log.debug("Incorrect URN: can not open session.");
-      throw new InvalidSessionUrnException();
+      throw new InvalidSessionUrnException("SessionUrn was null");
     }
 
     SessionUrn urn = new SessionUrn(sessionUrn);
-    return urn.asFile();
+    SimpleSessionHandle[] sh = null;
+    try {
+      sh = getSessionManager().getSessionFor(urn);
+    } catch (IOException e)
+    {
+      log.warn("Ignored IO Exception when trying to access sessionlist.",e);
+    }
+    File sesfile = null;
+    if (sh!=null)
+    {
+      if (sh.length==1)
+      {
+        sesfile = new File(sh[0].getPhysLoc());
+        sh[0] = null;
+      } else {
+        log.error("Raising exception for multiple session files corresponding to single URN (was : "+sessionUrn+")");
+        throw new InvalidSessionUrnException("IMPLEMENTATION ERROR: Multiple session files available for URN ("+sessionUrn+")");
+      }
+    }
+    return sesfile;
 
   }
 
@@ -159,8 +197,13 @@ public class SimpleClientFactory implements IClientFactory {
     // 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);
+      File sessionDirectory = convertSessionUrnToFile(sessionUrn);
       // create session
       log
           .debug("found session directory "
@@ -169,20 +212,26 @@ public class SimpleClientFactory implements IClientFactory {
 
       /*
        * if (userId == null) { //create a default userHandle //with current OS
-       * user and hostname userId = new UserHandle(System.getProperty("user.name",
+       * 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); }
+       * 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);
+      client = this.initClient(sessionDirectory, userId, applicationHandle,
+          null,null);
     } catch (MalformedURLException e) {
       log.error("error while creating new IClient: incorrect session urn", e);
       client = null;
-
+    } catch (InvalidSessionDocumentException e) {
+      log
+          .error("error while creating new IClient: invalid session document",
+              e);
+      client = null;
     } catch (InvalidSessionUrnException e) {
       log.error("error while creating new IClient: incorrect session urn", e);
       client = null;
@@ -193,14 +242,37 @@ public class SimpleClientFactory implements IClientFactory {
     return client;
   }
 
+  /**
+   * initialise the vamsas session state and create a SimpleClient object to
+   * connect to it
+   * 
+   * @param sessdir
+   *          newly created or existing session directory
+   * @param userId
+   * @param clientHandle
+   * @param vamsasDocument
+   *          null or a document to pass to SimpleCLient to write into the
+   *          sessdir
+   * @param preferredName - name to use instead of vamsasDocument path when creating new session URN 
+   * @return the client
+   * @throws IOException
+   *           if there are problems in session or client creation or if the
+   *           session already has a vamsasDocument
+   * @throws InvalidSessionUrnException
+   *           for a malformed sessdir
+   */
   private IClient initClient(File sessdir, UserHandle userId,
-      ClientHandle clientHandle) throws IOException, InvalidSessionUrnException {
+      ClientHandle clientHandle, File vamsasDocument, String preferredName) throws IOException,
+      InvalidSessionUrnException, InvalidSessionDocumentException {
     IClient client = null;
     // create session
-    VamsasSession vamsasSession = new VamsasSession(sessdir);
-
-    this.getSessionManager().addSession(
-        new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()));
+    VamsasSession vamsasSession = null;
+    if (vamsasDocument == null) {
+      vamsasSession = new VamsasSession(sessdir);
+    } else {
+      vamsasSession = new VamsasSession(sessdir, vamsasDocument,preferredName);
+    }
+    getSessionManager().addSession(vamsasSession.getSessionUrn());
     if (userId == null) {
       // create a default userHandle
       // userId = new UserHandle(System.getProperty("user.name",
@@ -271,7 +343,8 @@ public class SimpleClientFactory implements IClientFactory {
     // 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
+      if (availableSessions.length > 1) {// more than one session if
+                                         // available... can not choose
 
         // represents list of session as String
         StringBuffer sessionURNs = new StringBuffer("");
@@ -291,34 +364,67 @@ public class SimpleClientFactory implements IClientFactory {
       }
     }
     // no session available - create a new one
-
-    client = clientInNewSession(userId, clientHandle);
+    try {
+      client = clientInNewSession(userId, clientHandle, null,null);
+    } catch (Exception e) {
+      throw new Error(
+          "IMPLEMENTATION ERROR: unexpected exception when creating a new session to connect to.",
+          e);
+    }
     return client;
   }
 
   /**
+   * create a new session directory and possibly import an existing document
+   * into it
    * 
    * @param userId
    * @param clientHandle
-   * @return
+   * @param vamsasDocument
+   *          null or a document file to copy into the new session
+   *          @param preferredName - name to be used as base for the new session URN
+   * @return null or a valid IClient instance
    */
   private IClient clientInNewSession(UserHandle userId,
-      ClientHandle clientHandle) {
+      ClientHandle clientHandle, File vamsasDocument, String preferredName)
+      throws InvalidSessionDocumentException, InvalidSessionUrnException {
 
     IClient client = null;
     try {
+      // try and make a friendly session name
+      String sesspref = "";
+      if (vamsasDocument != null) {
+        if (preferredName!=null)
+        {
+          sesspref = preferredName.replaceAll(
+              "([^-A-Za-z0-9]|\\.vdj)", "");
+        } else {
+          sesspref = vamsasDocument.getName().replaceAll(
+              "([^-A-Za-z0-9]|\\.vdj)", "");
+        }
+      }
+      sesspref += (new java.util.Date()).toString().replaceAll("[^-A-Za-z0-9]",
+          "_");
       // create sessionDirectory
-      File sessdir = File.createTempFile("sess", ".simpleclient",
-          this.sessionArena);
+      File sessdir = new File(sessionArena, sesspref + ".simpleclient");
+      if (sessdir.exists()) {
+        // make a unique session name
+        sessdir = File.createTempFile(sesspref, ".simpleclient", sessionArena);
+      } else {
+        if (!sessdir.createNewFile()) {
+          throw new Error(
+              "VAMSAS Implementation error : sesspref friendly session name is invalid on this platform - please tell the authors!");
+        }
+      }
       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);
+      client = initClient(sessdir, userId, clientHandle, vamsasDocument, preferredName);
     } 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);
+      log.error(
+          "Unable to create new IClient. The new session urn is malformed.", e);
     }
 
     return client;
@@ -350,12 +456,77 @@ public class SimpleClientFactory implements IClientFactory {
   }
 
   public IClient getNewSessionIClient(ClientHandle applicationHandle) {
-    return clientInNewSession(null, applicationHandle);
+    try {
+      return clientInNewSession(null, applicationHandle, null,null);
+    } catch (Exception e) {
+      log.error("Failed to create new session for app with default user.", e);
+    }
+    return null;
   }
 
   public IClient getNewSessionIClient(ClientHandle applicationHandle,
       UserHandle userId) {
-    return clientInNewSession(userId, applicationHandle);
+    try {
+      return clientInNewSession(userId, applicationHandle, null,null);
+    } catch (Exception e) {
+      log.error("Failed to create new session for app and user.", e);
+    }
+    return null;
+  }
+
+  private void checkImportedDocument(File vamsasDocument)
+      throws InvalidSessionDocumentException {
+    if (!vamsasDocument.exists()) {
+      throw new InvalidSessionDocumentException("File " + vamsasDocument
+          + " does not exist");
+    }
+    if (!vamsasDocument.canRead()) {
+      throw new InvalidSessionDocumentException("File " + vamsasDocument
+          + " does not exist");
+    }
+  }
+
+  public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
+      File vamsasDocument) throws InvalidSessionDocumentException {
+    checkImportedDocument(vamsasDocument);
+    try {
+      return clientInNewSession(null, applicationHandle, vamsasDocument,null);
+    } catch (InvalidSessionUrnException e) {
+      throw new InvalidSessionDocumentException("Unexpected exception", e);
+    }
+  }
+
+  public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
+      UserHandle userId, File vamsasDocument)
+      throws InvalidSessionDocumentException {
+    checkImportedDocument(vamsasDocument);
+    try {
+      return clientInNewSession(userId, applicationHandle, vamsasDocument,null);
+    } catch (InvalidSessionUrnException e) {
+      throw new InvalidSessionDocumentException("Unexpected exception", e);
+    }
+  }
+
+  public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
+      File vamsasDocument, String sessionName)
+      throws InvalidSessionDocumentException {
+    checkImportedDocument(vamsasDocument);
+    try {
+      return clientInNewSession(null, applicationHandle, vamsasDocument, sessionName);
+    } catch (InvalidSessionUrnException e) {
+      throw new InvalidSessionDocumentException("Unexpected exception", e);
+    }
+  }
+
+  public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
+      UserHandle userId, File vamsasDocument, String sessionName)
+      throws InvalidSessionDocumentException {
+    checkImportedDocument(vamsasDocument);
+    try {
+      return clientInNewSession(userId, applicationHandle, vamsasDocument, sessionName);
+    } catch (InvalidSessionUrnException e) {
+      throw new InvalidSessionDocumentException("Unexpected exception", e);
+    }
   }
 
 }