10 package uk.ac.vamsas.client.simpleclient;
14 import java.io.IOException;
15 import java.net.MalformedURLException;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
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.InvalidSessionDocumentException;
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;
31 * creates a session arena in the user home directory under .vamsas. Each
32 * session has its own subdirectory.
34 public class SimpleClientFactory implements IClientFactory {
36 private static Log log = LogFactory.getLog(SimpleClientFactory.class);
38 private File sessionArena = null;
40 private String vamsasSubdirectoryName = ".vamsas";
42 private SimpleSessionManager sessionManager = null;
44 private static final String SESSION_LIST = "sessions.obj";
46 // private String[] currentlyAvailableDessions = null;
49 * default constructor - called by CreateClientFactory only.
51 * Inits the sessionarena to the directory .vamsas of the user home directory.
54 public SimpleClientFactory() throws IOException {
57 // retrieves user home directory
58 String userHomeDirectory = System.getProperty("user.home");
59 if (userHomeDirectory == null || userHomeDirectory.length() < 1) {
60 new IOException("Unable to detect user home directory");
62 String sessionArenaPath = userHomeDirectory.concat(File.separator
63 .concat(this.vamsasSubdirectoryName));
65 this.initSessionArena(sessionArenaPath);
66 // this.initFactoryObjects();
70 * Create a client factory that works with sessions at the given path.
73 * path to directory called session arena, where will be created
74 * session directories and session files.
76 public SimpleClientFactory(String path) throws IOException {
77 this.initSessionArena(path);
81 * Inits sessionArena to a given path. checks if path is valid.
84 * path to a directory to use
86 * if the path is incorrect
88 private void initSessionArena(String path) throws IOException {
89 // Check path is valid and read/writeable.
90 File arenaFile = new File(path);
91 if (!arenaFile.exists()) {
92 if (!arenaFile.mkdirs()) {
93 this.sessionArena = null;
94 throw (new IOException("Unable to create a directory called " + path));
97 if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead()
98 && arenaFile.canWrite()) {
99 this.sessionArena = arenaFile;
101 this.sessionArena = null;
102 throw (new IOException("Cannot read and write to a directory called "
108 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle)
110 * Creates a IClient object, using default UserHandle with system
111 * variables:"user.name" or "USERNAME")), "host.name" or "HOSTNAME"
113 public IClient getIClient(ClientHandle applicationHandle)
114 throws NoDefaultSessionException {
115 // create a new session
116 // register new ClientHandle in session
117 // create SimpleClient instance
118 return this.getIClient(applicationHandle, (UserHandle) null);
122 * the URN should be something like simpleclient:FILEPATH URL encoded
124 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
127 public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) {
128 // locate session from Urn
129 // check that clientHandle is unique (with default user) - if not update the
130 // clientHandle urn to make it unique.
131 // wait for lock and attach to session
132 // create SimpleClient instance
133 log.debug("Trying to create session with URN " + sessionUrn);
134 return this.getIClient(applicationHandle, null, sessionUrn);
138 private File convertSessionUrnToFile(String sessionUrn)
139 throws InvalidSessionUrnException {
140 if (sessionUrn == null) {
141 log.debug("Incorrect URN: can not open session.");
142 throw new InvalidSessionUrnException();
145 SessionUrn urn = new SessionUrn(sessionUrn);
151 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
152 * uk.ac.vamsas.client.UserHandle, java.lang.String)
154 public IClient getIClient(ClientHandle applicationHandle, UserHandle userId,
156 // locate session from Urn
157 // check Uniqueness of user + ClientHandle in the session. Update
158 // clientHandle urn accordingly.
159 // wait for lock, attach to session
160 // create client instance
161 IClient client = null;
163 // TODO: implement 'opening stored session' opening mechanism
164 // 1. existing session document URL is vdoc://... ?
165 // 2. check for sessionUrn being of this form.
166 // 3. if it is - locate the file and pass to new VamsasSession
169 File sessionDirectory = this.convertSessionUrnToFile(sessionUrn);
172 .debug("found session directory "
173 + sessionDirectory.getAbsolutePath());
174 VamsasSession vamsasSession = new VamsasSession(sessionDirectory);
177 * if (userId == null) { //create a default userHandle //with current OS
178 * user and hostname userId = new UserHandle(System.getProperty("user.name",
179 * System.getProperty("USERNAME","Joe Doe")),
180 * System.getProperty("host.name",System.getProperty("HOSTNAME", "Unknown")
181 * ));// clientName, clientVersion, sessionPath); }
184 * //create simple client client = new SimpleClient(userId,
185 * applicationHandle, vamsasSession);
187 client = this.initClient(sessionDirectory, userId, applicationHandle, null);
188 } catch (MalformedURLException e) {
189 log.error("error while creating new IClient: incorrect session urn", e);
191 } catch (InvalidSessionDocumentException e)
193 log.error("error while creating new IClient: invalid session document", e);
195 } catch (InvalidSessionUrnException e) {
196 log.error("error while creating new IClient: incorrect session urn", e);
198 } catch (IOException e) {
199 log.error("error while creating new IClient: file access error", e);
205 * initialise the vamsas session state and create a SimpleClient object to connect to it
206 * @param sessdir newly created or existing session directory
208 * @param clientHandle
209 * @param vamsasDocument null or a document to pass to SimpleCLient to write into the sessdir
211 * @throws IOException if there are problems in session or client creation or if the session already has a vamsasDocument
212 * @throws InvalidSessionUrnException for a malformed sessdir
214 private IClient initClient(File sessdir, UserHandle userId,
215 ClientHandle clientHandle, File vamsasDocument) throws IOException, InvalidSessionUrnException, InvalidSessionDocumentException {
216 IClient client = null;
218 VamsasSession vamsasSession = null;
219 if (vamsasDocument==null)
221 vamsasSession = new VamsasSession(sessdir);
223 vamsasSession = new VamsasSession(sessdir, vamsasDocument);
226 this.getSessionManager().addSession(
227 new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()));
228 if (userId == null) {
229 // create a default userHandle
230 // userId = new UserHandle(System.getProperty("user.name",
231 // System.getProperty("USERNAME","Joe Doe")),
232 // System.getProperty("host.name",System.getProperty("HOSTNAME",
233 // "Unknown") ));// clientName, clientVersion, sessionPath);
234 userId = new UserHandle(null, null);
237 // FullName and organisation should not be null (otherwise UserHandle equals
238 // method raises an java.lang.NullPointerException )
239 // use current OS user and hostname, if null
240 if (userId.getFullName() == null) {
241 userId.setFullName(System.getProperty("user.name", System.getProperty(
242 "USERNAME", "Joe Doe")));
245 if (userId.getOrganization() == null) {
246 userId.setOrganization(System.getProperty("host.name", System
247 .getProperty("HOSTNAME", "Unknown")));
250 if (clientHandle == null)
251 clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
253 if (clientHandle.getClientName() == null) {
254 clientHandle.setClientName("SimpleVamsasClientApp");
256 if (clientHandle.getVersion() == null) {
257 clientHandle.setVersion("0.1");
261 // create simple client
262 client = new SimpleClient(userId, clientHandle, vamsasSession);
263 vamsasSession.addClient((SimpleClient) client);
264 vamsasSession.setSessionManager(this.getSessionManager());
269 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
270 * uk.ac.vamsas.client.UserHandle)
272 public IClient getIClient(ClientHandle applicationHandle, UserHandle userId)
273 throws NoDefaultSessionException {
274 // create new session
275 // register SimpleClient and UserHandles in session
276 // create client instance
277 IClient client = null;
278 if (this.sessionArena == null)
280 "Improperly initialised SimpleClientFactory object - null sessionArena.");
282 ClientHandle clientHandle = applicationHandle;
283 // create default clientHandle with "SimpleVamsasClientApp","0.1",
284 if (clientHandle == null)
285 clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
287 if (clientHandle.getClientName() == null) {
288 clientHandle.setClientName("SimpleVamsasClientApp");
291 if (clientHandle.getVersion() == null) {
292 clientHandle.setVersion("0.1");
295 // check if any available session(s)
296 String[] availableSessions = this.getCurrentSessions();
297 if (availableSessions != null) {// there are available sessions
298 if (availableSessions.length > 1) {// more than one session if available... can not choose
300 // represents list of session as String
301 StringBuffer sessionURNs = new StringBuffer("");
302 for (int i = 0; i < availableSessions.length; i++) {
303 sessionURNs.append(availableSessions[i] + " ");
305 throw new NoDefaultSessionException(
306 "Several sessions available, please pick one: " + sessionURNs);
309 // check if only one session available. if yes, open it
310 if (availableSessions.length == 1) {
311 // only one session available, open it.
312 return this.getIClient(clientHandle, availableSessions[0]);
314 log.debug("No active session found");
317 // no session available - create a new one
319 client = clientInNewSession(userId, clientHandle, null);
320 } catch (Exception e)
322 throw new Error("IMPLEMENTATION ERROR: unexpected exception when creating a new session to connect to.",e);
328 * create a new session directory and possibly import an existing document into it
330 * @param clientHandle
331 * @param vamsasDocument null or a document file to copy into the new session
332 * @return null or a valid IClient instance
334 private IClient clientInNewSession(UserHandle userId,
335 ClientHandle clientHandle, File vamsasDocument) throws InvalidSessionDocumentException, InvalidSessionUrnException{
337 IClient client = null;
339 // try and make a friendly session name
340 String sesspref = "";
341 if (vamsasDocument!=null)
343 sesspref = vamsasDocument.getName().replaceAll("([^-A-Za-z0-9]|\\.vdj)", "");
345 sesspref += (new java.util.Date()).toString().replaceAll("[^-A-Za-z0-9]","_");
346 // create sessionDirectory
347 File sessdir = new File(sessionArena, sesspref+".simpleclient");
348 if (sessdir.exists())
350 // make a unique session name
351 sessdir = File.createTempFile(sesspref, ".simpleclient",
354 if (!sessdir.createNewFile())
356 throw new Error("VAMSAS Implementation error : sesspref friendly session name is invalid on this platform - please tell the authors!");
359 log.debug("Creating new session directory");
360 if (!(sessdir.delete() && sessdir.mkdir()))
361 throw new IOException("Could not make session directory " + sessdir);
362 client = initClient(sessdir, userId, clientHandle, vamsasDocument);
363 } catch (IOException e) {
364 log.error("error while creating new IClient", e);
365 } catch (InvalidSessionUrnException e) {
366 log.error("Unable to create new IClient. The new session urn is malformed.",
374 * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
376 public String[] getCurrentSessions() {
377 String[] sessions = null;
379 sessions = this.getSessionManager().getCurrentSessions();
380 } catch (IOException e) {
381 log.error("Unable to get available sessions", e);
388 * @return the sessionFile
390 private SimpleSessionManager getSessionManager() throws IOException {
391 if (this.sessionManager == null) {
392 this.sessionManager = new SimpleSessionManager(new File(
393 this.sessionArena, SESSION_LIST));
395 return this.sessionManager;
398 public IClient getNewSessionIClient(ClientHandle applicationHandle) {
400 return clientInNewSession(null, applicationHandle, null);
402 catch (Exception e) {
403 log.error("Failed to create new session for app with default user.",e);
408 public IClient getNewSessionIClient(ClientHandle applicationHandle,
411 return clientInNewSession(userId, applicationHandle, null);
412 } catch (Exception e) {
413 log.error("Failed to create new session for app and user.",e);
417 private void checkImportedDocument(File vamsasDocument) throws InvalidSessionDocumentException
419 if (!vamsasDocument.exists())
421 throw new InvalidSessionDocumentException("File "+vamsasDocument+" does not exist");
423 if (!vamsasDocument.canRead())
425 throw new InvalidSessionDocumentException("File "+vamsasDocument+" does not exist");
428 public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
429 File vamsasDocument) throws InvalidSessionDocumentException {
430 checkImportedDocument(vamsasDocument);
432 return clientInNewSession(null, applicationHandle, vamsasDocument);
433 } catch (InvalidSessionUrnException e)
435 throw new InvalidSessionDocumentException("Unexpected exception", e);
439 public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
440 UserHandle userId, File vamsasDocument) throws InvalidSessionDocumentException {
441 checkImportedDocument(vamsasDocument);
443 return clientInNewSession(userId, applicationHandle, vamsasDocument);
444 } catch (InvalidSessionUrnException e)
446 throw new InvalidSessionDocumentException("Unexpected exception", e);