f93fa28e2bce84e2ed20df755c739c804bbd7062
[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  * 
32  */
33 public class SimpleClientFactory implements IClientFactory {
34
35   private static Log log = LogFactory.getLog(SimpleClientFactory.class);
36
37   private File sessionArena = null;
38   
39   private String vamsasSubdirectoryName = ".vamsas";
40   
41   private SessionsFile sessionFile = null;
42   private static final String SESSION_LIST="sessions.obj";
43   
44   //private   String[] currentlyAvailableDessions = null; 
45   
46   /**
47    * default constructor - called by CreateClientFactory only.
48    *
49    *Inits the sessionarena to the directory .vamsas of the user home directory. 
50    *
51    */
52   public SimpleClientFactory() throws IOException
53   {
54    // sessionArena
55     
56     //retrieves user home directory
57     String userHomeDirectory = System.getProperty("user.home");
58     if (userHomeDirectory == null || userHomeDirectory.length()<1)
59       {
60         new IOException("Unable to detect user home directory");
61       }
62     String sessionArenaPath =  userHomeDirectory.concat(File.separator.concat(this.vamsasSubdirectoryName));
63     
64     this.initSessionArena(sessionArenaPath);
65     this.initFactoryObjects();
66   }
67   
68   
69   /**
70    * Create a client factory that works with sessions at the given
71    * path.
72    * @param path path to directory called  session arena, where will be created session directories and session files.
73    */
74   public SimpleClientFactory(String path) throws IOException
75   {
76     this.initSessionArena(path);
77   }
78   /**
79    * Inits sessionArena to a given path.
80    * checks if path is valid.
81    * 
82    * @param path path to a directory to use 
83    * @throws IOException if the path is incorrect
84    */
85   private void  initSessionArena (String path) throws IOException
86   {
87     // Check path is valid and read/writeable.
88     File arenaFile = new File (path);
89     if (!arenaFile.exists())
90     {
91       if (! arenaFile.mkdirs())
92       {
93         this.sessionArena = null;
94         throw(new IOException("Unable to create a directory called "+path));
95       }
96     }
97     if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead() && arenaFile.canWrite()) 
98       {
99         this.sessionArena = arenaFile;
100       } 
101     else
102       {
103       this.sessionArena = null;
104         throw(new IOException("Cannot read and write to a directory called "+path));
105       }
106   }
107   
108   /**
109    * construct SessionFile objects and watchers for each
110    */
111   private void initFactoryObjects() throws IOException {
112     if (this.sessionFile!=null )
113       throw new IOException("initFactoryObjects called for initialised ClientFactory object.");
114     this.sessionFile = new SessionsFile(new File(this.sessionArena,SESSION_LIST));
115
116   }
117   /**
118    * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
119    */
120   public String[] getCurrentSessions() 
121   { 
122     String[] sessions = null;
123     if (this.sessionFile!=null )
124       {
125         SessionHandle[] sessionHandles =  this.sessionFile.retrieveSessionsList();
126         if (sessionHandles != null)
127           {
128             sessions = new String[sessionHandles.length];
129             for (int i = sessionHandles.length -1; i > -1; i--)
130               {
131                 SessionHandle sessionHandle = sessionHandles[i];
132                 sessions [i] = sessionHandle.getSessionUrn();
133               }
134           }
135       }
136     return sessions;
137   }
138   
139
140   /**
141    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle)
142    * 
143    * Creates a IClient object, using default UserHandle with system variables:"user.name" or "USERNAME")),
144             "host.name" or "HOSTNAME" 
145    */
146   public IClient getIClient(ClientHandle applicationHandle)
147       throws NoDefaultSessionException {
148     // create a new session
149     // register new ClientHandle in session
150     // create SimpleClient instance
151     return this.getIClient(applicationHandle, (UserHandle) null);
152   }
153
154   /**
155    * the URN should be something like simpleclient:FILEPATH URL encoded
156    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle, java.lang.String)
157    */
158   public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) {
159 //  locate session from Urn
160     // check that clientHandle is unique (with default user) - if not update the clientHandle urn to make it unique.
161     // wait for lock and attach to session
162     // create SimpleClient instance
163     log.debug("Trying to create session with URN "+sessionUrn);
164     return this.getIClient(applicationHandle, null, sessionUrn);
165   
166   }
167
168   private File convertSessionUrnToFile(String sessionUrn) throws InvalidSessionUrnException
169   {
170     if (sessionUrn == null)
171       {
172         log.debug("Incorrect URN: can not open session.");
173         throw new InvalidSessionUrnException();
174       }
175     
176     SessionUrn urn = new SessionUrn(sessionUrn);
177    return urn.asFile();
178     
179   }
180   
181   /**
182    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle, uk.ac.vamsas.client.UserHandle, java.lang.String)
183    */
184   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId,
185       String sessionUrn) {
186 //  locate session from Urn
187     // check Uniqueness of user + ClientHandle in the session. Update clientHandle urn accordingly.
188     // wait for lock, attach to session
189     // create client instance
190     SimpleClient client = null;
191     
192     try {
193       File sessionDirectory = this.convertSessionUrnToFile(sessionUrn);
194       //create session
195       log.debug("found session directory "+sessionDirectory.getAbsolutePath());
196       VamsasSession vamsasSession = new VamsasSession(sessionDirectory);
197  
198       if (userId == null)
199         {
200         //create a default userHandle
201         //with current OS user and hostname
202           userId = new UserHandle(System.getProperty("user.name", System.getProperty("USERNAME","Joe Doe")),
203               System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown") ));// clientName, clientVersion,  sessionPath);
204         }
205  
206  
207  //create simple client
208        client = new SimpleClient(userId,  applicationHandle,  vamsasSession);
209     } catch (MalformedURLException e) {
210       log.error("error while creating new IClient: incorrect session urn",e);
211       client = null;
212      
213     } catch (InvalidSessionUrnException e) {
214       log.error("error while creating new IClient: incorrect session urn",e);
215       client = null;
216     } catch (IOException e) {
217       log.error("error while creating new IClient: file access error",e);
218       client = null;
219     }
220     return client;
221   }
222
223   /**
224    * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle, uk.ac.vamsas.client.UserHandle)
225    */
226   public IClient getIClient(ClientHandle applicationHandle, UserHandle userId)
227       throws NoDefaultSessionException {
228     // create new session
229     // register SimpleClient and UserHandles in session
230     // create client instance
231     SimpleClient client = null;
232     if (this.sessionArena==null)
233       throw new Error("Improperly initialised SimpleClientFactory object - null sessionArena.");
234     
235     ClientHandle clientHandle =applicationHandle;
236     //create default clientHandle with "SimpleVamsasClientApp","0.1",
237     if (clientHandle == null)
238      clientHandle = new ClientHandle("SimpleVamsasClientApp","0.1");
239     
240     //check if any available session(s)
241     String[] availableSessions = this.getCurrentSessions();
242     if (availableSessions != null) 
243       {//there are available sessions
244         if (availableSessions.length>1)
245           {//more than one session if available... can not choose
246           
247           //represents list of session as String
248             StringBuffer sessionURNs = new StringBuffer("");
249             for (int i = 0; i< availableSessions.length ; i++)
250               {
251                 sessionURNs.append(availableSessions[i]+" ");
252               }
253             throw new  NoDefaultSessionException("Several sessions available, please pick one: "+sessionURNs);
254           }
255       
256         //check if only one session available. if yes, open it
257         if (availableSessions.length == 1)
258           {
259           //only one session available, open it.
260             return this.getIClient(clientHandle,  availableSessions[0]);
261           }
262       }
263     //no session available  - create a new one
264     
265     
266     try 
267       {
268         //create sessionDirectory
269         File sessdir = File.createTempFile("sess", ".simpleclient", this.sessionArena);
270         log.debug("Creating new session  directory");
271        if (!(sessdir.delete() && sessdir.mkdir()))
272           throw new IOException("Could not make session directory "+sessdir);
273       //create session
274         VamsasSession vamsasSession = new VamsasSession(sessdir);
275       
276         this.getSessionFile().addSession(new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()), false);
277         if (userId == null)
278           {
279       //create a default userHandle
280       //with current OS user and hostname
281             userId = new UserHandle(System.getProperty("user.name", System.getProperty("USERNAME","Joe Doe")),
282               System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown") ));// clientName, clientVersion,  sessionPath);
283           }
284      
285       
286       //create simple client
287          client = new SimpleClient(userId,  clientHandle,  vamsasSession);
288       } 
289     catch (IOException e) 
290       {
291         log.error("error while creating new IClient",e);
292       }
293     catch (InvalidSessionUrnException e) 
294       {
295         log.error("Unable to create new IClient. The session urn is incorrect ",e);
296       }
297    
298       return client;
299   }
300
301
302   /**
303    * @return the sessionFile
304    */
305   private SessionsFile getSessionFile()  throws IOException
306     {
307       if (this.sessionFile == null)
308         {
309           this.sessionFile = new SessionsFile( new File (this.sessionArena, SESSION_LIST));
310         }
311       return this.sessionFile;
312     }
313
314   
315
316 }