PageRenderTime 40ms CodeModel.GetById 31ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/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
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}