001: package clime.messadmin.model;
002:
003: import java.security.Principal;
004: import java.util.ArrayList;
005: import java.util.Date;
006: import java.util.Enumeration;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.List;
010: import java.util.Locale;
011: import java.util.Map;
012: import java.util.NoSuchElementException;
013:
014: import javax.servlet.ServletContext;
015: import javax.servlet.http.HttpSession;
016: import javax.servlet.http.HttpSessionContext;
017:
018: import clime.messadmin.providers.ProviderUtils;
019: import clime.messadmin.providers.spi.LocaleProvider;
020: import clime.messadmin.providers.spi.SerializableProvider;
021: import clime.messadmin.providers.spi.SessionDataProvider;
022: import clime.messadmin.providers.spi.SizeOfProvider;
023: import clime.messadmin.providers.spi.UserNameProvider;
024: import clime.messadmin.utils.SimpleEntry;
025:
026: /**
027: * Stores/computes extra informations related to a session, such as the ones from requests
028: * Takes care of HttpSession-related stats.
029: * @author Cédrik LIME
030: */
031: public class SessionInfo implements ISessionInfo {
032: private HttpSession httpSession;
033: private String id;
034: private ClassLoader classLoader;
035:
036: protected final RequestInfo cumulativeRequestStats = new RequestInfo(
037: null);
038:
039: // cache from ServletRequest and HttpServletRequest
040: protected Principal userPrincipal;
041: protected String remoteUser;
042: protected String remoteHost;
043: protected String lastRequestURL;
044: protected boolean isSecure = false;
045: protected String userAgent;
046: protected String authType;
047: protected String referer;
048: // If a request has been transmitted over a secure protocol, such as HTTPS, this
049: // information must be exposed via the isSecure method of the ServletRequest
050: // interface. The web container must expose the following attributes to the servlet
051: // programmer:
052: protected String sslCipherSuite;
053: protected Integer sslAlgorithmSize;
054:
055: // The order of this array is defined as being in ascending order of trust. The first
056: // certificate in the chain is the one set by the client, the next is the one used to
057: // authenticate the first, and so on.
058: //protected X509Certificate[] sslCertificates;
059:
060: /**
061: *
062: */
063: public SessionInfo() {
064: super ();
065: // for (int i = 0; i < responseStatus.length; ++i) {
066: // responseStatus[i] = new HitsCounter();
067: // }
068: }
069:
070: /**
071: *
072: */
073: public SessionInfo(HttpSession session) {
074: this ();
075: httpSession = session;
076: id = session.getId();
077: }
078:
079: /**
080: *
081: */
082: public SessionInfo(HttpSession session, ClassLoader cl) {
083: this (session);
084: classLoader = cl;
085: }
086:
087: protected HttpSession getHttpSession() {
088: return httpSession;
089: }
090:
091: protected void setHttpSession(HttpSession session) {
092: httpSession = session;
093: }
094:
095: ClassLoader getClassLoader() {
096: return classLoader;
097: }
098:
099: void setClassLoader(ClassLoader cl) {
100: classLoader = cl;
101: }
102:
103: /** {@inheritDoc} */
104: public Map getAttributes() {
105: Map result = new HashMap();
106: Enumeration enumeration = getAttributeNames();
107: while (enumeration.hasMoreElements()) {
108: String name = (String) enumeration.nextElement();
109: Object value = getAttribute(name);
110: result.put(name, value);
111: }
112: return result;
113: }
114:
115: /** {@inheritDoc} */
116: public boolean isSerializable() {
117: try {
118: /*
119: Enumeration enumeration = getAttributeNames();
120: IdentityHashMap visitedObjects = new IdentityHashMap();
121: while (enumeration.hasMoreElements()) {
122: String attributeName = (String) enumeration.nextElement();
123: Object attributeValue = getAttribute(attributeName);
124: if (! SerializableUtils.isMaybeSerializable(attributeValue, visitedObjects)) {
125: return false;
126: }
127: }
128: */
129: Enumeration enumeration = getAttributeNames();
130: while (enumeration.hasMoreElements()) {
131: String attributeName = (String) enumeration
132: .nextElement();
133: Object attributeValue = getAttribute(attributeName);
134: if (!SerializableProvider.Util.isSerializable(
135: attributeValue, classLoader)) {
136: return false;
137: }
138: }
139: return true;
140: } catch (RuntimeException rte) {
141: return false;
142: }
143: }
144:
145: /** {@inheritDoc} */
146: public long getSize() {
147: Object objectToSize = null;
148: try {
149: // when sizing an HttpSession, we are really only interested in its attributes!
150: if (httpSession != null) {
151: Map attributes = new HashMap();
152: Enumeration enumeration = httpSession
153: .getAttributeNames();
154: while (enumeration.hasMoreElements()) {
155: String name = (String) enumeration.nextElement();
156: Object attribute = httpSession.getAttribute(name);
157: attributes.put(name, attribute);
158: }
159: objectToSize = attributes;
160: }
161: return SizeOfProvider.Util.getObjectSize(objectToSize,
162: classLoader);
163: } catch (IllegalStateException ise) {
164: // Session is invalidated: do nothing
165: return -1;
166: }
167: }
168:
169: /** {@inheritDoc} */
170: public int getNErrors() {
171: return cumulativeRequestStats.getNErrors();
172: }
173:
174: /** {@inheritDoc} */
175: public ErrorData getLastError() {
176: return cumulativeRequestStats.getLastError();
177: }
178:
179: /**
180: * {@inheritDoc}
181: */
182: public String getLastRequestURL() {
183: return lastRequestURL;
184: }
185:
186: /**
187: * {@inheritDoc}
188: */
189: public String getRemoteHost() {
190: return remoteHost;
191: }
192:
193: /**
194: * {@inheritDoc}
195: */
196: public Principal getUserPrincipal() {
197: return userPrincipal;
198: }
199:
200: /**
201: * {@inheritDoc}
202: */
203: public String getRemoteUser() {
204: return remoteUser;
205: }
206:
207: public void setRemoteUser(String remoteUser) {
208: this .remoteUser = remoteUser;
209: }
210:
211: /**
212: * {@inheritDoc}
213: */
214: public int getHits() {
215: return cumulativeRequestStats.getHits();// hits;
216: }
217:
218: /**
219: * {@inheritDoc}
220: */
221: public long getRequestLastLength() {
222: return cumulativeRequestStats.getRequestLastLength();
223: }
224:
225: /**
226: * {@inheritDoc}
227: */
228: public long getResponseLastLength() {
229: return cumulativeRequestStats.getResponseLastLength();
230: }
231:
232: /**
233: * {@inheritDoc}
234: */
235: public long getRequestMinLength() {
236: return cumulativeRequestStats.getRequestMinLength();
237: }
238:
239: /**
240: * {@inheritDoc}
241: */
242: public long getResponseMinLength() {
243: return cumulativeRequestStats.getResponseMinLength();
244: }
245:
246: /**
247: * {@inheritDoc}
248: */
249: public Date getRequestMinLengthDate() {
250: return cumulativeRequestStats.getRequestMinLengthDate();
251: }
252:
253: /**
254: * {@inheritDoc}
255: */
256: public Date getResponseMinLengthDate() {
257: return cumulativeRequestStats.getResponseMinLengthDate();
258: }
259:
260: /**
261: * {@inheritDoc}
262: */
263: public long getRequestMaxLength() {
264: return cumulativeRequestStats.getRequestMaxLength();
265: }
266:
267: /**
268: * {@inheritDoc}
269: */
270: public long getResponseMaxLength() {
271: return cumulativeRequestStats.getResponseMaxLength();
272: }
273:
274: /**
275: * {@inheritDoc}
276: */
277: public Date getRequestMaxLengthDate() {
278: return cumulativeRequestStats.getRequestMaxLengthDate();
279: }
280:
281: /**
282: * {@inheritDoc}
283: */
284: public Date getResponseMaxLengthDate() {
285: return cumulativeRequestStats.getResponseMaxLengthDate();
286: }
287:
288: /**
289: * {@inheritDoc}
290: */
291: public long getRequestTotalLength() {
292: return cumulativeRequestStats.getRequestTotalLength();
293: }
294:
295: /**
296: * {@inheritDoc}
297: */
298: public long getResponseTotalLength() {
299: return cumulativeRequestStats.getResponseTotalLength();
300: }
301:
302: /**
303: * {@inheritDoc}
304: */
305: public double getRequestMeanLength() {
306: return cumulativeRequestStats.getRequestMeanLength();
307: }
308:
309: /**
310: * {@inheritDoc}
311: */
312: public double getResponseMeanLength() {
313: return cumulativeRequestStats.getResponseMeanLength();
314: }
315:
316: /**
317: * {@inheritDoc}
318: */
319: public double getRequestStdDevLength() {
320: return cumulativeRequestStats.getRequestStdDevLength();
321: }
322:
323: /**
324: * {@inheritDoc}
325: */
326: public double getResponseStdDevLength() {
327: return cumulativeRequestStats.getResponseStdDevLength();
328: }
329:
330: /**
331: * {@inheritDoc}
332: */
333: public Date getLastRequestDate() {
334: return cumulativeRequestStats.getLastRequestDate(); //requestLength.getLastAccessTime();
335: }
336:
337: /**
338: * {@inheritDoc}
339: */
340: public Date getLastResponseDate() {
341: return cumulativeRequestStats.getLastResponseDate(); //responseLength.getLastAccessTime();
342: }
343:
344: /**
345: * {@inheritDoc}
346: */
347: public boolean isSecure() {
348: return isSecure;
349: }
350:
351: /**
352: * {@inheritDoc}
353: */
354: public String getUserAgent() {
355: return userAgent;
356: }
357:
358: /**
359: * {@inheritDoc}
360: */
361: public String getAuthType() {
362: return authType;
363: }
364:
365: /**
366: * {@inheritDoc}
367: */
368: public String getReferer() {
369: return referer;
370: }
371:
372: /**
373: * {@inheritDoc}
374: */
375: public int getLastResponseStatus() {
376: return cumulativeRequestStats.getLastResponseStatus();
377: }
378:
379: /**
380: * {@inheritDoc}
381: */
382: public int getLastUsedTime() {
383: return (int) cumulativeRequestStats.getLastUsedTime();
384: }
385:
386: /**
387: * {@inheritDoc}
388: */
389: public int getMinUsedTime() {
390: return (int) cumulativeRequestStats.getMinUsedTime();
391: }
392:
393: /**
394: * {@inheritDoc}
395: */
396: public Date getMinUsedTimeDate() {
397: return cumulativeRequestStats.getMinUsedTimeDate();
398: }
399:
400: /**
401: * {@inheritDoc}
402: */
403: public int getMaxUsedTime() {
404: return (int) cumulativeRequestStats.getMaxUsedTime();
405: }
406:
407: /**
408: * {@inheritDoc}
409: */
410: public Date getMaxUsedTimeDate() {
411: return cumulativeRequestStats.getMaxUsedTimeDate();
412: }
413:
414: /**
415: * {@inheritDoc}
416: */
417: public int getTotalUsedTime() {
418: return (int) cumulativeRequestStats.getTotalUsedTime();
419: }
420:
421: /**
422: * {@inheritDoc}
423: */
424: public double getMeanUsedTime() {
425: return cumulativeRequestStats.getMeanUsedTime();
426: }
427:
428: /**
429: * {@inheritDoc}
430: */
431: public double getStdDevUsedTime() {
432: return cumulativeRequestStats.getStdDevUsedTime();
433: }
434:
435: /**
436: * {@inheritDoc}
437: */
438: public Locale getGuessedLocale() {
439: return LocaleProvider.Util.guessLocaleFromSession(httpSession,
440: classLoader);
441: }
442:
443: /**
444: * {@inheritDoc}
445: */
446: public Object getGuessedUser() {
447: return UserNameProvider.Util.guessUserFromSession(httpSession,
448: classLoader);
449: }
450:
451: /**
452: * {@inheritDoc}
453: */
454: public int getIdleTime() {
455: try {
456: long diffMilliSeconds = System.currentTimeMillis()
457: - getLastAccessedTime();
458: return (int) diffMilliSeconds;
459: } catch (IllegalStateException ise) {
460: //ignore: invalidated session
461: return -1;
462: }
463: }
464:
465: /**
466: * {@inheritDoc}
467: */
468: public int getTTL() {
469: try {
470: long diffMilliSeconds = (1000 * getMaxInactiveInterval())
471: - (System.currentTimeMillis() - getLastAccessedTime());
472: return (int) diffMilliSeconds;
473: } catch (IllegalStateException ise) {
474: //ignore: invalidated session
475: return -1;
476: }
477: }
478:
479: /**
480: * {@inheritDoc}
481: */
482: public int getAge() {
483: try {
484: long diffMilliSeconds = getLastAccessedTime()
485: - getCreationTime();
486: return (int) diffMilliSeconds;
487: } catch (IllegalStateException ise) {
488: //ignore: invalidated session
489: return -1;
490: }
491: }
492:
493: /**
494: * {@inheritDoc}
495: */
496: public List getSessionSpecificData() {
497: Iterator iter = ProviderUtils.getProviders(
498: SessionDataProvider.class, classLoader).iterator();
499: List result = new ArrayList();
500: while (iter.hasNext()) {
501: SessionDataProvider sd = (SessionDataProvider) iter.next();
502: try {
503: String title = sd.getSessionDataTitle(httpSession);
504: String xhtml = sd.getXHTMLSessionData(httpSession);
505: if (title != null && xhtml != null) {
506: result.add(new SimpleEntry(title, xhtml));
507: }
508: } catch (RuntimeException rte) {
509: result
510: .add(new SimpleEntry(sd.getClass().getName(),
511: rte));
512: }
513: }
514: return result;
515: }
516:
517: /**
518: * {@inheritDoc}
519: */
520: public String getSslCipherSuite() {
521: return sslCipherSuite;
522: }
523:
524: /**
525: * {@inheritDoc}
526: */
527: public Integer getSslAlgorithmSize() {
528: return sslAlgorithmSize;
529: }
530:
531: // /**
532: // * {@inheritDoc}
533: // */
534: // public X509Certificate[] getSslCertificates() {
535: // return sslCertificates;
536: // }
537:
538: /*********************************************************************/
539: /*** HttpSession wrapped methods; no not call when passivated! **/
540: /*********************************************************************/
541:
542: /**
543: * A enumerator class for empty session attributes, specializes
544: * the general Enumerator
545: */
546: private static class EmptyEnumerator implements Enumeration {
547: static final Enumeration INSTANCE = new EmptyEnumerator();
548:
549: private EmptyEnumerator() {
550: }
551:
552: /** {@inheritDoc} */
553: public boolean hasMoreElements() {
554: return false;
555: }
556:
557: /** {@inheritDoc} */
558: public Object nextElement() {
559: throw new NoSuchElementException(
560: "SessionAttribute Enumerator");//$NON-NLS-1$
561: }
562: }
563:
564: /**
565: * {@inheritDoc}
566: */
567: public Object getAttribute(String name) {
568: try {
569: return (httpSession == null) ? null : httpSession
570: .getAttribute(name);
571: } catch (IllegalStateException ise) {
572: //ignore: invalidated session
573: return null;
574: }
575: }
576:
577: /**
578: * {@inheritDoc}
579: */
580: public Enumeration getAttributeNames() {
581: try {
582: return (httpSession == null) ? EmptyEnumerator.INSTANCE
583: : httpSession.getAttributeNames();
584: } catch (IllegalStateException ise) {
585: //ignore: invalidated session
586: return EmptyEnumerator.INSTANCE;
587: }
588: }
589:
590: /**
591: * {@inheritDoc}
592: */
593: public long getCreationTime() {
594: try {
595: return (httpSession == null) ? -1 : httpSession
596: .getCreationTime();
597: } catch (IllegalStateException ise) {
598: //ignore: invalidated session
599: return -1;
600: }
601: }
602:
603: /**
604: * {@inheritDoc}
605: */
606: public String getId() {
607: return id;//httpSession.getId();
608: }
609:
610: /**
611: * {@inheritDoc}
612: */
613: public long getLastAccessedTime() {
614: try {
615: return (httpSession == null) ? -1 : httpSession
616: .getLastAccessedTime();
617: } catch (IllegalStateException ise) {
618: //ignore: invalidated session
619: return -1;
620: }
621: }
622:
623: /**
624: * {@inheritDoc}
625: */
626: public int getMaxInactiveInterval() {
627: try {
628: return (httpSession == null) ? -1 : httpSession
629: .getMaxInactiveInterval();
630: } catch (IllegalStateException ise) {
631: //ignore: invalidated session
632: return 0;
633: }
634: }
635:
636: /**
637: * {@inheritDoc}
638: */
639: public ServletContext getServletContext() {
640: return httpSession.getServletContext();
641: }
642:
643: /**
644: * {@inheritDoc}
645: */
646: public void invalidate() {
647: httpSession.invalidate();
648: }
649:
650: /**
651: * {@inheritDoc}
652: */
653: public boolean isNew() {
654: try {
655: return (httpSession == null) ? false : httpSession.isNew();
656: } catch (IllegalStateException ise) {
657: //ignore: invalidated session
658: return false;
659: }
660: }
661:
662: /**
663: * {@inheritDoc}
664: */
665: public void removeAttribute(String name) {
666: try {
667: if (httpSession != null) {
668: httpSession.removeAttribute(name);
669: }
670: } catch (IllegalStateException ise) {
671: //ignore: invalidated session
672: }
673: }
674:
675: /**
676: * {@inheritDoc}
677: */
678: public void setAttribute(String name, Object value) {
679: try {
680: if (httpSession != null) {
681: httpSession.setAttribute(name, value);
682: }
683: } catch (IllegalStateException ise) {
684: //ignore: invalidated session
685: }
686: }
687:
688: /**
689: * {@inheritDoc}
690: */
691: public void setMaxInactiveInterval(int interval) {
692: try {
693: if (httpSession != null) {
694: httpSession.setMaxInactiveInterval(interval);
695: }
696: } catch (IllegalStateException ise) {
697: //ignore: invalidated session
698: }
699: }
700:
701: /**
702: * {@inheritDoc}
703: * @deprecated no replacement
704: */
705: public HttpSessionContext getSessionContext() {
706: return httpSession.getSessionContext();
707: }
708:
709: /**
710: * {@inheritDoc}
711: * @deprecated replaced by {@link #getAttribute}
712: */
713: public Object getValue(String name) {
714: return httpSession.getValue(name);
715: }
716:
717: /**
718: * {@inheritDoc}
719: * @deprecated replaced by {@link #getAttributeNames}
720: */
721: public String[] getValueNames() {
722: return httpSession.getValueNames();
723: }
724:
725: /**
726: * {@inheritDoc}
727: * @deprecated replaced by {@link #setAttribute}
728: */
729: public void putValue(String name, Object value) {
730: httpSession.putValue(name, value);
731: }
732:
733: /**
734: * {@inheritDoc}
735: * @deprecated replaced by {@link #removeAttribute}
736: */
737: public void removeValue(String name) {
738: httpSession.removeValue(name);
739: }
740: }
|