001: /**
002: *
003: */package clime.messadmin.model;
004:
005: import java.util.HashSet;
006: import java.util.Hashtable;
007: import java.util.Iterator;
008: import java.util.Map;
009: import java.util.Set;
010:
011: import javax.servlet.ServletContext;
012: import javax.servlet.http.HttpServletRequest;
013: import javax.servlet.http.HttpSession;
014: import javax.servlet.http.HttpSessionActivationListener;
015: import javax.servlet.http.HttpSessionEvent;
016: import javax.servlet.http.HttpSessionListener;
017:
018: import clime.messadmin.core.Constants;
019: import clime.messadmin.filter.MessAdminRequestWrapper;
020: import clime.messadmin.filter.MessAdminResponseWrapper;
021: import clime.messadmin.utils.StringUtils;
022:
023: /**
024: * @author Cédrik LIME
025: */
026: public class Application implements HttpSessionListener,
027: HttpSessionActivationListener, IRequestListener {
028: protected final ApplicationInfo applicationInfo;
029: protected final Request cumulativeRequests = new Request(null);
030: protected final Map activeSessions = new Hashtable(); //<String, Session> // must be synchronized
031: protected final Map passiveSessions = new Hashtable(); //<String, Session> // must be synchronized
032: /**
033: * Map of user-defined data to store in the Application scope.
034: * This is mainly used for plugins (key == plugin FQ name, for example)
035: */
036: protected final Map userData = new Hashtable();
037:
038: /**
039: * @param servletContext
040: */
041: public Application(ServletContext servletContext) {
042: super ();
043: applicationInfo = new ApplicationInfo(servletContext);
044: }
045:
046: /**
047: * @return Returns the applicationInfo.
048: */
049: public IApplicationInfo getApplicationInfo() {
050: return applicationInfo;
051: }
052:
053: /**
054: * @return Returns the userData.
055: */
056: public Map getUserData() {
057: return userData;
058: }
059:
060: /**
061: * @param sessionId
062: * @return active Session associated with sessionId
063: */
064: public Session getSession(String sessionId) {
065: return (Session) activeSessions.get(sessionId);
066: }
067:
068: /**
069: * @return all known active Sessions for this application
070: */
071: public Set/*<Session>*/getActiveSessions() {
072: return new HashSet(activeSessions.values());
073: }
074:
075: /**
076: * @return all known active SessionsInfo for this application
077: */
078: public Set/*<SessionInfo>*/getActiveSessionInfos() {
079: Set result = new HashSet(activeSessions.size());
080: Iterator iter = getActiveSessions().iterator();
081: while (iter.hasNext()) {
082: Session session = (Session) iter.next();
083: result.add(session.getSessionInfo());
084: }
085: return result;
086: }
087:
088: /**
089: * @return all known active Sessions ids for this application
090: */
091: public Set/*<Session>*/getActiveSessionsIds() {
092: return new HashSet(activeSessions.keySet());
093: }
094:
095: /**
096: * @return all known passive Sessions for this application
097: */
098: public Set/*<Session>*/getPassiveSessions() {
099: return new HashSet(passiveSessions.values());
100: }
101:
102: /**
103: * @return all known passive Sessions ids for this application
104: */
105: public Set/*<String>*/getPassiveSessionsIds() {
106: return new HashSet(passiveSessions.keySet());
107: }
108:
109: protected void hit() {
110: ++applicationInfo.hits;
111: }
112:
113: public void addUsedTime(int duration) {
114: applicationInfo.cumulativeRequestStats.usedTime
115: .registerValue(duration);
116: }
117:
118: /**
119: * If message if blank or null, remove ServletContext attribute, otherwise inject message into ServletContext
120: * @param message
121: */
122: public boolean injectPermanentMessage(String message) {
123: boolean inject = StringUtils.isNotBlank(message);
124: boolean actionDone = false;
125: if (inject) {
126: if (!message.equals(getApplicationInfo().getAttribute(
127: Constants.GLOBAL_MESSAGE_KEY))) {
128: // Setting message
129: getApplicationInfo().setAttribute(
130: Constants.GLOBAL_MESSAGE_KEY, message);
131: actionDone = true;
132: }
133: } else {
134: if (getApplicationInfo().getAttribute(
135: Constants.GLOBAL_MESSAGE_KEY) != null) {
136: // Removing message
137: getApplicationInfo().removeAttribute(
138: Constants.GLOBAL_MESSAGE_KEY);
139: actionDone = true;
140: }
141: }
142: // remove display timestamps from sessions
143: Iterator iter = getActiveSessionInfos().iterator();
144: while (iter.hasNext()) {
145: ISessionInfo session = (ISessionInfo) iter.next();
146: session
147: .removeAttribute(Constants.GLOBAL_MESSAGE_TIMESTAMP_KEY);
148: }
149: return actionDone;
150: }
151:
152: /*****************************************/
153: /** Request/Response Listener methods **/
154: /*****************************************/
155:
156: public void registerContextPath(final String contextPath) {
157: if (applicationInfo.contextPath == null) {
158: applicationInfo.contextPath = contextPath;
159: }
160: }
161:
162: /** {@inheritDoc} */
163: public void requestInitialized(final HttpServletRequest request,
164: final ServletContext servletContext) {
165: if (request == null || servletContext == null) {
166: return;
167: }
168: if (applicationInfo.getClassLoader() == null) {
169: applicationInfo.setClassLoader(Thread.currentThread()
170: .getContextClassLoader());
171: }
172: registerContextPath(request.getContextPath());
173: final HttpSession httpSession = request.getSession(false);
174: if (httpSession == null) {
175: return;
176: } // else
177: try {
178: Session session = getSession(httpSession.getId());
179: if (session == null) {
180: // Maybe this session comes from a serialized state. We need to register it.
181: try {
182: httpSession.getAttributeNames(); // this throws an IllegalStateException for an old session
183: this .sessionCreated(new HttpSessionEvent(
184: httpSession));
185: session = getSession(httpSession.getId());
186: } catch (IllegalStateException ise) {
187: // session is invalidated: it's not new, it's old! So, don't create anything...
188: }
189: }
190: if (session != null) {
191: // we need this test in case session comes from a serialized state @ startup
192: session.requestInitialized(request, servletContext);
193: }
194: cumulativeRequests.requestInitialized(
195: applicationInfo.cumulativeRequestStats, request,
196: servletContext);
197: } catch (IllegalStateException ise) {
198: // session is invalidated
199: }
200: }
201:
202: /** {@inheritDoc} */
203: public void requestDestroyed(final MessAdminRequestWrapper request,
204: final MessAdminResponseWrapper response,
205: final ServletContext servletContext) {
206: if (request == null || response == null
207: || servletContext == null) {
208: return;
209: }
210: hit();
211: cumulativeRequests.requestDestroyed(
212: applicationInfo.cumulativeRequestStats, request,
213: response, servletContext);
214: final HttpSession httpSession = request.getSession(false);
215: if (httpSession != null) {
216: try {
217: final Session session = getSession(httpSession.getId());
218: if (session != null) {
219: session.requestDestroyed(request, response,
220: servletContext);
221: }
222: } catch (IllegalStateException ise) {
223: // session is invalidated
224: }
225: }
226: }
227:
228: /** {@inheritDoc} */
229: public void requestException(Exception e,
230: MessAdminRequestWrapper request,
231: MessAdminResponseWrapper response,
232: ServletContext servletContext) {
233: if (request == null || response == null
234: || servletContext == null) {
235: return;
236: }
237: cumulativeRequests.requestException(
238: applicationInfo.cumulativeRequestStats, e, request,
239: response, servletContext);
240: final HttpSession httpSession = request.getSession(false);
241: if (httpSession != null) {
242: try {
243: final Session session = getSession(httpSession.getId());
244: if (session != null) {
245: session.requestException(e, request, response,
246: servletContext);
247: }
248: } catch (IllegalStateException ise) {
249: // session is invalidated
250: }
251: }
252: }
253:
254: /*********************************************/
255: /** HttpSession[Activation]Listener methods **/
256: /*********************************************/
257:
258: /**
259: * {@inheritDoc}
260: */
261: public void sessionCreated(final HttpSessionEvent event) {
262: HttpSession httpSession = event.getSession();
263: Session session = new Session(httpSession, applicationInfo
264: .getClassLoader());
265: activeSessions.put(httpSession.getId(), session);
266: ++applicationInfo.totalCreatedSessions;
267: applicationInfo.activeSessions.addValue(1);
268: }
269:
270: /**
271: * {@inheritDoc}
272: */
273: public void sessionDestroyed(final HttpSessionEvent event) {
274: HttpSession httpSession = event.getSession();
275: String sessionId = httpSession.getId();
276: activeSessions.remove(sessionId);
277: passiveSessions.remove(sessionId);
278: applicationInfo.activeSessions.addValue(-1);
279: }
280:
281: /**
282: * {@inheritDoc}
283: */
284: public void sessionWillPassivate(final HttpSessionEvent se) {
285: String sessionId = se.getSession().getId();
286: // session is not active anymore: remove it from active list
287: Session session = (Session) activeSessions.remove(sessionId);
288: passiveSessions.put(sessionId, session);
289: session.sessionWillPassivate(se);
290: applicationInfo.activeSessions.addValue(-1);
291: ++applicationInfo.passiveSessionsCount;
292: }
293:
294: /**
295: * {@inheritDoc}
296: */
297: public void sessionDidActivate(final HttpSessionEvent se) {
298: String sessionId = se.getSession().getId();
299: Session session = (Session) passiveSessions.remove(sessionId);
300: // refresh list of active sessions
301: activeSessions.put(sessionId, session);
302: session.sessionDidActivate(se);
303: --applicationInfo.passiveSessionsCount;
304: applicationInfo.activeSessions.addValue(1);
305: }
306: }
|