2 * This file is part of the Vamsas Client version 0.1.
3 * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite,
4 * Andrew Waterhouse and Dominik Lindner.
6 * Earlier versions have also been incorporated into Jalview version 2.4
7 * since 2008, and TOPALi version 2 since 2007.
9 * The Vamsas Client is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * The Vamsas Client is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the Vamsas Client. If not, see <http://www.gnu.org/licenses/>.
22 package uk.ac.vamsas.client.simpleclient;
26 import java.io.IOException;
27 import java.net.MalformedURLException;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
32 import uk.ac.vamsas.client.ClientHandle;
33 import uk.ac.vamsas.client.IClient;
34 import uk.ac.vamsas.client.IClientFactory;
35 import uk.ac.vamsas.client.InvalidSessionDocumentException;
36 import uk.ac.vamsas.client.InvalidSessionUrnException;
37 import uk.ac.vamsas.client.NoDefaultSessionException;
38 import uk.ac.vamsas.client.SessionHandle;
39 import uk.ac.vamsas.client.UserHandle;
43 * creates a session arena in the user home directory under .vamsas. Each
44 * session has its own subdirectory.
46 public class SimpleClientFactory implements IClientFactory {
48 private static Log log = LogFactory.getLog(SimpleClientFactory.class);
50 private File sessionArena = null;
52 private String vamsasSubdirectoryName = ".vamsas";
54 private SimpleSessionManager sessionManager = null;
56 private static final String SESSION_LIST = "sessions.obj";
58 // private String[] currentlyAvailableDessions = null;
61 * default constructor - called by CreateClientFactory only.
63 * Inits the sessionarena to the directory .vamsas of the user home directory.
66 public SimpleClientFactory() throws IOException {
69 // retrieves user home directory
70 String userHomeDirectory = System.getProperty("user.home");
71 if (userHomeDirectory == null || userHomeDirectory.length() < 1) {
72 new IOException("Unable to detect user home directory");
74 String sessionArenaPath = userHomeDirectory.concat(File.separator
75 .concat(this.vamsasSubdirectoryName));
77 this.initSessionArena(sessionArenaPath);
78 // this.initFactoryObjects();
82 * Create a client factory that works with sessions at the given path.
85 * path to directory called session arena, where will be created
86 * session directories and session files.
88 public SimpleClientFactory(String path) throws IOException {
89 this.initSessionArena(path);
93 * Inits sessionArena to a given path. checks if path is valid.
96 * path to a directory to use
98 * if the path is incorrect
100 private void initSessionArena(String path) throws IOException {
101 // Check path is valid and read/writeable.
102 File arenaFile = new File(path);
103 if (!arenaFile.exists()) {
104 if (!arenaFile.mkdirs()) {
105 this.sessionArena = null;
106 throw (new IOException("Unable to create a directory called " + path));
109 if (arenaFile.exists() && arenaFile.isDirectory() && arenaFile.canRead()
110 && arenaFile.canWrite()) {
111 this.sessionArena = arenaFile;
113 this.sessionArena = null;
114 throw (new IOException("Cannot read and write to a directory called "
120 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle)
122 * Creates a IClient object, using default UserHandle with system
123 * variables:"user.name" or "USERNAME")), "host.name" or "HOSTNAME"
125 public IClient getIClient(ClientHandle applicationHandle)
126 throws NoDefaultSessionException {
127 // create a new session
128 // register new ClientHandle in session
129 // create SimpleClient instance
130 return this.getIClient(applicationHandle, (UserHandle) null);
134 * the URN should be something like simpleclient:FILEPATH URL encoded
136 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
139 public IClient getIClient(ClientHandle applicationHandle, String sessionUrn) {
140 // locate session from Urn
141 // check that clientHandle is unique (with default user) - if not update the
142 // clientHandle urn to make it unique.
143 // wait for lock and attach to session
144 // create SimpleClient instance
145 log.debug("Trying to create session with URN " + sessionUrn);
146 return this.getIClient(applicationHandle, null, sessionUrn);
150 private File convertSessionUrnToFile(String sessionUrn)
151 throws InvalidSessionUrnException {
152 if (sessionUrn == null) {
153 log.debug("Incorrect URN: can not open session.");
154 throw new InvalidSessionUrnException();
157 SessionUrn urn = new SessionUrn(sessionUrn);
163 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
164 * uk.ac.vamsas.client.UserHandle, java.lang.String)
166 public IClient getIClient(ClientHandle applicationHandle, UserHandle userId,
168 // locate session from Urn
169 // check Uniqueness of user + ClientHandle in the session. Update
170 // clientHandle urn accordingly.
171 // wait for lock, attach to session
172 // create client instance
173 IClient client = null;
175 // TODO: implement 'opening stored session' opening mechanism
176 // 1. existing session document URL is vdoc://... ?
177 // 2. check for sessionUrn being of this form.
178 // 3. if it is - locate the file and pass to new VamsasSession
181 File sessionDirectory = this.convertSessionUrnToFile(sessionUrn);
184 .debug("found session directory "
185 + sessionDirectory.getAbsolutePath());
186 VamsasSession vamsasSession = new VamsasSession(sessionDirectory);
189 * if (userId == null) { //create a default userHandle //with current OS
190 * user and hostname userId = new
191 * UserHandle(System.getProperty("user.name",
192 * System.getProperty("USERNAME","Joe Doe")),
193 * System.getProperty("host.name",System.getProperty("HOSTNAME",
194 * "Unknown") ));// clientName, clientVersion, sessionPath); }
197 * //create simple client client = new SimpleClient(userId,
198 * applicationHandle, vamsasSession);
200 client = this.initClient(sessionDirectory, userId, applicationHandle,
202 } catch (MalformedURLException e) {
203 log.error("error while creating new IClient: incorrect session urn", e);
205 } catch (InvalidSessionDocumentException e) {
207 .error("error while creating new IClient: invalid session document",
210 } catch (InvalidSessionUrnException e) {
211 log.error("error while creating new IClient: incorrect session urn", e);
213 } catch (IOException e) {
214 log.error("error while creating new IClient: file access error", e);
221 * initialise the vamsas session state and create a SimpleClient object to
225 * newly created or existing session directory
227 * @param clientHandle
228 * @param vamsasDocument
229 * null or a document to pass to SimpleCLient to write into the
232 * @throws IOException
233 * if there are problems in session or client creation or if the
234 * session already has a vamsasDocument
235 * @throws InvalidSessionUrnException
236 * for a malformed sessdir
238 private IClient initClient(File sessdir, UserHandle userId,
239 ClientHandle clientHandle, File vamsasDocument) throws IOException,
240 InvalidSessionUrnException, InvalidSessionDocumentException {
241 IClient client = null;
243 VamsasSession vamsasSession = null;
244 if (vamsasDocument == null) {
245 vamsasSession = new VamsasSession(sessdir);
247 vamsasSession = new VamsasSession(sessdir, vamsasDocument);
250 this.getSessionManager().addSession(
251 new SessionHandle(new SessionUrn(vamsasSession).getSessionUrn()));
252 if (userId == null) {
253 // create a default userHandle
254 // userId = new UserHandle(System.getProperty("user.name",
255 // System.getProperty("USERNAME","Joe Doe")),
256 // System.getProperty("host.name",System.getProperty("HOSTNAME",
257 // "Unknown") ));// clientName, clientVersion, sessionPath);
258 userId = new UserHandle(null, null);
261 // FullName and organisation should not be null (otherwise UserHandle equals
262 // method raises an java.lang.NullPointerException )
263 // use current OS user and hostname, if null
264 if (userId.getFullName() == null) {
265 userId.setFullName(System.getProperty("user.name", System.getProperty(
266 "USERNAME", "Joe Doe")));
269 if (userId.getOrganization() == null) {
270 userId.setOrganization(System.getProperty("host.name", System
271 .getProperty("HOSTNAME", "Unknown")));
274 if (clientHandle == null)
275 clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
277 if (clientHandle.getClientName() == null) {
278 clientHandle.setClientName("SimpleVamsasClientApp");
280 if (clientHandle.getVersion() == null) {
281 clientHandle.setVersion("0.1");
285 // create simple client
286 client = new SimpleClient(userId, clientHandle, vamsasSession);
287 vamsasSession.addClient((SimpleClient) client);
288 vamsasSession.setSessionManager(this.getSessionManager());
293 * @see uk.ac.vamsas.client.IClientFactory#getIClient(uk.ac.vamsas.client.ClientHandle,
294 * uk.ac.vamsas.client.UserHandle)
296 public IClient getIClient(ClientHandle applicationHandle, UserHandle userId)
297 throws NoDefaultSessionException {
298 // create new session
299 // register SimpleClient and UserHandles in session
300 // create client instance
301 IClient client = null;
302 if (this.sessionArena == null)
304 "Improperly initialised SimpleClientFactory object - null sessionArena.");
306 ClientHandle clientHandle = applicationHandle;
307 // create default clientHandle with "SimpleVamsasClientApp","0.1",
308 if (clientHandle == null)
309 clientHandle = new ClientHandle("SimpleVamsasClientApp", "0.1");
311 if (clientHandle.getClientName() == null) {
312 clientHandle.setClientName("SimpleVamsasClientApp");
315 if (clientHandle.getVersion() == null) {
316 clientHandle.setVersion("0.1");
319 // check if any available session(s)
320 String[] availableSessions = this.getCurrentSessions();
321 if (availableSessions != null) {// there are available sessions
322 if (availableSessions.length > 1) {// more than one session if
323 // available... can not choose
325 // represents list of session as String
326 StringBuffer sessionURNs = new StringBuffer("");
327 for (int i = 0; i < availableSessions.length; i++) {
328 sessionURNs.append(availableSessions[i] + " ");
330 throw new NoDefaultSessionException(
331 "Several sessions available, please pick one: " + sessionURNs);
334 // check if only one session available. if yes, open it
335 if (availableSessions.length == 1) {
336 // only one session available, open it.
337 return this.getIClient(clientHandle, availableSessions[0]);
339 log.debug("No active session found");
342 // no session available - create a new one
344 client = clientInNewSession(userId, clientHandle, null);
345 } catch (Exception e) {
347 "IMPLEMENTATION ERROR: unexpected exception when creating a new session to connect to.",
354 * create a new session directory and possibly import an existing document
358 * @param clientHandle
359 * @param vamsasDocument
360 * null or a document file to copy into the new session
361 * @return null or a valid IClient instance
363 private IClient clientInNewSession(UserHandle userId,
364 ClientHandle clientHandle, File vamsasDocument)
365 throws InvalidSessionDocumentException, InvalidSessionUrnException {
367 IClient client = null;
369 // try and make a friendly session name
370 String sesspref = "";
371 if (vamsasDocument != null) {
372 sesspref = vamsasDocument.getName().replaceAll(
373 "([^-A-Za-z0-9]|\\.vdj)", "");
375 sesspref += (new java.util.Date()).toString().replaceAll("[^-A-Za-z0-9]",
377 // create sessionDirectory
378 File sessdir = new File(sessionArena, sesspref + ".simpleclient");
379 if (sessdir.exists()) {
380 // make a unique session name
381 sessdir = File.createTempFile(sesspref, ".simpleclient", sessionArena);
383 if (!sessdir.createNewFile()) {
385 "VAMSAS Implementation error : sesspref friendly session name is invalid on this platform - please tell the authors!");
388 log.debug("Creating new session directory");
389 if (!(sessdir.delete() && sessdir.mkdir()))
390 throw new IOException("Could not make session directory " + sessdir);
391 client = initClient(sessdir, userId, clientHandle, vamsasDocument);
392 } catch (IOException e) {
393 log.error("error while creating new IClient", e);
394 } catch (InvalidSessionUrnException e) {
396 "Unable to create new IClient. The new session urn is malformed.", e);
403 * @see uk.ac.vamsas.client.IClientFactory#getCurrentSessions()
405 public String[] getCurrentSessions() {
406 String[] sessions = null;
408 sessions = this.getSessionManager().getCurrentSessions();
409 } catch (IOException e) {
410 log.error("Unable to get available sessions", e);
417 * @return the sessionFile
419 private SimpleSessionManager getSessionManager() throws IOException {
420 if (this.sessionManager == null) {
421 this.sessionManager = new SimpleSessionManager(new File(
422 this.sessionArena, SESSION_LIST));
424 return this.sessionManager;
427 public IClient getNewSessionIClient(ClientHandle applicationHandle) {
429 return clientInNewSession(null, applicationHandle, null);
430 } catch (Exception e) {
431 log.error("Failed to create new session for app with default user.", e);
436 public IClient getNewSessionIClient(ClientHandle applicationHandle,
439 return clientInNewSession(userId, applicationHandle, null);
440 } catch (Exception e) {
441 log.error("Failed to create new session for app and user.", e);
446 private void checkImportedDocument(File vamsasDocument)
447 throws InvalidSessionDocumentException {
448 if (!vamsasDocument.exists()) {
449 throw new InvalidSessionDocumentException("File " + vamsasDocument
450 + " does not exist");
452 if (!vamsasDocument.canRead()) {
453 throw new InvalidSessionDocumentException("File " + vamsasDocument
454 + " does not exist");
458 public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
459 File vamsasDocument) throws InvalidSessionDocumentException {
460 checkImportedDocument(vamsasDocument);
462 return clientInNewSession(null, applicationHandle, vamsasDocument);
463 } catch (InvalidSessionUrnException e) {
464 throw new InvalidSessionDocumentException("Unexpected exception", e);
468 public IClient openAsNewSessionIClient(ClientHandle applicationHandle,
469 UserHandle userId, File vamsasDocument)
470 throws InvalidSessionDocumentException {
471 checkImportedDocument(vamsasDocument);
473 return clientInNewSession(userId, applicationHandle, vamsasDocument);
474 } catch (InvalidSessionUrnException e) {
475 throw new InvalidSessionDocumentException("Unexpected exception", e);