/core/src/com/bluemarsh/jswat/core/session/DefaultSessionManager.java

http://jswat.googlecode.com/ · Java · 230 lines · 169 code · 16 blank · 45 comment · 23 complexity · f91db3cc9dd2704c1e775eb104cd6297 MD5 · raw file

  1. /*
  2. * The contents of this file are subject to the terms of the Common Development
  3. * and Distribution License (the License). You may not use this file except in
  4. * compliance with the License.
  5. *
  6. * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
  7. * or http://www.netbeans.org/cddl.txt.
  8. *
  9. * When distributing Covered Code, include this CDDL Header Notice in each file
  10. * and include the License file at http://www.netbeans.org/cddl.txt.
  11. * If applicable, add the following below the CDDL Header, with the fields
  12. * enclosed by brackets [] replaced by your own identifying information:
  13. * "Portions Copyrighted [year] [name of copyright owner]"
  14. *
  15. * The Original Software is JSwat. The Initial Developer of the Original
  16. * Software is Nathan L. Fiedler. Portions created by Nathan L. Fiedler
  17. * are Copyright (C) 2004-2010. All Rights Reserved.
  18. *
  19. * Contributor(s): Nathan L. Fiedler.
  20. *
  21. * $Id: DefaultSessionManager.java 285 2010-11-20 23:56:08Z nathanfiedler $
  22. */
  23. package com.bluemarsh.jswat.core.session;
  24. import com.bluemarsh.jswat.core.PlatformProvider;
  25. import com.bluemarsh.jswat.core.PlatformService;
  26. import java.beans.ExceptionListener;
  27. import java.beans.XMLDecoder;
  28. import java.beans.XMLEncoder;
  29. import java.io.FileNotFoundException;
  30. import java.io.IOException;
  31. import java.io.InputStream;
  32. import java.io.OutputStream;
  33. import java.util.Collections;
  34. import java.util.Iterator;
  35. import java.util.LinkedList;
  36. import java.util.List;
  37. import java.util.logging.Level;
  38. import java.util.logging.Logger;
  39. /**
  40. * DefaultSessionManager manages Session instances persisted to properties
  41. * files in the userdir.
  42. *
  43. * @author Nathan Fiedler
  44. */
  45. public class DefaultSessionManager extends AbstractSessionManager {
  46. /** Logger for gracefully reporting unexpected errors. */
  47. private static final Logger logger = Logger.getLogger(
  48. DefaultSessionManager.class.getName());
  49. /** The prefix for session identifiers. */
  50. private static final String ID_PREFIX = "SID_";
  51. /** List of the open sessions. */
  52. private List<Session> openSessions;
  53. /** The currently selected Session instance. */
  54. private Session currentSession;
  55. /**
  56. * Creates a new instance of SessionManager.
  57. */
  58. public DefaultSessionManager() {
  59. super();
  60. openSessions = new LinkedList<Session>();
  61. }
  62. @Override
  63. public synchronized void add(Session session) {
  64. // Give the session a name, if it doesn't have one already.
  65. String name = session.getProperty(Session.PROP_SESSION_NAME);
  66. if (name == null || name.length() == 0) {
  67. name = generateName();
  68. session.setProperty(Session.PROP_SESSION_NAME, name);
  69. }
  70. openSessions.add(session);
  71. if (currentSession == null) {
  72. setCurrent(session);
  73. }
  74. fireEvent(new SessionManagerEvent(this, session,
  75. SessionManagerEventType.ADDED));
  76. }
  77. @Override
  78. public synchronized Session copy(Session session, String name) {
  79. SessionFactory factory = SessionProvider.getSessionFactory();
  80. String id = generateIdentifier();
  81. Session copy = factory.createSession(id);
  82. Iterator<String> keys = session.propertyNames();
  83. while (keys.hasNext()) {
  84. String key = keys.next();
  85. String value = session.getProperty(key);
  86. copy.setProperty(key, value);
  87. }
  88. String sessionName = name == null ? generateName() : name;
  89. copy.setProperty(Session.PROP_SESSION_NAME, sessionName);
  90. openSessions.add(copy);
  91. fireEvent(new SessionManagerEvent(this, copy,
  92. SessionManagerEventType.ADDED));
  93. return copy;
  94. }
  95. @Override
  96. public Session findById(String id) {
  97. Iterator<Session> sessions = iterateSessions();
  98. while (sessions.hasNext()) {
  99. Session session = sessions.next();
  100. if (session.getIdentifier().equals(id)) {
  101. return session;
  102. }
  103. }
  104. return null;
  105. }
  106. @Override
  107. public String generateIdentifier() {
  108. if (openSessions.isEmpty()) {
  109. return ID_PREFIX + '1';
  110. } else {
  111. int max = 0;
  112. for (Session session : openSessions) {
  113. String id = session.getIdentifier();
  114. id = id.substring(ID_PREFIX.length());
  115. try {
  116. int i = Integer.parseInt(id);
  117. if (i > max) {
  118. max = i;
  119. }
  120. } catch (NumberFormatException nfe) {
  121. // This cannot happen as we generate the identifier
  122. // and it will always have an integer suffix.
  123. }
  124. }
  125. max++;
  126. return ID_PREFIX + max;
  127. }
  128. }
  129. @Override
  130. public synchronized Session getCurrent() {
  131. return currentSession;
  132. }
  133. @Override
  134. @SuppressWarnings("unchecked")
  135. public synchronized void loadSessions() {
  136. // Read the persisted Sessions from disk.
  137. XMLDecoder decoder = null;
  138. try {
  139. PlatformService platform = PlatformProvider.getPlatformService();
  140. String name = "sessions.xml";
  141. InputStream is = platform.readFile(name);
  142. decoder = new XMLDecoder(is);
  143. decoder.setExceptionListener(new ExceptionListener() {
  144. @Override
  145. public void exceptionThrown(Exception e) {
  146. logger.log(Level.SEVERE, null, e);
  147. }
  148. });
  149. openSessions = (List<Session>) decoder.readObject();
  150. // Get the ID of the current session.
  151. String id = (String) decoder.readObject();
  152. Session session = findById(id);
  153. if (session != null) {
  154. setCurrent(session);
  155. }
  156. } catch (FileNotFoundException e) {
  157. // Do not report this error, it's normal.
  158. } catch (Exception e) {
  159. // Parser, I/O, and various runtime exceptions may occur,
  160. // need to report them and gracefully recover.
  161. logger.log(Level.SEVERE, null, e);
  162. // SessionProvider will ensure that a current session exists.
  163. } finally {
  164. if (decoder != null) {
  165. decoder.close();
  166. }
  167. }
  168. }
  169. @Override
  170. public synchronized Iterator<Session> iterateSessions() {
  171. // Make sure the caller cannot modify the list.
  172. List<Session> ro = Collections.unmodifiableList(openSessions);
  173. return ro.iterator();
  174. }
  175. @Override
  176. public synchronized void remove(Session session) {
  177. if (currentSession == session) {
  178. throw new IllegalArgumentException("cannot delete current session");
  179. }
  180. openSessions.remove(session);
  181. fireEvent(new SessionManagerEvent(this, session,
  182. SessionManagerEventType.REMOVED));
  183. }
  184. @Override
  185. public synchronized void saveSessions(boolean close) {
  186. if (close) {
  187. for (Session session : openSessions) {
  188. if (session.isConnected()) {
  189. session.disconnect(false);
  190. }
  191. session.close();
  192. }
  193. }
  194. String name = "sessions.xml";
  195. PlatformService platform = PlatformProvider.getPlatformService();
  196. try {
  197. OutputStream os = platform.writeFile(name);
  198. XMLEncoder encoder = new XMLEncoder(os);
  199. encoder.writeObject(openSessions);
  200. encoder.writeObject(currentSession.getIdentifier());
  201. encoder.close();
  202. } catch (IOException ioe) {
  203. logger.log(Level.SEVERE, null, ioe);
  204. } finally {
  205. platform.releaseLock(name);
  206. }
  207. }
  208. @Override
  209. public synchronized void setCurrent(Session session) {
  210. currentSession = session;
  211. fireEvent(new SessionManagerEvent(this, session,
  212. SessionManagerEventType.CURRENT));
  213. }
  214. }