/core/src/com/bluemarsh/jswat/core/session/DefaultSessionManager.java
Java | 230 lines | 169 code | 16 blank | 45 comment | 23 complexity | f91db3cc9dd2704c1e775eb104cd6297 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
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 */ 23package com.bluemarsh.jswat.core.session; 24 25import com.bluemarsh.jswat.core.PlatformProvider; 26import com.bluemarsh.jswat.core.PlatformService; 27import java.beans.ExceptionListener; 28import java.beans.XMLDecoder; 29import java.beans.XMLEncoder; 30import java.io.FileNotFoundException; 31import java.io.IOException; 32import java.io.InputStream; 33import java.io.OutputStream; 34import java.util.Collections; 35import java.util.Iterator; 36import java.util.LinkedList; 37import java.util.List; 38import java.util.logging.Level; 39import java.util.logging.Logger; 40 41/** 42 * DefaultSessionManager manages Session instances persisted to properties 43 * files in the userdir. 44 * 45 * @author Nathan Fiedler 46 */ 47public class DefaultSessionManager extends AbstractSessionManager { 48 49 /** Logger for gracefully reporting unexpected errors. */ 50 private static final Logger logger = Logger.getLogger( 51 DefaultSessionManager.class.getName()); 52 /** The prefix for session identifiers. */ 53 private static final String ID_PREFIX = "SID_"; 54 /** List of the open sessions. */ 55 private List<Session> openSessions; 56 /** The currently selected Session instance. */ 57 private Session currentSession; 58 59 /** 60 * Creates a new instance of SessionManager. 61 */ 62 public DefaultSessionManager() { 63 super(); 64 openSessions = new LinkedList<Session>(); 65 } 66 67 @Override 68 public synchronized void add(Session session) { 69 // Give the session a name, if it doesn't have one already. 70 String name = session.getProperty(Session.PROP_SESSION_NAME); 71 if (name == null || name.length() == 0) { 72 name = generateName(); 73 session.setProperty(Session.PROP_SESSION_NAME, name); 74 } 75 76 openSessions.add(session); 77 if (currentSession == null) { 78 setCurrent(session); 79 } 80 fireEvent(new SessionManagerEvent(this, session, 81 SessionManagerEventType.ADDED)); 82 } 83 84 @Override 85 public synchronized Session copy(Session session, String name) { 86 SessionFactory factory = SessionProvider.getSessionFactory(); 87 String id = generateIdentifier(); 88 Session copy = factory.createSession(id); 89 Iterator<String> keys = session.propertyNames(); 90 while (keys.hasNext()) { 91 String key = keys.next(); 92 String value = session.getProperty(key); 93 copy.setProperty(key, value); 94 } 95 String sessionName = name == null ? generateName() : name; 96 copy.setProperty(Session.PROP_SESSION_NAME, sessionName); 97 openSessions.add(copy); 98 fireEvent(new SessionManagerEvent(this, copy, 99 SessionManagerEventType.ADDED)); 100 return copy; 101 } 102 103 @Override 104 public Session findById(String id) { 105 Iterator<Session> sessions = iterateSessions(); 106 while (sessions.hasNext()) { 107 Session session = sessions.next(); 108 if (session.getIdentifier().equals(id)) { 109 return session; 110 } 111 } 112 return null; 113 } 114 115 @Override 116 public String generateIdentifier() { 117 if (openSessions.isEmpty()) { 118 return ID_PREFIX + '1'; 119 } else { 120 int max = 0; 121 for (Session session : openSessions) { 122 String id = session.getIdentifier(); 123 id = id.substring(ID_PREFIX.length()); 124 try { 125 int i = Integer.parseInt(id); 126 if (i > max) { 127 max = i; 128 } 129 } catch (NumberFormatException nfe) { 130 // This cannot happen as we generate the identifier 131 // and it will always have an integer suffix. 132 } 133 } 134 max++; 135 return ID_PREFIX + max; 136 } 137 } 138 139 @Override 140 public synchronized Session getCurrent() { 141 return currentSession; 142 } 143 144 @Override 145 @SuppressWarnings("unchecked") 146 public synchronized void loadSessions() { 147 // Read the persisted Sessions from disk. 148 XMLDecoder decoder = null; 149 try { 150 PlatformService platform = PlatformProvider.getPlatformService(); 151 String name = "sessions.xml"; 152 InputStream is = platform.readFile(name); 153 decoder = new XMLDecoder(is); 154 decoder.setExceptionListener(new ExceptionListener() { 155 156 @Override 157 public void exceptionThrown(Exception e) { 158 logger.log(Level.SEVERE, null, e); 159 } 160 }); 161 openSessions = (List<Session>) decoder.readObject(); 162 // Get the ID of the current session. 163 String id = (String) decoder.readObject(); 164 Session session = findById(id); 165 if (session != null) { 166 setCurrent(session); 167 } 168 } catch (FileNotFoundException e) { 169 // Do not report this error, it's normal. 170 } catch (Exception e) { 171 // Parser, I/O, and various runtime exceptions may occur, 172 // need to report them and gracefully recover. 173 logger.log(Level.SEVERE, null, e); 174 // SessionProvider will ensure that a current session exists. 175 } finally { 176 if (decoder != null) { 177 decoder.close(); 178 } 179 } 180 } 181 182 @Override 183 public synchronized Iterator<Session> iterateSessions() { 184 // Make sure the caller cannot modify the list. 185 List<Session> ro = Collections.unmodifiableList(openSessions); 186 return ro.iterator(); 187 } 188 189 @Override 190 public synchronized void remove(Session session) { 191 if (currentSession == session) { 192 throw new IllegalArgumentException("cannot delete current session"); 193 } 194 openSessions.remove(session); 195 fireEvent(new SessionManagerEvent(this, session, 196 SessionManagerEventType.REMOVED)); 197 } 198 199 @Override 200 public synchronized void saveSessions(boolean close) { 201 if (close) { 202 for (Session session : openSessions) { 203 if (session.isConnected()) { 204 session.disconnect(false); 205 } 206 session.close(); 207 } 208 } 209 String name = "sessions.xml"; 210 PlatformService platform = PlatformProvider.getPlatformService(); 211 try { 212 OutputStream os = platform.writeFile(name); 213 XMLEncoder encoder = new XMLEncoder(os); 214 encoder.writeObject(openSessions); 215 encoder.writeObject(currentSession.getIdentifier()); 216 encoder.close(); 217 } catch (IOException ioe) { 218 logger.log(Level.SEVERE, null, ioe); 219 } finally { 220 platform.releaseLock(name); 221 } 222 } 223 224 @Override 225 public synchronized void setCurrent(Session session) { 226 currentSession = session; 227 fireEvent(new SessionManagerEvent(this, session, 228 SessionManagerEventType.CURRENT)); 229 } 230}