001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.terracotta.session;
006:
007: import com.tc.object.bytecode.ManagerUtil;
008: import com.tc.util.ReflectiveProxy;
009: import com.terracotta.session.util.Assert;
010: import com.terracotta.session.util.ConfigProperties;
011: import com.terracotta.session.util.ContextMgr;
012: import com.terracotta.session.util.DefaultContextMgr;
013: import com.terracotta.session.util.DefaultCookieWriter;
014: import com.terracotta.session.util.DefaultIdGenerator;
015: import com.terracotta.session.util.DefaultLifecycleEventMgr;
016: import com.terracotta.session.util.LifecycleEventMgr;
017: import com.terracotta.session.util.SessionCookieWriter;
018: import com.terracotta.session.util.SessionIdGenerator;
019: import com.terracotta.session.util.WebsphereIdGenerator;
020:
021: import java.io.IOException;
022: import java.lang.reflect.Method;
023:
024: import javax.servlet.Filter;
025: import javax.servlet.FilterChain;
026: import javax.servlet.FilterConfig;
027: import javax.servlet.ServletContext;
028: import javax.servlet.ServletException;
029: import javax.servlet.ServletRequest;
030: import javax.servlet.ServletResponse;
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033:
034: public class SessionFilter implements Filter {
035: public final static String APP_SERVER_PARAM_NAME = "app-server";
036: public final static String BEA_WEBLOGIC = "BEA-Weblogic";
037: public final static String IBM_WEBSPHERE = "IBM-Websphere";
038:
039: private SessionManager mgr = null;
040: private ServletContext servletContext = null;
041: private String appServer = null;
042:
043: public static final String FILTER_CLASS = SessionFilter.class
044: .getName();
045: public static final String FILTER_NAME = "Terracotta Session Filter";
046:
047: public SessionFilter() {
048: // nothing
049: }
050:
051: public void init(FilterConfig config) {
052: servletContext = config.getServletContext();
053: appServer = config.getInitParameter(APP_SERVER_PARAM_NAME);
054: }
055:
056: public void destroy() {
057: // not used
058: }
059:
060: public void doFilter(ServletRequest request,
061: ServletResponse response, FilterChain chain)
062: throws IOException, ServletException {
063: if (request instanceof HttpServletRequest
064: && response instanceof HttpServletResponse) {
065: doHttpFilter((HttpServletRequest) request,
066: (HttpServletResponse) response, chain);
067: } else {
068: chain.doFilter(request, response);
069: }
070: }
071:
072: private void doHttpFilter(HttpServletRequest request,
073: HttpServletResponse response, FilterChain chain)
074: throws IOException, ServletException {
075: Assert.pre(request != null);
076: Assert.pre(response != null);
077: Assert.pre(chain != null);
078:
079: SessionManager tcMgr = getManager(request);
080: TerracottaRequest sReq = tcMgr.preprocess(request, response);
081: TerracottaResponse sRes = tcMgr.createResponse(sReq, response);
082: try {
083: chain.doFilter(sReq, sRes);
084: } finally {
085: tcMgr.postprocess(sReq);
086: }
087: }
088:
089: protected synchronized SessionManager getManager(
090: HttpServletRequest req) {
091: if (mgr == null) {
092: if (isWebsphere()) {
093: mgr = createWebsphereManager(req);
094: } else if (servletContext instanceof WebAppConfig) {
095: mgr = createWebAppConfigManager(req,
096: (WebAppConfig) servletContext, servletContext);
097: } else {
098: mgr = createDefaultManager(req, servletContext);
099: }
100: }
101: Assert.post(mgr != null);
102: return mgr;
103: }
104:
105: private SessionManager createWebsphereManager(HttpServletRequest req) {
106: Object sessionContext;
107: Method getSessionContext;
108: WebAppConfig webappconfig;
109:
110: try {
111: getSessionContext = servletContext.getClass().getMethod(
112: "__tc_getSessionContext", new Class[] {});
113: } catch (Exception e) {
114: throw new RuntimeException("Missing method on "
115: + servletContext.getClass(), e);
116: }
117:
118: try {
119: sessionContext = getSessionContext.invoke(servletContext,
120: new Object[] {});
121: } catch (Exception e) {
122: throw new RuntimeException(
123: "Exception retrieving session context", e);
124: }
125:
126: if (sessionContext == null) {
127: throw new RuntimeException(
128: "got back null for session context from "
129: + servletContext.getClass());
130: }
131:
132: webappconfig = (WebAppConfig) ReflectiveProxy
133: .createProxyIfPossible(WebAppConfig.class,
134: sessionContext);
135: if (webappconfig == null) {
136: throw new RuntimeException(
137: "Cannot create proxy to WebAppConfig -- check methods defined on "
138: + sessionContext.getClass());
139: }
140:
141: return createWebAppConfigManager(req, webappconfig,
142: servletContext);
143: }
144:
145: private boolean isWebsphere() {
146: return IBM_WEBSPHERE.equals(appServer);
147: }
148:
149: protected SessionManager createDefaultManager(
150: final HttpServletRequest req, final ServletContext sc) {
151: final SessionManager rv = createManager(req, null,
152: new BaseRequestResponseFactory(), sc);
153: return rv;
154: }
155:
156: protected SessionManager createWebAppConfigManager(
157: final HttpServletRequest req, final WebAppConfig wac,
158: final ServletContext sc) {
159: final SessionManager rv = createManager(req, wac,
160: pickFactory(), sc);
161: return rv;
162: }
163:
164: protected SessionManager createManager(
165: final HttpServletRequest req, final WebAppConfig wac,
166: final RequestResponseFactory factory,
167: final ServletContext sc) {
168: final ConfigProperties cp = new ConfigProperties(wac,
169: getClass().getClassLoader());
170:
171: String appName = DefaultContextMgr.computeAppName(req);
172: int lockType = ManagerUtil.getSessionLockType(appName);
173: SessionIdGenerator sig = pickIdGenerator(cp, lockType);
174:
175: final SessionCookieWriter scw = DefaultCookieWriter
176: .makeInstance(cp);
177: final LifecycleEventMgr eventMgr = DefaultLifecycleEventMgr
178: .makeInstance(cp);
179: final ContextMgr contextMgr = DefaultContextMgr.makeInstance(
180: req, sc);
181: final SessionManager rv = new TerracottaSessionManager(sig,
182: scw, eventMgr, contextMgr, factory, cp);
183: return rv;
184: }
185:
186: private RequestResponseFactory pickFactory() {
187: try {
188: if (BEA_WEBLOGIC.equals(appServer)) {
189: return (RequestResponseFactory) Class
190: .forName(
191: "com.terracotta.session.WeblogicRequestResponseFactory")
192: .newInstance();
193: } else {
194: return new BaseRequestResponseFactory();
195: }
196: } catch (Exception e) {
197: throw new AssertionError(e);
198: }
199: }
200:
201: private SessionIdGenerator pickIdGenerator(ConfigProperties cp,
202: int lockType) {
203: if (isWebsphere()) {
204: return new WebsphereIdGenerator(cp.getSessionIdLength(), cp
205: .getServerId(), lockType, cp.getDelimiter());
206: }
207: return DefaultIdGenerator.makeInstance(cp, lockType);
208: }
209:
210: }
|