001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/security/session/MemoryBasedSessionManager.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.security.session;
037    
038    import java.net.URL;
039    import java.util.Collections;
040    import java.util.HashMap;
041    import java.util.Iterator;
042    import java.util.Map;
043    
044    /**
045     * This exception shall be thrown when a session(ID) will be used that has been expired.
046     *
047     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
048     * @author last edited by: $Author: mschneider $
049     *
050     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
051     */
052    
053    public class MemoryBasedSessionManager implements SessionManager {
054    
055        private Map<String, Session> sessionsById = Collections.synchronizedMap( new HashMap<String, Session>( 100 ) );
056    
057        private Map<String, Session> sessionsByUser = Collections.synchronizedMap( new HashMap<String, Session>( 100 ) );
058    
059        private static URL config = null;
060    
061        private static MemoryBasedSessionManager self = null;
062    
063        /**
064         * realizes Singelton pattern <br>
065         * returns an instance of the <tt>SessionManager</tt>. Before this method can be invoked
066         *
067         * @return single instance of SessionManager in a JVM
068         */
069        public synchronized static MemoryBasedSessionManager getInstance() {
070            if ( self == null ) {
071                self = new MemoryBasedSessionManager( config );
072            }
073            return self;
074        }
075    
076        /**
077         * creates a session that never expires for a named user who will be authentificated through his name and password.
078         * If the user doesn't exists or the passwoed is invalid for an existing user an exception will be thrown.
079         *
080         * @param user
081         *            user name
082         * @return the session
083         */
084        public static Session createSession( String user ) {
085            return createSession( user, -1 );
086        }
087    
088        /**
089         * creates a session for a named user who will be authentificated through his name and password. The session expires
090         * after the passed duration after the last access to it. If the user doesn't exists or the passwoed is invalid for
091         * an existing user an exception will be thrown.
092         *
093         * @param user
094         *            user name
095         * @param duration
096         * @return the session
097         */
098        public static Session createSession( String user, int duration ) {
099    
100            Session ses = new Session( user, duration );
101            try {
102                MemoryBasedSessionManager.getInstance().addSession( ses );
103            } catch ( Exception e ) {
104                e.printStackTrace();
105            }
106            return ses;
107        }
108    
109        /**
110         * creates a session for an anonymous user that never expires
111         *
112         * @return the session
113         */
114        public static Session createSession() {
115            return createSession( -1 );
116        }
117    
118        /**
119         * creates a session for an anonymous user that expires after the passed duration after the last access to it.
120         *
121         * @param duration
122         * @return the session
123         */
124        public static Session createSession( int duration ) {
125            Session ses = new Session( duration );
126            try {
127                MemoryBasedSessionManager.getInstance().addSession( ses );
128            } catch ( Exception e ) {
129                e.printStackTrace();
130            }
131            return ses;
132        }
133    
134        /**
135         * private constructor. just to be used by the initSessionManager method
136         *
137         * @param config
138         */
139        private MemoryBasedSessionManager( URL config ) {
140            MemoryBasedSessionManager.config = config;
141        }
142    
143        /**
144         * returns the session identified by its ID. If no session with the passed ID is known <tt>null</tt> will be
145         * returned. If the requested session isn't alive anymore it will be removed from the session manager
146         *
147         * @param id
148         * @return the session identified by its ID. If no session with the passed ID is known <tt>null</tt> will be
149         *         returned.
150         * @throws SessionStatusException
151         */
152        public Session getSessionByID( String id )
153                                throws SessionStatusException {
154            Session ses = sessionsById.get( id );
155            if ( ses != null ) {
156                if ( !ses.isAlive() ) {
157                    removeSessionByID( id );
158                } else {
159                    ses.reset();
160                }
161            }
162            return ses;
163        }
164    
165        /**
166         * returns the session assigned to the passed user. If no session is assigend to the passed user <tt>null</tt> will
167         * be returned. If the requested session isn't alive anymore it will be removed from the session manager
168         *
169         * @param user
170         * @return the session assigned to the passed user. If no session is assigend to the passed user <tt>null</tt> will
171         *         be returned.
172         */
173        public Session getSessionByUser( String user )
174                                throws SessionStatusException {
175            Session ses = sessionsByUser.get( user );
176            if ( ses != null ) {
177                if ( !ses.isAlive() ) {
178                    removeSessionByID( ses.getSessionID().getId() );
179                } else {
180                    ses.reset();
181                }
182            }
183            return ses;
184        }
185    
186        /**
187         * adds a session to the session managment. the session will be stored within two lists. one addresses the session
188         * with its ID the other with its user name. If the session is anonymous it just will be stored in the first list.
189         *
190         * @param session
191         * @throws SessionStatusException
192         */
193        public void addSession( Session session )
194                                throws SessionStatusException {
195            if ( session.getUser() != null ) {
196                sessionsByUser.put( session.getUser(), session );
197            }
198            try {
199                sessionsById.put( session.getSessionID().getId(), session );
200            } catch ( Exception e ) {
201                throw new SessionStatusException( "can't add session to session manager:\n" + e.getMessage() );
202            }
203        }
204    
205        /**
206         * removes a session identified by its ID from the session managment. the removed session will be returned.
207         *
208         * @param id
209         * @return the session
210         */
211        public Session removeSessionByID( String id ) {
212            Session ses = sessionsById.remove( id );
213            if ( ses != null && ses.getUser() != null ) {
214                sessionsByUser.remove( ses.getUser() );
215            }
216            return ses;
217        }
218    
219        /**
220         * removes all sessions that are expired from the session management
221         */
222        public synchronized void clearExpired() {
223            synchronized ( sessionsById ) {
224                synchronized ( sessionsByUser ) {
225                    Iterator<String> ids = sessionsById.keySet().iterator();
226                    while ( ids.hasNext() ) {
227                        Object key = ids.next();
228                        Session ses = sessionsById.get( key );
229                        if ( !ses.isAlive() ) {
230                            sessionsById.remove( key );
231                            if ( ses.getUser() != null ) {
232                                sessionsByUser.remove( ses.getUser() );
233                            }
234                        }
235                    }
236                }
237            }
238    
239        }
240    
241    }