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