001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry;
016:
017: import static java.lang.String.format;
018:
019: import java.io.IOException;
020:
021: import javax.servlet.Filter;
022: import javax.servlet.FilterChain;
023: import javax.servlet.FilterConfig;
024: import javax.servlet.ServletContext;
025: import javax.servlet.ServletException;
026: import javax.servlet.ServletRequest;
027: import javax.servlet.ServletResponse;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.apache.tapestry.internal.ServletContextSymbolProvider;
034: import org.apache.tapestry.internal.TapestryAppInitializer;
035: import org.apache.tapestry.ioc.Registry;
036: import org.apache.tapestry.ioc.def.ModuleDef;
037: import org.apache.tapestry.ioc.services.SymbolProvider;
038: import org.apache.tapestry.services.HttpServletRequestHandler;
039: import org.apache.tapestry.services.ServletApplicationInitializer;
040:
041: /**
042: * The TapestryFilter is responsible for intercepting all requests into the web application. It
043: * identifies the requests that are relevant to Tapestry, and lets the servlet container handle the
044: * rest. It is also responsible for initializating Tapestry.
045: */
046: public class TapestryFilter implements Filter {
047: private final Log _log = LogFactory.getLog(TapestryFilter.class);
048:
049: private FilterConfig _config;
050:
051: private Registry _registry;
052:
053: private HttpServletRequestHandler _handler;
054:
055: /**
056: * Initializes the filter using the {@link TapestryAppInitializer}. The application package is
057: * defined by the <code>tapestry.app-package</code> context init parameter and the application
058: * name is the capitalization of the filter name (as specified in web.xml).
059: */
060: public final void init(FilterConfig filterConfig)
061: throws ServletException {
062: _config = filterConfig;
063:
064: ServletContext context = _config.getServletContext();
065:
066: String filterName = _config.getFilterName();
067:
068: SymbolProvider provider = new ServletContextSymbolProvider(
069: context);
070:
071: TapestryAppInitializer appInitializer = new TapestryAppInitializer(
072: provider, filterName, "servlet");
073:
074: appInitializer.addModules(provideExtraModuleDefs(context));
075:
076: _registry = appInitializer.getRegistry();
077:
078: long start = appInitializer.getStartTime();
079:
080: long toRegistry = appInitializer.getRegistryCreatedTime();
081:
082: ServletApplicationInitializer ai = _registry.getService(
083: "ServletApplicationInitializer",
084: ServletApplicationInitializer.class);
085:
086: ai.initializeApplication(filterConfig.getServletContext());
087:
088: _registry.eagerLoadServices();
089:
090: _handler = _registry.getService("HttpServletRequestHandler",
091: HttpServletRequestHandler.class);
092:
093: init(_registry);
094:
095: long toFinish = System.currentTimeMillis();
096:
097: _log
098: .info(format(
099: "Startup time: %,d ms to build IoC Registry, %,d ms overall.",
100: toRegistry - start, toFinish - start));
101: }
102:
103: protected final FilterConfig getFilterConfig() {
104: return _config;
105: }
106:
107: /**
108: * Invoked from {@link #init(FilterConfig)} after the Registry has been created, to allow any
109: * additional initialization to occur. This implementation does nothing, and my be overriden in
110: * subclasses.
111: *
112: * @param registry
113: * from which services may be extracted
114: * @throws ServletException
115: */
116: protected void init(Registry registry) throws ServletException {
117:
118: }
119:
120: /**
121: * Overridden in subclasses to provide additional module definitions beyond those normally
122: * located. This implementation returns an empty array.
123: */
124: protected ModuleDef[] provideExtraModuleDefs(ServletContext context) {
125: return new ModuleDef[0];
126: }
127:
128: public final void doFilter(ServletRequest request,
129: ServletResponse response, FilterChain chain)
130: throws IOException, ServletException {
131: try {
132: boolean handled = _handler.service(
133: (HttpServletRequest) request,
134: (HttpServletResponse) response);
135:
136: if (!handled)
137: chain.doFilter(request, response);
138: } finally {
139: _registry.cleanupThread();
140: }
141: }
142:
143: /** Shuts down and discards the registry. */
144: public final void destroy() {
145: destroy(_registry);
146:
147: _registry.shutdown();
148:
149: _registry = null;
150: _config = null;
151: _handler = null;
152: }
153:
154: /**
155: * Invoked from {@link #destroy()} to allow subclasses to add additional shutdown logic to the
156: * filter. The Registry will be shutdown after this call. This implementation does nothing, and
157: * may be overridden in subclasses.
158: *
159: * @param registry
160: */
161: protected void destroy(Registry registry) {
162:
163: }
164:
165: }
|