40932904a51c074209a6a5c7e8b8d1e8ec5d4ca9
[vamsas.git] / src / uk / ac / vamsas / client / simpleclient / SimpleClientFactory.java
1 /*
2 * VAMSAS Project
3 *
4
5
6 * Dec 13, 2006 
7 *
8 */
9  
10 package uk.ac.vamsas.client.simpleclient;
11
12 import java.io.File;
13
14 import java.io.IOException;
15 import java.net.MalformedURLException;
16
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import uk.ac.vamsas.client.ClientHandle;
22 import uk.ac.vamsas.client.IClient;
23 import uk.ac.vamsas.client.IClientFactory;
24 import uk.ac.vamsas.client.InvalidSessionUrnException;
25 import uk.ac.vamsas.client.NoDefaultSessionException;
26 import uk.ac.vamsas.client.SessionHandle;
27 import uk.ac.vamsas.client.UserHandle;
28
29 /**
30  * 
31  * creates a session arena in the user home directory under .vamsas. Each
32  * session has its own subdirectory.
33  */
34 public class SimpleClientFactory implements IClientFactory {
35
36   private static Log log = LogFactory.getLog(SimpleClientFactory.class);
37
38   private File sessionArena = null;
39   
40   private String vamsasSubdirectoryName = ".vamsas";
41   
42  private SimpleSessionManager sessionManager = null;
43   private static final String SESSION_LIST="sessions.obj";
44   
45   // private String[] currentlyAvailableDessions = null;
46   
47   /**
48    * default constructor - called by CreateClientFactory only.
49    * 
50    * Inits the sessionarena to the directory .vamsas of the user home directory.
51    * 
52    */
53   public SimpleClientFactory() throws IOException
54   {
55    // sessionArena
56     
57     // retrieves user home directory
58     String userHomeDirectory = System.getProperty("user.home");
59     if (userHomeDirectory == null || userHomeDirectory.length()<1)
60       {
61         new IOException("Unable to detect user home directory");
62       }
63     String sessionArenaPath =  userHomeDirectory.concat(File.separator.concat(this.vamsasSubdirectoryName));
64     
65     this.initSessionArena(sessionArenaPath);
66    // this.initFactoryObjects();
67   }
68   
69   
70   /**
71    * Create a client factory that works with sessions at the given path.
72    * 
73    * @param path
74    *          path to directory called session arena, where will be created
75    *          session directories and session files.
76    */
77   public SimpleClientFactory(String path) throws IOException
78   {
79     this.initSessionArena(path);
80   }
81   /**
82    * Inits sessionArena to a given path. checks if path is valid.
83    * 
84    * @param path
85    *          path to a directory to use
86    * @throws IOException
87    *           if the path is incorrect
88    */
89   private void  initSessionArena (String path) throws IOException
90   {
91     // Check path is valid and read/writeable.
92     File arenaFile = new File (path);
93     if (!arenaFile.exists())
94     {
95       if (! arenaFile.mkdirs())
96       {
97         this.sessionArena = null;
98         throw(new IOException("Unable to create a directory called "+path));
99       }
100     }
101     if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead() && arenaFile.canWrite()) 
102       {
103         this.sessionArena = arenaFile;
104       } 
105     else
106       {
107       this.sessionArena = null;
108         throw(new IOException("Cannot read and write to a directory called "+path));
109       }
110   }
111   
112   
113
114   
115
116   /**
117    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle)
118    * 
119    * Creates a IClient object, using default UserHandle with system
120    * variables:"user.name" or "USERNAME")), "host.name" or "HOSTNAME"
121    */
122   public IClient getIClient(ClientHandle applicationHandle)
123       throws NoDefaultSessionException {
124     // create a new session
125     // register new ClientHandle in session
126     // create SimpleClient instance
127     return this.getIClient(applicationHandle, (UserHandle) null);
128   }
129
130   /**
131    * the URN should be something like simpleclient:FILEPATH URL encoded
132    * 
133    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
134    *      java.lang.String)
135    */
136   public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) {
137 // locate session from Urn
138     // check that clientHandle is unique (with default user) - if not update the
139     // clientHandle urn to make it unique.
140     // wait for lock and attach to session
141     // create SimpleClient instance
142     log.debug("Trying to create session with URN "+sessionUrn);
143     return this.getIClient(applicationHandle, null, sessionUrn);
144   
145   }
146
147   private File convertSessionUrnToFile(String sessionUrn) throws InvalidSessionUrnException
148   {
149     if (sessionUrn == null)
150       {
151         log.debug("Incorrect URN: can not open session.");
152         throw new InvalidSessionUrnException();
153       }
154     
155     SessionUrn urn = new SessionUrn(sessionUrn);
156    return urn.asFile();
157     
158   }
159   
160   /**
161    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
162    *      uk.ac.vamsas.client.UserHandle, java.lang.String)
163    */
164   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId,
165       String sessionUrn) {
166 // locate session from Urn
167     // check Uniqueness of user + ClientHandle in the session. Update
168     // clientHandle urn accordingly.
169     // wait for lock, attach to session
170     // create client instance
171     IClient client = null;
172     
173     try {
174       File sessionDirectory = this.convertSessionUrnToFile(sessionUrn);
175       // create session
176       log.debug("found session directory "+sessionDirectory.getAbsolutePath());
177       VamsasSession vamsasSession = new VamsasSession(sessionDirectory);
178  
179    /*
180      * if (userId == null) { //create a default userHandle //with current OS
181      * user and hostname userId = new UserHandle(System.getProperty("user.name",
182      * System.getProperty("USERNAME","Joe Doe")),
183      * System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown")
184      * ));// clientName, clientVersion, sessionPath); }
185      * 
186      * 
187      * //create simple client client = new SimpleClient(userId,
188      * applicationHandle, vamsasSession);
189      */
190       client = this.initClient(sessionDirectory, userId, applicationHandle);
191     } catch (MalformedURLException e) {
192       log.error("error while creating new IClient: incorrect session urn",e);
193       client = null;
194      
195     } catch (InvalidSessionUrnException e) {
196       log.error("error while creating new IClient: incorrect session urn",e);
197       client = null;
198     } catch (IOException e) {
199       log.error("error while creating new IClient: file access error",e);
200       client = null;
201     }
202     return client;
203   }
204
205   
206   private IClient initClient( File sessdir, UserHandle userId, ClientHandle clientHandle) throws IOException, InvalidSessionUrnException
207   {
208     IClient client = null;
209     // create session
210     VamsasSession vamsasSession = new VamsasSession(sessdir);
211   
212     this.getSessionManager().addSession(new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()));
213     if (userId == null)
214     {
215       // create a default userHandle
216       // userId = new UserHandle(System.getProperty("user.name",
217       // System.getProperty("USERNAME","Joe Doe")),
218       // System.getProperty("host.name",System.getProperty("HOSTNAME",
219       // "Unknown") ));// clientName, clientVersion, sessionPath);
220       userId = new UserHandle(null, null);
221     }
222     
223     // FullName and organisation should not be null (otherwise UserHandle equals
224     // method raises an java.lang.NullPointerException )
225     // use current OS user and hostname, if null
226     if ( userId.getFullName() == null)
227       {
228         userId.setFullName(System.getProperty("user.name", System.getProperty("USERNAME","Joe Doe")));
229       }
230         
231     if (userId.getOrganization() == null)
232       {
233         userId.setOrganization( System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown") ));
234       }
235       
236     if (clientHandle == null)
237       clientHandle = new ClientHandle("SimpleVamsasClientApp","0.1");
238      else
239        {
240          if (clientHandle.getClientName() == null)
241            {
242              clientHandle.setClientName("SimpleVamsasClientApp");
243            }
244          if (clientHandle.getVersion() == null)
245            {
246              clientHandle.setVersion("0.1");
247            }
248        }
249     
250   // create simple client
251      client = new SimpleClient(userId,  clientHandle,  vamsasSession);
252      vamsasSession.addClient((SimpleClient) client);
253      vamsasSession.setSessionManager(this.getSessionManager());
254      return client;
255   }
256   /**
257    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
258    *      uk.ac.vamsas.client.UserHandle)
259    */
260   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId)
261       throws NoDefaultSessionException {
262     // create new session
263     // register SimpleClient and UserHandles in session
264     // create client instance
265     IClient client = null;
266     if (this.sessionArena==null)
267       throw new Error("Improperly initialised SimpleClientFactory object - null sessionArena.");
268     
269     ClientHandle clientHandle =applicationHandle;
270     // create default clientHandle with "SimpleVamsasClientApp","0.1",
271     if (clientHandle == null)
272      clientHandle = new ClientHandle("SimpleVamsasClientApp","0.1");
273     else
274       {
275         if (clientHandle.getClientName() == null)
276         {
277           clientHandle.setClientName("SimpleVamsasClientApp");
278         }
279       
280     
281     if (clientHandle.getVersion() == null)
282       {
283         clientHandle.setVersion("0.1");
284       }
285       }
286     // check if any available session(s)
287     String[] availableSessions = this.getCurrentSessions();
288     if (availableSessions != null) 
289       {// there are available sessions
290         if (availableSessions.length>1)
291           {// more than one session if available... can not choose
292           
293           // represents list of session as String
294             StringBuffer sessionURNs = new StringBuffer("");
295             for (int i = 0; i< availableSessions.length ; i++)
296               {
297                 sessionURNs.append(availableSessions[i]+" ");
298               }
299             throw new  NoDefaultSessionException("Several sessions available, please pick one: "+sessionURNs);
300           }
301       
302         // check if only one session available. if yes, open it
303         if (availableSessions.length == 1)
304           {
305           // only one session available, open it.
306             return this.getIClient(clientHandle,  availableSessions[0]);
307           }
308         else {
309           log.debug("No active session found");
310         }
311       }
312     // no session available - create a new one
313     
314     client = clientInNewSession(userId, clientHandle);
315     return client;
316   }
317   /**
318    * 
319    * @param userId
320    * @param clientHandle
321    * @return
322    */
323   private IClient clientInNewSession(UserHandle userId,
324       ClientHandle clientHandle) {
325     IClient client = null;
326     try 
327       {
328         // create sessionDirectory
329         File sessdir = File.createTempFile("sess", ".simpleclient", this.sessionArena);
330         log.debug("Creating new session  directory");
331         if (!(sessdir.delete() && sessdir.mkdir()))
332           throw new IOException("Could not make session directory "+sessdir);
333        client = this.initClient(sessdir, userId, clientHandle);
334       } 
335     catch (IOException e) 
336       {
337         log.error("error while creating new IClient",e);
338       }
339     catch (InvalidSessionUrnException e) 
340       {
341         log.error("Unable to create new IClient. The session urn is incorrect ",e);
342       }
343    
344     return client;
345   }
346   /**
347    * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
348    */
349   public String[] getCurrentSessions() {
350     String [] sessions = null;
351     try {
352       sessions =this.getSessionManager().getCurrentSessions();
353     } catch (IOException e) {
354      log.error("Unable to get available sessions",e);
355      sessions = null;
356     }
357     return sessions;
358   }
359
360
361   /**
362    * @return the sessionFile
363    */
364   private SimpleSessionManager getSessionManager()  throws IOException
365     {
366       if (this.sessionManager == null)
367         {
368           this.sessionManager = new SimpleSessionManager( new File (this.sessionArena, SESSION_LIST));
369         }
370       return this.sessionManager;
371     }
372
373
374   public IClient getNewSessionIClient(ClientHandle applicationHandle) {
375     return clientInNewSession(null, applicationHandle);
376   }
377
378
379   public IClient getNewSessionIClient(ClientHandle applicationHandle,
380       UserHandle userId) {
381     return clientInNewSession(userId, applicationHandle);
382   }
383
384   
385
386 }