001: package com.lutris.appserver.server.sessionContainerAdapter;
002:
003: import java.lang.reflect.Method;
004: import java.util.Date;
005: import java.util.Enumeration;
006: import java.util.Set;
007: import java.util.Vector;
008:
009: import javax.management.MBeanServer;
010: import javax.management.MBeanServerFactory;
011: import javax.management.ObjectName;
012: import javax.servlet.http.HttpSession;
013:
014: import com.lutris.appserver.server.Application;
015: import com.lutris.appserver.server.httpPresentation.HttpPresentationComms;
016: import com.lutris.appserver.server.session.Session;
017: import com.lutris.appserver.server.session.SessionException;
018: import com.lutris.appserver.server.session.SessionManager;
019: import com.lutris.appserver.server.sessionEnhydra.CreateSessionException;
020: import com.lutris.appserver.server.user.User;
021:
022: /**
023: * @author Milin Radivoj
024: *
025: * <p>
026: * Description:
027: * </p>
028: * an implementation of ContainerAdapterSessionManager specific to the Tomcat
029: * Servlet container. It uses reflection to obtain data from the Tomcat's
030: * session manager, which really manages the sessions
031: * @version 1.0
032: */
033: public class TomcatContainerAdapterSessionManager extends
034: ContainerAdapterSessionManager {
035:
036: private Object manager;
037:
038: private Method createSession;
039:
040: private Method expireSession;
041:
042: private Method findSession;
043:
044: private Method findSessions;
045:
046: private Method getActiveSessions;
047:
048: private Method getMaxActive;
049:
050: private Method getExpiredSessions;
051:
052: private Application application;
053:
054: private boolean saveOnRestart = false;
055:
056: private int maxSessions = -1;
057:
058: private boolean initialized = false;
059:
060: public TomcatContainerAdapterSessionManager(
061: com.lutris.appserver.server.Application application,
062: com.lutris.util.Config config,
063: com.lutris.logging.LogChannel logger)
064: throws com.lutris.appserver.server.session.SessionException {
065: super (application, config, logger);
066: this .application = application;
067:
068: try {
069: if (config.containsKey("SessionHome.SaveOnRestart")) {
070: saveOnRestart = config.getBoolean(
071: "SessionHome.SaveOnRestart", false);
072: }
073: } catch (com.lutris.util.ConfigException e) {
074: throw new com.lutris.appserver.server.session.SessionException(
075: e);
076: }
077:
078: try {
079: if (config.containsKey("SessionHome.MaxSessions")) {
080: maxSessions = config.getInt("SessionHome.MaxSessions");
081: }
082: } catch (com.lutris.util.ConfigException e) {
083: throw new com.lutris.appserver.server.session.SessionException(
084: e);
085: }
086: }
087:
088: /**
089: * Creates a new session
090: *
091: * @return Seession
092: * @throws SessionException
093: */
094: public Session createSession()
095: throws com.lutris.appserver.server.session.SessionException {
096:
097: if (!initialized)
098: initialize();
099:
100: HttpSession httpSession;
101:
102: try {
103: httpSession = (HttpSession) createSession.invoke(manager,
104: new Object[] {});
105: } catch (Exception e) {
106: throw new CreateSessionException(
107: "New session cannot be instantiated "
108: + e.getMessage());
109: }
110: if (httpSession != null) {
111: ContainerAdapterSession enhydraSession = new ContainerAdapterSession(
112: this , httpSession);
113: httpSession.setAttribute(SESSION, enhydraSession);
114: httpSession.setMaxInactiveInterval(maxSessionIdleTime);
115:
116: return enhydraSession;
117: } else {
118: throw new CreateSessionException(
119: "New session cannot be instantiated");
120: }
121: }
122:
123: /**
124: * Not implemented
125: *
126: * @return
127: */
128: public Session createSession(String ipPortToken)
129: throws com.lutris.appserver.server.session.SessionException {
130:
131: /** No need to implement this method - used only for Director */
132: throw new java.lang.UnsupportedOperationException(
133: "Method createSession(String ipPortToken) not implemented.");
134: }
135:
136: /**
137: * Creates a new session
138: *
139: * @return Seession
140: * @throws SessionException
141: */
142: public Session createSession(HttpPresentationComms comms)
143: throws com.lutris.appserver.server.session.SessionException {
144:
145: if (!initialized)
146: initialize();
147:
148: return super .createSession(comms);
149: }
150:
151: /**
152: * Delete existing session
153: *
154: * @return
155: * @throws SessionException
156: */
157: public void deleteSession(Session parm1)
158: throws com.lutris.appserver.server.session.SessionException {
159: if (!initialized)
160: initialize();
161: try {
162: expireSession.invoke(manager, new Object[] { parm1
163: .getSessionKey() });
164: } catch (Exception e) {
165: throw new SessionException("Session cannot be deleteded "
166: + e.getMessage());
167: }
168:
169: }
170:
171: /**
172: * Delete existing session
173: *
174: * @return
175: * @throws SessionException
176: */
177: public void deleteSession(String parm1)
178: throws com.lutris.appserver.server.session.SessionException {
179: if (!initialized)
180: initialize();
181: try {
182: expireSession.invoke(manager, new Object[] { parm1 });
183: } catch (Exception e) {
184: throw new SessionException("Session cannot be deleteded "
185: + e.getMessage());
186: }
187: }
188:
189: /**
190: * Lookup the <code>Session</code> object associated with the specified
191: * session key.
192: * <P>
193: *
194: *
195: * @param sessionKey
196: * The String used to reference a <code>Session</code> object.
197: * @return If the key is associated with an active session, then the
198: * corresponding <code>Session</code> object is returned.
199: * Otherwise <code>null</code> is returned.
200: * @exception SessionException
201: * If the session cannot be retrieved.
202: */
203: public Session getSession(String sessionId)
204: throws com.lutris.appserver.server.session.SessionException {
205:
206: if (!initialized)
207: initialize();
208: HttpSession httpSession;
209:
210: try {
211: httpSession = (HttpSession) findSession.invoke(manager,
212: new Object[] { sessionId });
213: } catch (Exception e) {
214: throw new SessionException(
215: "Problem while lookup for session "
216: + e.getMessage());
217: }
218:
219: Session enhydraSession = null;
220:
221: if (httpSession != null) {
222:
223: try {
224: enhydraSession = (Session) httpSession
225: .getAttribute(SESSION);
226: } catch (IllegalStateException ex) {
227: //it's ok session is expired
228: return null;
229: }
230: if (enhydraSession != null) {
231: chackSessionManager(enhydraSession);
232: enhydraSession.setHttpSession(httpSession);
233: }
234: return enhydraSession;
235: } else {
236: return null;
237: }
238: }
239:
240: /**
241: * Lookup the <code>Session</code> object associated with the specified
242: * session key.
243: * <P>
244: *
245: *
246: * @param sessionKey
247: * The String used to reference a <code>Session</code> object.
248: * @return If the key is associated with an active session, then the
249: * corresponding <code>Session</code> object is returned.
250: * Otherwise <code>null</code> is returned.
251: * @exception SessionException
252: * If the session cannot be retrieved.
253: */
254:
255: public Session getSession(Thread parm1, String sessionId)
256: throws com.lutris.appserver.server.session.SessionException {
257: return getSession(sessionId);
258: }
259:
260: /**
261: * Returns teh session object corresponding to the HttpPresentationComms
262: *
263: * @param parm1
264: * ignored
265: * @param sessionId
266: * ignored
267: * @param comms
268: * HttpPresentationComms object that contains HttpServletRequest
269: * from which the session is extracted
270: * @return the Session object
271: * @throws SessionException
272: */
273: public Session getSession(Thread parm1, String sessionId,
274: HttpPresentationComms comms)
275: throws com.lutris.appserver.server.session.SessionException {
276:
277: if (!initialized)
278: initialize();
279:
280: return super .getSession(parm1, sessionId, comms);
281: }
282:
283: /**
284: * Get all of the active sessions Keys.
285: *
286: * @return An enumeration of the active sessions Keys.
287: * @exception SessionException
288: * If the sessions cannot be retrieved.
289: */
290: public Enumeration getSessionKeys(User parm1)
291: throws com.lutris.appserver.server.session.SessionException {
292:
293: if (!initialized)
294: initialize();
295:
296: HttpSession[] httpSession;
297: try {
298: httpSession = (HttpSession[]) findSessions.invoke(manager,
299: new Object[] {});
300:
301: } catch (Exception e) {
302: throw new SessionException(
303: "Problem while lookup for session Keys "
304: + e.getMessage());
305: }
306:
307: Vector list = new Vector();
308:
309: if (httpSession != null) {
310:
311: for (int i = 0; i < httpSession.length; i++) {
312: Session enhydraSession = null;
313:
314: try {
315: enhydraSession = (Session) httpSession[i]
316: .getAttribute(SESSION);
317: } catch (IllegalStateException ex) {
318: //it's ok session is expired
319: continue;
320: }
321: User user = enhydraSession.getUser();
322: if (user != null && parm1 != null
323: && parm1.getName() != null
324: && user.getName() != null
325: && parm1.getName().equals(user.getName()))
326: list.add(httpSession[i].getId());
327: }
328:
329: return list.elements();
330:
331: } else {
332: return list.elements();
333: }
334: }
335:
336: /**
337: * Gets the number of currently active sessions.
338: *
339: * @return The number of currently active sessions.
340: * @exception SessionException
341: *
342: */
343: public int activeSessionCount()
344: throws com.lutris.appserver.server.session.SessionException {
345:
346: if (!initialized)
347: initialize();
348: Integer count;
349:
350: try {
351: count = (Integer) getActiveSessions.invoke(manager,
352: new Object[] {});
353: } catch (Exception e) {
354: throw new SessionException(
355: "Problem while lookup for active session count "
356: + e.getMessage());
357: }
358: return count.intValue();
359: }
360:
361: /**
362: *
363: * @return the number of expired sessions (not including the sessions forced
364: * to expire), or -1 if it can not be determined
365: * @throws SessionException
366: */
367: public int expiredSessionCount()
368: throws com.lutris.appserver.server.session.SessionException {
369: if (!initialized)
370: initialize();
371: Integer count;
372: try {
373: count = (Integer) getExpiredSessions.invoke(manager,
374: new Object[] {});
375: } catch (Exception e) {
376: return -1;
377: }
378:
379: return count.intValue();
380: }
381:
382: /**
383: * Gets the maximum number of concurent sessions that existed at any time
384: *
385: * @return The number of sessions, or -1.
386: */
387: public int maxSessionCount() {
388:
389: Integer count;
390: try {
391: if (!initialized)
392: initialize();
393: count = (Integer) getMaxActive.invoke(manager,
394: new Object[] {});
395: } catch (Exception e) {
396: return -1;
397: }
398: return count.intValue();
399:
400: }
401:
402: /**
403: * Not implemented
404: *
405: * @return
406: */
407: public Date maxSessionCountDate() {
408:
409: /** Not implemented */
410: throw new java.lang.UnsupportedOperationException(
411: "Method maxSessionCountDate() not implemented.");
412: }
413:
414: /**
415: * Reset the maximum session count. See <CODE>maxSessionCount()</CODE>.
416: * The highwater mark should be reset to the current number of sessions.
417: *
418: * @exception SessionException
419: * if the max session count cannot be reset.
420: */
421:
422: public void resetMaxSessionCount()
423: throws com.lutris.appserver.server.session.SessionException {
424:
425: try {
426:
427: Method setMaxActive = manager.getClass().getMethod(
428: "setMaxActive", new Class[] { int.class });
429:
430: int current = activeSessionCount();
431:
432: setMaxActive.invoke(manager, new Object[] { new Integer(
433: current) });
434:
435: } catch (Exception e) {
436: throw new SessionException(
437: "Problem while reset Max Session Count "
438: + e.getMessage());
439: }
440: }
441:
442: /**
443: * Get all of the active sessions Keys.
444: *
445: * @return An enumeration of the active sessions Keys.
446: * @exception SessionException
447: * If the sessions cannot be retrieved.
448: */
449: public Enumeration getSessionKeys()
450: throws com.lutris.appserver.server.session.SessionException {
451:
452: if (!initialized)
453: initialize();
454: Object[] httpSession;
455:
456: try {
457: httpSession = (Object[]) findSessions.invoke(manager,
458: new Object[] {});
459: } catch (Exception e) {
460: throw new SessionException(
461: "Problem while lookup for session Keys "
462: + e.getMessage());
463: }
464:
465: Vector list = new Vector();
466:
467: if (httpSession != null) {
468:
469: for (int i = 0; i < httpSession.length; i++) {
470: list.add(((HttpSession) httpSession[i]).getId());
471: }
472: return list.elements();
473: } else {
474: return list.elements();
475: }
476:
477: }
478:
479: public void initialize()
480: throws com.lutris.appserver.server.session.SessionException {
481: try {
482:
483: MBeanServer mBeanServer = findMBeanServer();
484: Object current = application.getClass().getClassLoader();
485:
486: ObjectName oname = new ObjectName("*:j2eeType=WebModule,*");
487:
488: Set moduls = mBeanServer.queryNames(oname, null);
489: Object[] o = (Object[]) moduls.toArray();
490:
491: for (int j = 0; j < o.length; j++) {
492:
493: Object context = (Object) mBeanServer.invoke(
494: (ObjectName) o[j], "findMappingObject",
495: new Object[] {}, new String[] {});
496:
497: Method getLoader = context.getClass().getMethod(
498: "getLoader", new Class[] {});
499:
500: Object webAppLoader = getLoader.invoke(context,
501: new Object[] {});
502:
503: Method getClassLoader = null;
504: getClassLoader = webAppLoader.getClass().getMethod(
505: "getClassLoader", new Class[] {});
506: Object webAppClassLoader = getClassLoader.invoke(
507: webAppLoader, new Object[] {});
508:
509: if (webAppClassLoader.equals(current)) {
510:
511: Method getManager = context.getClass().getMethod(
512: "getManager", new Class[] {});
513:
514: manager = getManager.invoke(context,
515: new Object[] {});
516:
517: createSession = manager.getClass().getMethod(
518: "createSession", new Class[] {});
519: expireSession = manager.getClass().getMethod(
520: "expireSession",
521: new Class[] { String.class });
522: findSession = manager.getClass()
523: .getMethod("findSession",
524: new Class[] { String.class });
525: findSessions = manager.getClass().getMethod(
526: "findSessions", new Class[] {});
527: getActiveSessions = manager.getClass().getMethod(
528: "getActiveSessions", new Class[] {});
529: getMaxActive = manager.getClass().getMethod(
530: "getMaxActive", new Class[] {});
531:
532: getExpiredSessions = manager.getClass().getMethod(
533: "getExpiredSessions", new Class[] {});
534:
535: if (!saveOnRestart) {
536: try {
537: Method setPathname = manager
538: .getClass()
539: .getMethod(
540: "setPathname",
541: new Class[] { String.class });
542:
543: setPathname.invoke(manager,
544: new Object[] { null });
545: } catch (Exception e) {
546: //it`s OK
547: }
548: }
549:
550: if (maxSessions > 0) {
551: try {
552: Method setMaxActiveSessions = manager
553: .getClass().getMethod(
554: "setMaxActiveSessions",
555: new Class[] { int.class });
556:
557: setMaxActiveSessions.invoke(manager,
558: new Object[] { new Integer(
559: maxSessions) });
560: } catch (Exception e) {
561: //it`s OK
562: }
563: }
564:
565: initialized = true;
566: return;
567: }
568: }
569:
570: } catch (Exception e) {
571: throw new SessionException(
572: "Problem in initialization of TomcatContainerAdapterSessionManager : "
573: + e.getMessage());
574: }
575:
576: }
577:
578: private MBeanServer findMBeanServer() {
579: MBeanServer mBeanServer;
580: try {
581: java.util.ArrayList server = MBeanServerFactory
582: .findMBeanServer(null);
583: if (server == null) {
584: return null;
585: } else {
586: mBeanServer = (MBeanServer) server.get(0);
587: }
588: } catch (Exception e) {
589: mBeanServer = null;
590: }
591: return mBeanServer;
592: }
593:
594: /**
595: *
596: */
597: public void shutdown() {
598: super .shutdown();
599: initialized = false;
600: application = null;
601: manager = null;
602: createSession = null;
603: expireSession = null;
604: findSession = null;
605: findSessions = null;
606: getActiveSessions = null;
607: getMaxActive = null;
608: getExpiredSessions = null;
609: }
610:
611: private void chackSessionManager(Session session) {
612:
613: SessionManager sessionManager = session.getSessionManager();
614:
615: if (sessionManager == null) {
616: ((ContainerAdapterSession) session).setSessionManager(this);
617: }
618: }
619: }
|