0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.server.webapp;
0031:
0032: import com.caucho.amber.manager.AmberContainer;
0033: import com.caucho.config.ConfigException;
0034: import com.caucho.config.j2ee.PersistenceContextRefConfig;
0035: import com.caucho.config.SchemaBean;
0036: import com.caucho.config.types.*;
0037: import com.caucho.i18n.CharacterEncoding;
0038: import com.caucho.jsp.JspServlet;
0039: import com.caucho.jsp.cfg.JspConfig;
0040: import com.caucho.jsp.cfg.JspPropertyGroup;
0041: import com.caucho.jsp.cfg.JspTaglib;
0042: import com.caucho.jsp.el.JspApplicationContextImpl;
0043: import com.caucho.lifecycle.Lifecycle;
0044: import com.caucho.loader.Environment;
0045: import com.caucho.loader.EnvironmentBean;
0046: import com.caucho.loader.EnvironmentClassLoader;
0047: import com.caucho.loader.EnvironmentLocal;
0048: import com.caucho.make.AlwaysModified;
0049: import com.caucho.make.DependencyContainer;
0050: import com.caucho.management.server.HostMXBean;
0051: import com.caucho.naming.Jndi;
0052: import com.caucho.server.cache.AbstractCache;
0053: import com.caucho.server.cluster.Cluster;
0054: import com.caucho.server.cluster.Server;
0055: import com.caucho.server.deploy.DeployContainer;
0056: import com.caucho.server.deploy.DeployGenerator;
0057: import com.caucho.server.deploy.EnvironmentDeployInstance;
0058: import com.caucho.server.dispatch.*;
0059: import com.caucho.server.host.Host;
0060: import com.caucho.server.log.AbstractAccessLog;
0061: import com.caucho.server.log.AccessLog;
0062: import com.caucho.server.resin.Resin;
0063: import com.caucho.server.rewrite.RewriteDispatch;
0064: import com.caucho.server.security.*;
0065: import com.caucho.server.session.SessionManager;
0066: import com.caucho.server.util.CauchoSystem; //import com.caucho.soa.client.WebServiceClient;
0067: import com.caucho.transaction.TransactionManagerImpl;
0068: import com.caucho.util.Alarm;
0069: import com.caucho.util.L10N;
0070: import com.caucho.util.LruCache;
0071: import com.caucho.vfs.Dependency;
0072: import com.caucho.vfs.Encoding;
0073: import com.caucho.vfs.Path;
0074: import com.caucho.vfs.Vfs;
0075: import com.caucho.webbeans.el.WebBeansELResolver;
0076: import com.caucho.webbeans.manager.*;
0077: import com.caucho.webbeans.component.*;
0078: import com.caucho.java.WorkDir;
0079:
0080: import javax.annotation.PostConstruct;
0081: import javax.management.ObjectName;
0082: import javax.naming.InitialContext;
0083: import javax.naming.NamingException;
0084: import javax.servlet.*;
0085: import javax.servlet.http.*;
0086: import javax.webbeans.*;
0087: import java.io.File;
0088: import java.io.IOException;
0089: import java.util.ArrayList;
0090: import java.util.HashMap;
0091: import java.util.Iterator;
0092: import java.util.Locale;
0093: import java.util.logging.Level;
0094: import java.util.logging.Logger;
0095:
0096: /**
0097: * Resin's webApp implementation.
0098: */
0099: public class WebApp extends ServletContextImpl implements Dependency,
0100: EnvironmentBean, SchemaBean, DispatchBuilder,
0101: EnvironmentDeployInstance, java.io.Serializable {
0102: private static final String DEFAULT_VERSION = "2.5";
0103:
0104: private static final L10N L = new L10N(WebApp.class);
0105: private static final Logger log = Logger.getLogger(WebApp.class
0106: .getName());
0107:
0108: private static final int JSP_NONE = 0;
0109: private static final int JSP_1 = 1;
0110: private static final int JSP_2 = 2;
0111:
0112: private static EnvironmentLocal<AbstractAccessLog> _accessLogLocal = new EnvironmentLocal<AbstractAccessLog>(
0113: "caucho.server.access-log");
0114:
0115: private static EnvironmentLocal<WebApp> _appLocal = new EnvironmentLocal<WebApp>(
0116: "caucho.application");
0117:
0118: private static ThreadLocal<ServletRequest> _requestThreadLocal = new ThreadLocal<ServletRequest>();
0119:
0120: static String[] _classLoaderHackPackages;
0121:
0122: private ClassLoader _parentClassLoader;
0123:
0124: // The environment class loader
0125: private EnvironmentClassLoader _classLoader;
0126:
0127: // The parent
0128: private WebAppContainer _parent;
0129:
0130: // Any old version web-app
0131: private WebApp _oldWebApp;
0132: private long _oldWebAppExpireTime;
0133:
0134: // The webApp entry
0135: private WebAppController _controller;
0136:
0137: // The webApp directory.
0138: private final Path _appDir;
0139:
0140: // The context path
0141: private String _contextPath = "";
0142:
0143: // A description
0144: private String _description = "";
0145:
0146: private String _servletVersion;
0147:
0148: private boolean _isDynamicDeploy;
0149: private boolean _isDisableCrossContext;
0150:
0151: // Any war-generators.
0152: private ArrayList<DeployGenerator> _appGenerators = new ArrayList<DeployGenerator>();
0153:
0154: // Any web-app-default for children
0155: private ArrayList<WebAppConfig> _webAppDefaultList = new ArrayList<WebAppConfig>();
0156:
0157: // The servlet manager
0158: private ServletManager _servletManager;
0159: // The servlet mapper
0160: private ServletMapper _servletMapper;
0161: // True the mapper should be strict
0162: private boolean _isStrictMapping;
0163: // True if the servlet init-param is allowed to use EL
0164: private boolean _servletAllowEL = false;
0165:
0166: // The filter manager
0167: private FilterManager _filterManager;
0168: // The filter mapper
0169: private FilterMapper _filterMapper;
0170: // The filter mapper
0171: private FilterMapper _loginFilterMapper;
0172: // The include filter mapper
0173: private FilterMapper _includeFilterMapper;
0174: // The forward filter mapper
0175: private FilterMapper _forwardFilterMapper;
0176: // The error filter mapper
0177: private FilterMapper _errorFilterMapper;
0178: // True if includes are allowed to wrap a filter (forbidden by servlet spec)
0179: private boolean _dispatchWrapsFilters;
0180:
0181: // Transaction manager
0182: private TransactionManagerImpl _tm;
0183:
0184: // The session manager
0185: private SessionManager _sessionManager;
0186: // True if the session manager is inherited
0187: private boolean _isInheritSession;
0188:
0189: private String _characterEncoding;
0190:
0191: // The cache
0192: private AbstractCache _cache;
0193:
0194: private LruCache<String, FilterChainEntry> _filterChainCache = new LruCache<String, FilterChainEntry>(
0195: 256);
0196:
0197: private UrlMap<CacheMapping> _cacheMappingMap = new UrlMap<CacheMapping>();
0198:
0199: private LruCache<String, RequestDispatcherImpl> _dispatcherCache;
0200:
0201: // login configuration factory for lazy start
0202: private Login _loginFactory;
0203: private AbstractLogin _login;
0204:
0205: // Old login manager for compat
0206: private AbstractLogin _loginManager;
0207:
0208: // The security constraints
0209: private ConstraintManager _constraintManager;
0210:
0211: // True for SSL secure.
0212: private boolean _isSecure;
0213:
0214: // Error pages.
0215: private ErrorPageManager _errorPageManager;
0216:
0217: // Any configuration exception
0218: private Throwable _configException;
0219:
0220: // dispatch mapping
0221: private RewriteDispatch _rewriteDispatch;
0222:
0223: private LruCache<String, String> _realPathCache = new LruCache<String, String>(
0224: 1024);
0225: // real-path mapping
0226: private RewriteRealPath _rewriteRealPath;
0227:
0228: // mime mapping
0229: private HashMap<String, String> _mimeMapping = new HashMap<String, String>();
0230: // locale mapping
0231: private HashMap<String, String> _localeMapping = new HashMap<String, String>();
0232:
0233: // List of all the listeners.
0234: private ArrayList<Listener> _listeners = new ArrayList<Listener>();
0235:
0236: // List of the ServletContextListeners from the configuration file
0237: private ArrayList<ServletContextListener> _webAppListeners = new ArrayList<ServletContextListener>();
0238:
0239: // List of the ServletContextAttributeListeners from the configuration file
0240: private ArrayList<ServletContextAttributeListener> _attributeListeners = new ArrayList<ServletContextAttributeListener>();
0241:
0242: // List of the ServletRequestListeners from the configuration file
0243: private ArrayList<ServletRequestListener> _requestListeners = new ArrayList<ServletRequestListener>();
0244:
0245: private ServletRequestListener[] _requestListenerArray = new ServletRequestListener[0];
0246:
0247: // List of the ServletRequestAttributeListeners from the configuration file
0248: private ArrayList<ServletRequestAttributeListener> _requestAttributeListeners = new ArrayList<ServletRequestAttributeListener>();
0249:
0250: private ServletRequestAttributeListener[] _requestAttributeListenerArray = new ServletRequestAttributeListener[0];
0251:
0252: private ArrayList<Validator> _resourceValidators = new ArrayList<Validator>();
0253:
0254: private DependencyContainer _invocationDependency;
0255:
0256: private AbstractAccessLog _accessLog;
0257: private Path _tempDir;
0258:
0259: private boolean _cookieHttpOnly;
0260:
0261: // special
0262: private int _jspState;
0263: private JspPropertyGroup _jsp;
0264: private ArrayList<JspTaglib> _taglibList;
0265: private JspApplicationContextImpl _jspApplicationContext;
0266: private HashMap<String, Object> _extensions = new HashMap<String, Object>();
0267:
0268: private MultipartForm _multipartForm;
0269:
0270: private ArrayList<String> _regexp;
0271:
0272: private long _shutdownWaitTime = 15000L;
0273: private long _activeWaitTime = 15000L;
0274:
0275: private long _idleTime = 2 * 3600 * 1000L;
0276:
0277: private final Object _countLock = new Object();
0278: private final Lifecycle _lifecycle;
0279:
0280: private int _requestCount;
0281: private long _lastRequestTime = Alarm.getCurrentTime();
0282:
0283: //
0284: // statistics
0285: //
0286:
0287: private long _status500CountTotal;
0288: private long _status500LastTime;
0289:
0290: /**
0291: * Creates the webApp with its environment loader.
0292: */
0293: public WebApp(Path rootDirectory) {
0294: this (new WebAppController("/", "/", rootDirectory, null));
0295: }
0296:
0297: /**
0298: * Creates the webApp with its environment loader.
0299: */
0300: WebApp(WebAppController controller) {
0301: String contextPath = controller.getContextPath();
0302: setContextPathId(contextPath);
0303:
0304: _controller = controller;
0305: _appDir = controller.getRootDirectory();
0306:
0307: try {
0308: _classLoader = new EnvironmentClassLoader(controller
0309: .getParentClassLoader(), "web-app:" + getURL());
0310:
0311: // the JSP servlet needs to initialize the JspFactory
0312: JspServlet.initStatic();
0313:
0314: _classLoader
0315: .addParentPriorityPackages(_classLoaderHackPackages);
0316:
0317: // _classLoader.setId("web-app:" + getURL());
0318:
0319: _appLocal.set(this , _classLoader);
0320:
0321: setParent(controller.getContainer());
0322:
0323: Vfs.setPwd(_appDir, _classLoader);
0324: WorkDir.setLocalWorkDir(_appDir.lookup("WEB-INF/work"),
0325: _classLoader);
0326:
0327: // map.put("app", _appVar);
0328:
0329: if (CauchoSystem.isTesting()) {
0330: } else if (_appDir.equals(CauchoSystem.getResinHome())) {
0331: throw new ConfigException(
0332: L
0333: .l(
0334: "web-app root-directory can not be the same as resin.home\n{0}",
0335: _appDir));
0336: } else if (_parent != null
0337: && _appDir.equals(_parent.getRootDirectory())) {
0338: throw new ConfigException(
0339: L
0340: .l(
0341: "web-app root-directory can not be the same as the host root-directory\n{0}",
0342: _appDir));
0343: }
0344:
0345: _servletManager = new ServletManager();
0346: _servletMapper = new ServletMapper();
0347: _servletMapper.setServletContext(this );
0348: _servletMapper.setServletManager(_servletManager);
0349:
0350: _filterManager = new FilterManager();
0351: _filterMapper = new FilterMapper();
0352: _filterMapper.setServletContext(this );
0353: _filterMapper.setFilterManager(_filterManager);
0354:
0355: _loginFilterMapper = new FilterMapper();
0356: _loginFilterMapper.setServletContext(this );
0357: _loginFilterMapper.setFilterManager(_filterManager);
0358:
0359: _includeFilterMapper = new FilterMapper();
0360: _includeFilterMapper.setServletContext(this );
0361: _includeFilterMapper.setFilterManager(_filterManager);
0362:
0363: _forwardFilterMapper = new FilterMapper();
0364: _forwardFilterMapper.setServletContext(this );
0365: _forwardFilterMapper.setFilterManager(_filterManager);
0366:
0367: _errorFilterMapper = new FilterMapper();
0368: _errorFilterMapper.setServletContext(this );
0369: _errorFilterMapper.setFilterManager(_filterManager);
0370:
0371: _constraintManager = new ConstraintManager();
0372: _errorPageManager = new ErrorPageManager();
0373: _errorPageManager.setWebApp(this );
0374: if (getParent() != null)
0375: _errorPageManager.setParent(getParent()
0376: .getErrorPageManager());
0377:
0378: _invocationDependency = new DependencyContainer();
0379: _invocationDependency.add(this );
0380:
0381: _jspApplicationContext = new JspApplicationContextImpl(this );
0382: } catch (Throwable e) {
0383: setConfigException(e);
0384: } finally {
0385: _lifecycle = new Lifecycle(log, toString(), Level.INFO);
0386: }
0387: }
0388:
0389: /**
0390: * Sets the parent container.
0391: */
0392: public void setParent(WebAppContainer parent) {
0393: _parent = parent;
0394:
0395: if (parent == null)
0396: return;
0397: }
0398:
0399: /**
0400: * Set true for a dynamically deployed server.
0401: */
0402: public void setDynamicDeploy(boolean isDynamicDeploy) {
0403: _isDynamicDeploy = isDynamicDeploy;
0404: }
0405:
0406: /**
0407: * Set true for a dynamically deployed server.
0408: */
0409: public boolean isDynamicDeploy() {
0410: return _isDynamicDeploy;
0411: }
0412:
0413: /**
0414: * Gets the parent container.
0415: */
0416: public WebAppContainer getParent() {
0417: return _parent;
0418: }
0419:
0420: /**
0421: * Returns the local webApp.
0422: */
0423: public static WebApp getLocal() {
0424: return _appLocal.get();
0425: }
0426:
0427: /**
0428: * Gets the dispatch server.
0429: */
0430: public DispatchServer getDispatchServer() {
0431: if (_parent != null)
0432: return _parent.getDispatchServer();
0433: else
0434: return null;
0435: }
0436:
0437: /**
0438: * Gets the dispatch server.
0439: */
0440: public Server getServer() {
0441: if (_parent != null
0442: && _parent.getDispatchServer() instanceof Server)
0443: return (Server) _parent.getDispatchServer();
0444: else
0445: return null;
0446: }
0447:
0448: /**
0449: * The id is the context path.
0450: */
0451: public void setId(String id) {
0452: }
0453:
0454: /**
0455: * The id is the context path.
0456: */
0457: private void setContextPathId(String id) {
0458: if (!id.equals("") && !id.startsWith("/"))
0459: id = "/" + id;
0460:
0461: if (id.endsWith("/"))
0462: id = id.substring(0, id.length() - 1);
0463:
0464: setContextPath(id);
0465: }
0466:
0467: /**
0468: * Gets the environment class loader.
0469: */
0470: public ClassLoader getClassLoader() {
0471: return _classLoader;
0472: }
0473:
0474: /**
0475: * Sets the environment class loader.
0476: */
0477: public void setEnvironmentClassLoader(EnvironmentClassLoader loader) {
0478: throw new IllegalStateException();
0479: }
0480:
0481: /**
0482: * Gets the environment class loader.
0483: */
0484: public EnvironmentClassLoader getEnvironmentClassLoader() {
0485: return _classLoader;
0486: }
0487:
0488: /**
0489: * Sets the redeploy-mode of the controller
0490: */
0491: public void setRedeployMode(String mode) {
0492: if (_controller != null)
0493: _controller.setRedeployMode(mode);
0494: }
0495:
0496: /**
0497: * Returns the relax schema.
0498: */
0499: public String getSchema() {
0500: return "com/caucho/server/webapp/resin-web-xml.rnc";
0501: }
0502:
0503: /**
0504: * Sets the node for testing Servlet/JSP versions.
0505: */
0506: public void setConfigNode(org.w3c.dom.Node node) {
0507: String ns = node.getNamespaceURI();
0508:
0509: if (ns == null || ns.equals("")) {
0510: _jspState = JSP_1;
0511: }
0512: }
0513:
0514: /**
0515: * Gets the webApp directory.
0516: */
0517: public Path getAppDir() {
0518: return _appDir;
0519: }
0520:
0521: /**
0522: * Gets the dependency container
0523: */
0524: public DependencyContainer getInvocationDependency() {
0525: return _invocationDependency;
0526: }
0527:
0528: /**
0529: * Sets the regexp vars.
0530: */
0531: public void setRegexp(ArrayList<String> regexp) {
0532: _regexp = regexp;
0533: }
0534:
0535: /**
0536: * Gets the regexp vars.
0537: */
0538: public ArrayList<String> getRegexp() {
0539: return _regexp;
0540: }
0541:
0542: /**
0543: * Sets the document directory (app-dir).
0544: */
0545: public void setDocumentDirectory(Path appDir) {
0546: setAppDir(appDir);
0547: }
0548:
0549: /**
0550: * Sets the root directory (app-dir).
0551: */
0552: public void setRootDirectory(Path appDir) {
0553: }
0554:
0555: /**
0556: * Sets the webApp directory.
0557: */
0558: public void setAppDir(Path appDir) {
0559: setRootDirectory(appDir);
0560: }
0561:
0562: /**
0563: * Returns the ObjectName.
0564: */
0565: public ObjectName getObjectName() {
0566: return _controller.getObjectName();
0567: }
0568:
0569: /**
0570: * Gets the context path
0571: */
0572: public String getContextPath() {
0573: return _contextPath;
0574: }
0575:
0576: /**
0577: * Sets the context path
0578: */
0579: private void setContextPath(String contextPath) {
0580: _contextPath = contextPath;
0581:
0582: if (getServletContextName() == null)
0583: setDisplayName(contextPath);
0584: }
0585:
0586: /**
0587: * Sets the servlet version.
0588: */
0589: public void setVersion(String version) {
0590: _servletVersion = version;
0591: }
0592:
0593: /**
0594: * Returns the servlet version.
0595: */
0596: public String getVersion() {
0597: return _servletVersion;
0598: }
0599:
0600: /**
0601: * Sets the schema location.
0602: */
0603: public void setSchemaLocation(String location) {
0604: }
0605:
0606: public void setDistributable(boolean isDistributable) {
0607: }
0608:
0609: /**
0610: * Gets the URL
0611: */
0612: public String getURL() {
0613: if (_parent != null)
0614: return _parent.getURL() + _contextPath;
0615: else
0616: return _contextPath;
0617: }
0618:
0619: /**
0620: * Gets the URL
0621: */
0622: public String getHostName() {
0623: if (_parent != null)
0624: return _parent.getHostName();
0625: else
0626: return null;
0627: }
0628:
0629: /**
0630: * Gets the URL
0631: */
0632: public HostMXBean getHostAdmin() {
0633: if (_parent != null && _parent.getHost() != null)
0634: return _parent.getHost().getAdmin();
0635: else
0636: return null;
0637: }
0638:
0639: /**
0640: * A user description of the web-app
0641: */
0642: public String getDescription() {
0643: return _description;
0644: }
0645:
0646: /**
0647: * A user description of the web-app
0648: */
0649: public void setDescription(String description) {
0650: _description = description;
0651: }
0652:
0653: /**
0654: * Sets the icon
0655: */
0656: public void setIcon(com.caucho.config.types.Icon icon) {
0657: }
0658:
0659: /**
0660: * Sets the servlet init-param EL enabling.
0661: */
0662: public void setAllowServletEL(boolean allow) {
0663: _servletAllowEL = allow;
0664: }
0665:
0666: /**
0667: * If true, disables getContext().
0668: */
0669: public void setDisableCrossContext(boolean isDisable) {
0670: _isDisableCrossContext = isDisable;
0671: }
0672:
0673: /**
0674: * Sets the old version web-app.
0675: */
0676: public void setOldWebApp(WebApp oldWebApp, long expireTime) {
0677: _oldWebApp = oldWebApp;
0678: _oldWebAppExpireTime = expireTime;
0679: }
0680:
0681: /**
0682: * Adds a servlet configuration.
0683: */
0684: public ServletConfigImpl createServlet() throws ServletException {
0685: ServletConfigImpl config = new ServletConfigImpl();
0686:
0687: config.setServletContext(this );
0688: config.setAllowEL(_servletAllowEL);
0689:
0690: return config;
0691: }
0692:
0693: /**
0694: * Adds a servlet configuration.
0695: */
0696: public void addServlet(ServletConfigImpl config)
0697: throws ServletException {
0698: config.setServletContext(this );
0699:
0700: _servletManager.addServlet(config);
0701: }
0702:
0703: /**
0704: * Returns the character encoding.
0705: */
0706: public String getCharacterEncoding() {
0707: return _characterEncoding;
0708: }
0709:
0710: /**
0711: * Set true if strict mapping.
0712: */
0713: public void setStrictMapping(boolean isStrict)
0714: throws ServletException {
0715: _isStrictMapping = isStrict;
0716: }
0717:
0718: /**
0719: * Get the strict mapping setting.
0720: */
0721: public boolean getStrictMapping() {
0722: return _isStrictMapping;
0723: }
0724:
0725: /**
0726: * Lazy servlet validation.
0727: */
0728: public void setLazyServletValidate(boolean isLazy) {
0729: _servletManager.setLazyValidate(isLazy);
0730: }
0731:
0732: public ServletMapping createServletMapping() {
0733: ServletMapping servletMapping = new ServletMapping();
0734:
0735: servletMapping.setServletContext(this );
0736: servletMapping.setStrictMapping(getStrictMapping());
0737:
0738: return servletMapping;
0739: }
0740:
0741: /**
0742: * Adds a servlet-mapping configuration.
0743: */
0744: public void addServletMapping(ServletMapping servletMapping)
0745: throws ServletException {
0746: // log.fine("adding servlet mapping: " + servletMapping);
0747: servletMapping.setServletContext(this );
0748:
0749: servletMapping.init(_servletMapper);
0750: }
0751:
0752: /**
0753: * Adds a web service client.
0754: */
0755: /*
0756: public WebServiceClient createWebServiceClient()
0757: {
0758: return new WebServiceClient();
0759: }
0760: */
0761:
0762: /**
0763: * Adds a servlet-regexp configuration.
0764: */
0765: public void addServletRegexp(ServletRegexp servletRegexp)
0766: throws ServletException, ClassNotFoundException {
0767: ServletMapping mapping = new ServletMapping();
0768:
0769: mapping.addURLRegexp(servletRegexp.getURLRegexp());
0770: mapping.setServletName(servletRegexp.getServletName());
0771: mapping.setServletClass(servletRegexp.getServletClass());
0772: mapping.setServletContext(this );
0773: servletRegexp.getBuilderProgram().configure(mapping);
0774: mapping.setStrictMapping(getStrictMapping());
0775: mapping.init(_servletMapper);
0776:
0777: //_servletMapper.addServletRegexp(mapping);
0778: }
0779:
0780: /**
0781: * Adds a filter configuration.
0782: */
0783: public void addFilter(FilterConfigImpl config) {
0784: config.setServletContext(this );
0785:
0786: _filterManager.addFilter(config);
0787: }
0788:
0789: /**
0790: * Adds a filter-mapping configuration.
0791: */
0792: public void addFilterMapping(FilterMapping filterMapping)
0793: throws ServletException {
0794: filterMapping.setServletContext(this );
0795:
0796: if (filterMapping.isRequest()) {
0797: _filterMapper.addFilterMapping(filterMapping);
0798: _loginFilterMapper.addFilterMapping(filterMapping);
0799: }
0800:
0801: if (filterMapping.isInclude())
0802: _includeFilterMapper.addFilterMapping(filterMapping);
0803:
0804: if (filterMapping.isForward())
0805: _forwardFilterMapper.addFilterMapping(filterMapping);
0806:
0807: if (filterMapping.isError())
0808: _errorFilterMapper.addFilterMapping(filterMapping);
0809: }
0810:
0811: /**
0812: * Adds a persistence-context-ref configuration.
0813: */
0814: public void addPersistenceContextRef(
0815: PersistenceContextRefConfig persistenceContextRefConfig)
0816: throws ServletException {
0817: // XXX: TCK ejb30/persistence/ee/packaging/web/scope, needs a test case.
0818:
0819: log.fine("WebApp adding persistence context ref: "
0820: + persistenceContextRefConfig
0821: .getPersistenceContextRefName());
0822:
0823: String unitName = persistenceContextRefConfig
0824: .getPersistenceUnitName();
0825:
0826: log.fine("WebApp looking up entity manager: "
0827: + AmberContainer.getPersistenceContextJndiPrefix()
0828: + unitName);
0829:
0830: Object obj = Jndi.lookup(AmberContainer
0831: .getPersistenceContextJndiPrefix()
0832: + unitName);
0833:
0834: log.fine("WebApp found entity manager: " + obj);
0835:
0836: String contextRefName = persistenceContextRefConfig
0837: .getPersistenceContextRefName();
0838:
0839: try {
0840: Jndi.bindDeep("java:comp/env/" + contextRefName, obj);
0841: } catch (NamingException e) {
0842: throw ConfigException.create(e);
0843: }
0844: }
0845:
0846: /**
0847: * Set true if includes wrap filters.
0848: */
0849: public void setDispatchWrapsFilters(boolean wrap) {
0850: _dispatchWrapsFilters = wrap;
0851: }
0852:
0853: /**
0854: * Get true if includes wrap filters.
0855: */
0856: public boolean getDispatchWrapsFilters() {
0857: return _dispatchWrapsFilters;
0858: }
0859:
0860: /**
0861: * (compat) sets the directory servlet
0862: */
0863: public void setDirectoryServlet(String className) throws Exception {
0864: ServletConfigImpl config = new ServletConfigImpl();
0865: config.setServletName("directory");
0866: if (className.equals("none"))
0867: config
0868: .setServletClass("com.caucho.servlets.ErrorStatusServlet");
0869: else
0870: config.setServletClass(className);
0871:
0872: addServlet(config);
0873: }
0874:
0875: /**
0876: * Adds a welcome file list to the webApp.
0877: */
0878: public void addWelcomeFileList(WelcomeFileList list) {
0879: ArrayList<String> fileList = list.getWelcomeFileList();
0880:
0881: _servletMapper.setWelcomeFileList(fileList);
0882: }
0883:
0884: /**
0885: * Configures the locale encoding.
0886: */
0887: public LocaleEncodingMappingList createLocaleEncodingMappingList() {
0888: return new LocaleEncodingMappingList(this );
0889: }
0890:
0891: /**
0892: * Sets inherit session.
0893: */
0894: public void setInheritSession(boolean isInheritSession) {
0895: _isInheritSession = isInheritSession;
0896: }
0897:
0898: /**
0899: * Gets inherit session.
0900: */
0901: public boolean isInheritSession() {
0902: return _isInheritSession;
0903: }
0904:
0905: /**
0906: * Configures the session manager.
0907: */
0908: public SessionManager createSessionConfig() throws Exception {
0909: if (_isInheritSession)
0910: return new SessionManager(this );
0911:
0912: return getSessionManager();
0913: }
0914:
0915: /**
0916: * Adds the session manager.
0917: */
0918: public void addSessionConfig(SessionManager manager)
0919: throws ConfigException {
0920: if (_isInheritSession) {
0921: manager.close();
0922: }
0923: }
0924:
0925: /**
0926: * Sets the cookie-http-only
0927: */
0928: public void setCookieHttpOnly(boolean isHttpOnly) {
0929: _cookieHttpOnly = isHttpOnly;
0930: }
0931:
0932: /**
0933: * Sets the cookie-http-only
0934: */
0935: public boolean getCookieHttpOnly() {
0936: return _cookieHttpOnly;
0937: }
0938:
0939: /**
0940: * Sets an init-param
0941: */
0942: public InitParam createContextParam() {
0943: InitParam initParam = new InitParam();
0944:
0945: initParam.setAllowEL(_servletAllowEL);
0946:
0947: return initParam;
0948: }
0949:
0950: /**
0951: * Sets the context param
0952: */
0953: public void addContextParam(InitParam initParam) {
0954: HashMap<String, String> map = initParam.getParameters();
0955:
0956: Iterator<String> iter = map.keySet().iterator();
0957: while (iter.hasNext()) {
0958: String key = iter.next();
0959: String value = map.get(key);
0960:
0961: setInitParameter(key, value);
0962: }
0963: }
0964:
0965: /**
0966: * Adds an error page
0967: */
0968: public void addErrorPage(ErrorPage errorPage) {
0969: _errorPageManager.addErrorPage(errorPage);
0970: }
0971:
0972: /**
0973: * Sets the access log.
0974: */
0975: public AccessLog createAccessLog() {
0976: return new AccessLog();
0977: }
0978:
0979: /**
0980: * Sets the access log.
0981: */
0982: public void setAccessLog(AbstractAccessLog log) {
0983: _accessLog = log;
0984:
0985: _accessLogLocal.set(log);
0986: }
0987:
0988: /**
0989: * Adds a mime-mapping
0990: */
0991: public void addMimeMapping(MimeMapping mimeMapping) {
0992: _mimeMapping.put(mimeMapping.getExtension(), mimeMapping
0993: .getMimeType());
0994: }
0995:
0996: /**
0997: * Adds a locale-mapping
0998: */
0999: public void putLocaleEncoding(String locale, String encoding) {
1000: _localeMapping.put(locale.toLowerCase(), encoding);
1001: }
1002:
1003: /**
1004: * Returns the locale encoding.
1005: */
1006: public String getLocaleEncoding(Locale locale) {
1007: String encoding;
1008:
1009: String key = locale.toString();
1010: encoding = _localeMapping.get(key.toLowerCase());
1011:
1012: if (encoding != null)
1013: return encoding;
1014:
1015: if (locale.getVariant() != null) {
1016: key = locale.getLanguage() + '_' + locale.getCountry();
1017: encoding = _localeMapping.get(key.toLowerCase());
1018: if (encoding != null)
1019: return encoding;
1020: }
1021:
1022: if (locale.getCountry() != null) {
1023: key = locale.getLanguage();
1024: encoding = _localeMapping.get(key.toLowerCase());
1025: if (encoding != null)
1026: return encoding;
1027: }
1028:
1029: return Encoding.getMimeName(locale);
1030: }
1031:
1032: /**
1033: * Sets the login
1034: */
1035: public void setLoginConfig(LoginConfig loginConfig)
1036: throws Throwable {
1037: _loginManager = loginConfig.getLogin();
1038: }
1039:
1040: /**
1041: * Sets the login
1042: */
1043: public void setLogin(Login login) {
1044: _loginFactory = login;
1045: }
1046:
1047: /**
1048: * Adds rewrite-dispatch.
1049: */
1050: public RewriteDispatch createRewriteDispatch() {
1051: if (_rewriteDispatch == null)
1052: _rewriteDispatch = new RewriteDispatch(this );
1053:
1054: return _rewriteDispatch;
1055: }
1056:
1057: /**
1058: * Adds rewrite-real-path.
1059: */
1060: public RewriteRealPath createRewriteRealPath() {
1061: if (_rewriteRealPath == null)
1062: _rewriteRealPath = new RewriteRealPath(getAppDir());
1063:
1064: return _rewriteRealPath;
1065: }
1066:
1067: /**
1068: * Adds a path-mapping
1069: */
1070: public void addPathMapping(PathMapping pathMapping)
1071: throws Exception {
1072: String urlPattern = pathMapping.getUrlPattern();
1073: String urlRegexp = pathMapping.getUrlRegexp();
1074: String realPath = pathMapping.getRealPath();
1075:
1076: if (urlPattern != null)
1077: createRewriteRealPath()
1078: .addPathPattern(urlPattern, realPath);
1079: else if (urlRegexp != null)
1080: createRewriteRealPath().addPathRegexp(urlRegexp, realPath);
1081: else
1082: throw new NullPointerException();
1083: }
1084:
1085: /**
1086: * Adds a security constraint
1087: */
1088: public void addSecurityConstraint(SecurityConstraint constraint) {
1089: _constraintManager.addConstraint(constraint);
1090: }
1091:
1092: /**
1093: * Adds a security role
1094: */
1095: public void addSecurityRole(SecurityRole role) {
1096: }
1097:
1098: /**
1099: * Sets the secure requirement.
1100: */
1101: public void setSecure(boolean isSecure) {
1102: _isSecure = isSecure;
1103:
1104: if (isSecure) {
1105: TransportConstraint transConstraint = new TransportConstraint(
1106: "secure");
1107:
1108: SecurityConstraint constraint = new SecurityConstraint();
1109: constraint.setURLPattern("/*");
1110: constraint.addConstraint(transConstraint);
1111:
1112: _constraintManager.addConstraint(constraint);
1113: }
1114: }
1115:
1116: public void addListener(Listener listener) throws Exception {
1117: if (!hasListener(listener.getListenerClass())) {
1118: _listeners.add(listener);
1119:
1120: if (_lifecycle.isStarting() || _lifecycle.isActive()) {
1121: addListenerObject(listener.createListenerObject(), true);
1122: }
1123: }
1124: }
1125:
1126: /**
1127: * Returns true if a listener with the given type exists.
1128: */
1129: public boolean hasListener(Class listenerClass) {
1130: for (int i = 0; i < _listeners.size(); i++) {
1131: Listener listener = _listeners.get(i);
1132:
1133: if (listenerClass.equals(listener.getListenerClass()))
1134: return true;
1135: }
1136:
1137: return false;
1138: }
1139:
1140: /**
1141: * Adds the listener object.
1142: */
1143: private void addListenerObject(Object listenerObj, boolean start) {
1144: if (listenerObj instanceof ServletContextListener) {
1145: ServletContextListener scListener = (ServletContextListener) listenerObj;
1146: _webAppListeners.add(scListener);
1147:
1148: if (start) {
1149: ServletContextEvent event = new ServletContextEvent(
1150: this );
1151:
1152: try {
1153: scListener.contextInitialized(event);
1154: } catch (Exception e) {
1155: log.log(Level.FINE, e.toString(), e);
1156: }
1157: }
1158: }
1159:
1160: if (listenerObj instanceof ServletContextAttributeListener)
1161: addAttributeListener((ServletContextAttributeListener) listenerObj);
1162:
1163: if (listenerObj instanceof ServletRequestListener) {
1164: _requestListeners.add((ServletRequestListener) listenerObj);
1165:
1166: _requestListenerArray = new ServletRequestListener[_requestListeners
1167: .size()];
1168: _requestListeners.toArray(_requestListenerArray);
1169: }
1170:
1171: if (listenerObj instanceof ServletRequestAttributeListener) {
1172: _requestAttributeListeners
1173: .add((ServletRequestAttributeListener) listenerObj);
1174:
1175: _requestAttributeListenerArray = new ServletRequestAttributeListener[_requestAttributeListeners
1176: .size()];
1177: _requestAttributeListeners
1178: .toArray(_requestAttributeListenerArray);
1179: }
1180:
1181: if (listenerObj instanceof HttpSessionListener)
1182: getSessionManager().addListener(
1183: (HttpSessionListener) listenerObj);
1184:
1185: if (listenerObj instanceof HttpSessionAttributeListener)
1186: getSessionManager().addAttributeListener(
1187: (HttpSessionAttributeListener) listenerObj);
1188:
1189: if (listenerObj instanceof HttpSessionActivationListener)
1190: getSessionManager().addActivationListener(
1191: (HttpSessionActivationListener) listenerObj);
1192: }
1193:
1194: /**
1195: * Returns the request listeners.
1196: */
1197: public ServletRequestListener[] getRequestListeners() {
1198: return _requestListenerArray;
1199: }
1200:
1201: /**
1202: * Returns the request attribute listeners.
1203: */
1204: public ServletRequestAttributeListener[] getRequestAttributeListeners() {
1205: return _requestAttributeListenerArray;
1206: }
1207:
1208: /**
1209: * Adds a ResourceRef validator.
1210: */
1211: public void addResourceRef(ResourceRef ref) {
1212: _resourceValidators.add(ref);
1213: }
1214:
1215: // special config
1216:
1217: /**
1218: * Multipart form config.
1219: */
1220: public MultipartForm createMultipartForm() {
1221: if (_multipartForm == null)
1222: _multipartForm = new MultipartForm();
1223:
1224: return _multipartForm;
1225: }
1226:
1227: /**
1228: * Returns true if multipart forms are enabled.
1229: */
1230: public boolean doMultipartForm() {
1231: return _multipartForm != null && _multipartForm.isEnable();
1232: }
1233:
1234: /**
1235: * Returns the form upload max.
1236: */
1237: public long getFormUploadMax() {
1238: if (_multipartForm != null)
1239: return _multipartForm.getUploadMax();
1240: else
1241: return -1;
1242: }
1243:
1244: /**
1245: * Returns the access log
1246: */
1247: public AbstractAccessLog getAccessLog() {
1248: return _accessLog;
1249: }
1250:
1251: /**
1252: * Sets the temporary directory
1253: */
1254: public void setTempDir(Path path) {
1255: _tempDir = path;
1256: }
1257:
1258: /**
1259: * jsp configuration
1260: */
1261: public JspPropertyGroup createJsp() {
1262: if (_jsp == null) {
1263: _jsp = new JspPropertyGroup();
1264: }
1265:
1266: return _jsp;
1267: }
1268:
1269: /**
1270: * Returns the JSP configuration.
1271: */
1272: public JspPropertyGroup getJsp() {
1273: return _jsp;
1274: }
1275:
1276: /**
1277: * Returns the JspApplicationContext for EL evaluation.
1278: */
1279: public JspApplicationContextImpl getJspApplicationContext() {
1280: return _jspApplicationContext;
1281: }
1282:
1283: /**
1284: * Returns true for JSP 1.x
1285: */
1286: public boolean has23Config() {
1287: return _jspState == JSP_1;
1288: }
1289:
1290: /**
1291: * taglib configuration
1292: */
1293: public void addTaglib(JspTaglib taglib) {
1294: if (_taglibList == null) {
1295: _taglibList = new ArrayList<JspTaglib>();
1296: }
1297:
1298: _taglibList.add(taglib);
1299: }
1300:
1301: /**
1302: * Returns the taglib configuration.
1303: */
1304: public ArrayList<JspTaglib> getTaglibList() {
1305: return _taglibList;
1306: }
1307:
1308: public JspConfig createJspConfig() {
1309: return new JspConfig(this );
1310: }
1311:
1312: /**
1313: * jsp-config configuration
1314: */
1315: public void addJspConfig(JspConfig config) {
1316: _extensions.put("jsp-config", config);
1317: }
1318:
1319: /**
1320: * Returns an extension.
1321: */
1322: public Object getExtension(String key) {
1323: return _extensions.get(key);
1324: }
1325:
1326: /**
1327: * ejb-ref configuration
1328: */
1329: public EjbRef createEjbRef() {
1330: if (_controller != null && _controller.getArchivePath() != null)
1331: return new EjbRef(_controller.getArchivePath());
1332: else
1333: return new EjbRef();
1334: }
1335:
1336: /**
1337: * ejb-local-ref configuration
1338: */
1339: public EjbLocalRef createEjbLocalRef() {
1340: if (_controller != null && _controller.getArchivePath() != null)
1341: return new EjbLocalRef(_controller.getArchivePath());
1342: else
1343: return new EjbLocalRef();
1344: }
1345:
1346: /**
1347: * Sets the war-expansion
1348: */
1349: public WebAppExpandDeployGenerator createWebAppDeploy() {
1350: return _parent.createWebAppDeploy();
1351: }
1352:
1353: /**
1354: * Adds a war generator
1355: */
1356: public void addWebAppDeploy(WebAppExpandDeployGenerator deploy)
1357: throws Exception {
1358: String contextPath = getContextPath();
1359: String prefix = deploy.getURLPrefix();
1360:
1361: deploy.setURLPrefix(contextPath + prefix);
1362: deploy.setParent(_controller);
1363:
1364: // _parent.addWebAppDeploy(gen);
1365:
1366: deploy.setParentClassLoader(getClassLoader());
1367: // deploy.deploy();
1368: // XXX: The parent is added in the init()
1369: // server/10t3
1370: // _parent.addWebAppDeploy(deploy);
1371:
1372: for (WebAppConfig configDefault : _webAppDefaultList)
1373: deploy.addWebAppDefault(configDefault);
1374:
1375: Environment.addEnvironmentListener(deploy, getClassLoader());
1376:
1377: _appGenerators.add(deploy);
1378: }
1379:
1380: /**
1381: * Adds a web-app default
1382: */
1383: public void addWebAppDefault(WebAppConfig config) {
1384: _webAppDefaultList.add(config);
1385: }
1386:
1387: /**
1388: * Adds a web-app default
1389: */
1390: public ArrayList<WebAppConfig> getWebAppDefaultList() {
1391: return _webAppDefaultList;
1392: }
1393:
1394: /**
1395: * Adds a sub web-app
1396: */
1397: public void addWebApp(WebAppConfig config) throws Exception {
1398: String contextPath = getContextPath();
1399: String prefix = config.getId();
1400:
1401: if (prefix == null || prefix.equals("") || prefix.equals("/"))
1402: throw new ConfigException(L.l(
1403: "'{0}' is an illegal sub web-app id.", prefix));
1404:
1405: WebAppContainer container = _parent;
1406: DeployContainer<WebAppController> appGenerator;
1407: appGenerator = _parent.getWebAppGenerator();
1408:
1409: WebAppSingleDeployGenerator deploy;
1410: deploy = new WebAppSingleDeployGenerator(appGenerator,
1411: container, config);
1412:
1413: deploy.setURLPrefix(contextPath + prefix);
1414: // deploy.setParent(_controller);
1415:
1416: // XXX: The parent is added in the init()
1417: // _parent.addWebAppDeploy(gen);
1418:
1419: deploy.setParentWebApp(_controller);
1420: deploy.setParentClassLoader(getClassLoader());
1421: deploy.setContainer(container);
1422:
1423: for (WebAppConfig configDefault : _webAppDefaultList)
1424: deploy.addWebAppDefault(configDefault);
1425:
1426: String appDir = config.getDocumentDirectory();
1427:
1428: if (appDir == null)
1429: appDir = "./" + prefix;
1430:
1431: Path root = PathBuilder.lookupPath(appDir, null, getAppDir());
1432:
1433: deploy.setRootDirectory(root);
1434:
1435: deploy.init();
1436:
1437: _parent.addDeploy(deploy);
1438:
1439: //_appGenerators.add(deploy);
1440:
1441: //deploy.deploy();
1442: }
1443:
1444: /**
1445: * Sets the config exception.
1446: */
1447: public void setConfigException(Throwable e) {
1448: if (e != null) {
1449: Throwable e1 = e;
1450: for (; e1 != null && !(e1 instanceof ConfigException)
1451: && e1.getCause() != null && e1.getCause() != e1; e1 = e1
1452: .getCause()) {
1453: }
1454:
1455: if (e1 != null) {
1456: if (e1 instanceof ConfigException) {
1457: if (log.isLoggable(Level.FINE))
1458: log.log(Level.WARNING, e1.toString(), e1);
1459: else
1460: log.warning(e1.getMessage());
1461: } else {
1462: log.log(Level.WARNING, e1.toString(), e1);
1463: }
1464: }
1465: }
1466:
1467: if (_configException == null)
1468: _configException = e;
1469:
1470: // server/13l8
1471: if (e != null) { // && _invocationDependency != null) {
1472: // _invocationDependency.add
1473: // _invocationDependency.clearModified();
1474:
1475: _classLoader.addDependency(AlwaysModified.create());
1476: }
1477: }
1478:
1479: /**
1480: * Gets the config exception.
1481: */
1482: public Throwable getConfigException() {
1483: return _configException;
1484: }
1485:
1486: /**
1487: * Returns the current cluster.
1488: */
1489: public Cluster getCluster() {
1490: return Cluster.getCluster(getClassLoader());
1491: }
1492:
1493: /**
1494: * Returns true if should ignore client disconnect.
1495: */
1496: public boolean isIgnoreClientDisconnect() {
1497: DispatchServer server = getDispatchServer();
1498:
1499: if (server == null)
1500: return true;
1501: else
1502: return server.isIgnoreClientDisconnect();
1503: }
1504:
1505: /**
1506: * Sets the delay time waiting for requests to end.
1507: */
1508: public void setShutdownWaitMax(Period wait) {
1509: _shutdownWaitTime = wait.getPeriod();
1510:
1511: Resin resin = Resin.getLocal();
1512: if (resin != null
1513: && resin.getShutdownWaitMax() < _shutdownWaitTime) {
1514: log
1515: .warning(L
1516: .l(
1517: "web-app shutdown-wait-max '{0}' is longer than resin shutdown-wait-max '{1}'.",
1518: _shutdownWaitTime, resin
1519: .getShutdownWaitMax()));
1520: }
1521: }
1522:
1523: /**
1524: * Sets the delay time waiting for a restart
1525: */
1526: public void setActiveWaitTime(Period wait) {
1527: _activeWaitTime = wait.getPeriod();
1528: }
1529:
1530: /**
1531: * Sets the delay time waiting for requests to end.
1532: */
1533: public void setIdleTime(Period idle) {
1534: _idleTime = idle.getPeriod();
1535: }
1536:
1537: /**
1538: * Backwards compatability for config-file.
1539: */
1540: public void addConfigFile(Path path) throws Exception {
1541: com.caucho.config.core.ResinImport rImport;
1542: rImport = new com.caucho.config.core.ResinImport();
1543: rImport.setPath(path);
1544: rImport.setOptional(true);
1545: rImport.setParent(this );
1546: rImport.init();
1547:
1548: log
1549: .config("<config-file> is deprecated. Please use resin:import.");
1550: }
1551:
1552: /**
1553: * Returns true if the webApp is active.
1554: */
1555: public String getState() {
1556: return _lifecycle.getStateName();
1557: }
1558:
1559: /**
1560: * Returns true if it's init.
1561: */
1562: public boolean isInit() {
1563: return _lifecycle.isInit() || _configException != null;
1564: }
1565:
1566: /**
1567: * Returns true if it's in the middle of initializing
1568: */
1569: public boolean isInitializing() {
1570: return _lifecycle.isBeforeActive();
1571: }
1572:
1573: /**
1574: * Returns true if the webApp is active.
1575: */
1576: public boolean isActive() {
1577: return _lifecycle.isActive();
1578: }
1579:
1580: /**
1581: * Returns true if it's closed.
1582: */
1583: public boolean isClosed() {
1584: return _lifecycle.isDestroyed();
1585: }
1586:
1587: static ThreadLocal<ServletRequest> getRequestThreadLocal() {
1588: return _requestThreadLocal;
1589: }
1590:
1591: public static ServletRequest getThreadRequest() {
1592: return _requestThreadLocal.get();
1593: }
1594:
1595: /**
1596: * Initializes.
1597: */
1598: @PostConstruct
1599: public void init() throws Exception {
1600: if (!_lifecycle.toInitializing())
1601: return;
1602:
1603: try {
1604: _classLoader.setId("web-app:" + getURL());
1605:
1606: _invocationDependency
1607: .setCheckInterval(getEnvironmentClassLoader()
1608: .getDependencyCheckInterval());
1609:
1610: if (_tempDir == null)
1611: _tempDir = (Path) Environment
1612: .getLevelAttribute("caucho.temp-dir");
1613:
1614: if (_tempDir == null) {
1615: _tempDir = getAppDir().lookup("WEB-INF/tmp");
1616:
1617: if (getAppDir().lookup("WEB-INF").isDirectory())
1618: _tempDir.mkdirs();
1619: } else
1620: _tempDir.mkdirs();
1621:
1622: setAttribute("javax.servlet.context.tempdir", new File(
1623: _tempDir.getNativePath()));
1624:
1625: FilterChainBuilder securityBuilder = _constraintManager
1626: .getFilterBuilder();
1627:
1628: if (securityBuilder != null)
1629: _filterMapper.addTopFilter(securityBuilder);
1630:
1631: _cache = (AbstractCache) Environment
1632: .getAttribute("caucho.server.cache");
1633:
1634: for (int i = 0; i < _appGenerators.size(); i++)
1635: _parent.addDeploy(_appGenerators.get(i));
1636:
1637: _classLoader.setId("web-app:" + getURL());
1638:
1639: try {
1640: InitialContext ic = new InitialContext();
1641: ServletAuthenticator auth;
1642: auth = (ServletAuthenticator) ic
1643: .lookup("java:comp/env/caucho/auth");
1644:
1645: setAttribute("caucho.authenticator", auth);
1646: } catch (Exception e) {
1647: log.finest(e.toString());
1648: }
1649:
1650: WebAppController parent = null;
1651: if (_controller != null)
1652: parent = _controller.getParent();
1653: if (_isInheritSession
1654: && parent != null
1655: && _sessionManager != parent.getWebApp()
1656: .getSessionManager()) {
1657: SessionManager sessionManager = _sessionManager;
1658: _sessionManager = parent.getWebApp()
1659: .getSessionManager();
1660:
1661: if (sessionManager != null)
1662: sessionManager.close();
1663: }
1664:
1665: if (getSessionManager() != null)
1666: getSessionManager().init();
1667:
1668: _characterEncoding = CharacterEncoding.getLocalEncoding();
1669:
1670: for (int i = 0; i < _resourceValidators.size(); i++) {
1671: Validator validator = _resourceValidators.get(i);
1672:
1673: validator.validate();
1674: }
1675: } finally {
1676: _lifecycle.toInit();
1677: }
1678: }
1679:
1680: public WebAppAdmin getAdmin() {
1681: return _controller.getAdmin();
1682: }
1683:
1684: public void start() {
1685: if (!_lifecycle.isAfterInit())
1686: throw new IllegalStateException(
1687: L
1688: .l(
1689: "webApp must be initialized before starting. Currently in state {0}.",
1690: _lifecycle.getStateName()));
1691:
1692: Thread thread = Thread.currentThread();
1693: ClassLoader oldLoader = thread.getContextClassLoader();
1694: boolean isOkay = true;
1695:
1696: try {
1697: thread.setContextClassLoader(_classLoader);
1698:
1699: if (!_lifecycle.toStarting())
1700: return;
1701:
1702: isOkay = false;
1703:
1704: if (_accessLog == null)
1705: _accessLog = _accessLogLocal.get();
1706:
1707: long interval = _classLoader.getDependencyCheckInterval();
1708: _invocationDependency.setCheckInterval(interval);
1709:
1710: if (_parent != null)
1711: _invocationDependency.add(_parent.getWebAppGenerator());
1712:
1713: // Sets the last modified time so the app won't immediately restart
1714: _invocationDependency.clearModified();
1715: _classLoader.clearModified();
1716:
1717: String serverId = (String) new EnvironmentLocal(
1718: "caucho.server-id").get();
1719: if (serverId != null)
1720: setAttribute("caucho.server-id", serverId);
1721:
1722: _classLoader.start();
1723:
1724: // configuration exceptions discovered by resources like
1725: // the persistence manager
1726: if (_configException == null)
1727: _configException = Environment.getConfigException();
1728:
1729: try {
1730: getSessionManager().start();
1731: } catch (Throwable e) {
1732: log.log(Level.WARNING, e.toString(), e);
1733: }
1734:
1735: _jspApplicationContext
1736: .addELResolver(new WebBeansELResolver());
1737:
1738: ServletContextEvent event = new ServletContextEvent(this );
1739:
1740: for (Listener listener : _listeners) {
1741: try {
1742: addListenerObject(listener.createListenerObject(),
1743: false);
1744: } catch (Exception e) {
1745: throw ConfigException.create(e);
1746: }
1747: }
1748:
1749: for (int i = 0; i < _webAppListeners.size(); i++) {
1750: ServletContextListener listener = _webAppListeners
1751: .get(i);
1752:
1753: try {
1754: listener.contextInitialized(event);
1755: } catch (Exception e) {
1756: log.log(Level.WARNING, e.toString(), e);
1757: }
1758: }
1759:
1760: try {
1761: _filterManager.init();
1762: _servletManager.init();
1763: } catch (Exception e) {
1764: setConfigException(e);
1765: }
1766:
1767: _lifecycle.toActive();
1768:
1769: if (_parent instanceof Host) {
1770: Host host = (Host) _parent;
1771:
1772: host.setConfigETag(null);
1773: }
1774:
1775: if (_parent != null)
1776: _parent.clearCache();
1777:
1778: isOkay = true;
1779: } finally {
1780: if (!isOkay)
1781: _lifecycle.toError();
1782:
1783: thread.setContextClassLoader(oldLoader);
1784: }
1785: }
1786:
1787: /**
1788: * Returns true if the webApp has been modified.
1789: */
1790: public boolean isModified() {
1791: // server/13l8
1792:
1793: // _configException test is needed so compilation failures will force
1794: // restart
1795: if (_lifecycle.isAfterActive())
1796: return true;
1797: else if (_classLoader.isModified())
1798: return true;
1799: else
1800: return false;
1801: }
1802:
1803: /**
1804: * Returns true if the webApp has been modified.
1805: */
1806: public boolean isModifiedNow() {
1807: // force check
1808: _classLoader.isModifiedNow();
1809: _invocationDependency.isModifiedNow();
1810:
1811: return isModified();
1812: }
1813:
1814: /**
1815: * Log the reason for modification.
1816: */
1817: public boolean logModified(Logger log) {
1818: if (_lifecycle.isAfterActive()) {
1819: // closed web-apps don't modify (XXX: errors?)
1820: return true;
1821: } else
1822: return _classLoader.logModified(log);
1823: }
1824:
1825: /**
1826: * Returns true if the webApp deployed with an error.
1827: */
1828: public boolean isDeployError() {
1829: return _configException != null;
1830: }
1831:
1832: /**
1833: * Returns true if the deployment is idle.
1834: */
1835: public boolean isDeployIdle() {
1836: if (_idleTime < 0)
1837: return false;
1838: else
1839: return _lastRequestTime + _idleTime < Alarm
1840: .getCurrentTime();
1841: }
1842:
1843: /**
1844: * Returns the servlet context for the URI.
1845: */
1846: public ServletContext getContext(String uri) {
1847: if (uri == null)
1848: throw new IllegalArgumentException(L
1849: .l("getContext URI must not be null."));
1850: else if (uri.startsWith("/")) {
1851: }
1852:
1853: else if (uri.equals(""))
1854: uri = "/";
1855:
1856: else
1857: throw new IllegalArgumentException(L.l(
1858: "getContext URI '{0}' must be absolute.", uri));
1859:
1860: try {
1861: if (_isDisableCrossContext)
1862: return uri.startsWith(getContextPath()) ? this : null;
1863: else if (_parent != null)
1864: return _parent.findSubWebAppByURI(uri);
1865: else
1866: return this ;
1867: } catch (Exception e) {
1868: log.log(Level.WARNING, e.toString(), e);
1869:
1870: return null;
1871: }
1872: }
1873:
1874: /**
1875: * Returns the best matching servlet pattern.
1876: */
1877: public String getServletPattern(String uri) {
1878: return _servletMapper.getServletPattern(uri);
1879: }
1880:
1881: /**
1882: * Returns the best matching servlet pattern.
1883: */
1884: public ArrayList<String> getServletMappingPatterns() {
1885: return _servletMapper.getURLPatterns();
1886: }
1887:
1888: /**
1889: * Returns the best matching servlet pattern.
1890: */
1891: public ArrayList<String> getServletIgnoreMappingPatterns() {
1892: return _servletMapper.getIgnorePatterns();
1893: }
1894:
1895: /**
1896: * Fills the servlet instance. (Generalize?)
1897: */
1898: public Invocation buildInvocation(Invocation invocation) {
1899: Thread thread = Thread.currentThread();
1900: ClassLoader oldLoader = thread.getContextClassLoader();
1901:
1902: thread.setContextClassLoader(getClassLoader());
1903: try {
1904: FilterChain chain = null;
1905:
1906: if (_configException != null) {
1907: chain = new ExceptionFilterChain(_configException);
1908: invocation.setFilterChain(chain);
1909: invocation.setDependency(AlwaysModified.create());
1910:
1911: return invocation;
1912: } else if (!_lifecycle.waitForActive(_activeWaitTime)) {
1913: int code = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
1914: chain = new ErrorFilterChain(code);
1915: invocation.setFilterChain(chain);
1916: invocation.setDependency(AlwaysModified.create());
1917:
1918: return invocation;
1919: } else {
1920: FilterChainEntry entry = null;
1921:
1922: // jsp/1910 - can't cache jsp_precompile
1923: String query = invocation.getQueryString();
1924:
1925: boolean isPrecompile = false;
1926: if (query != null
1927: && query.indexOf("jsp_precompile") >= 0)
1928: isPrecompile = true;
1929:
1930: if (!isPrecompile)
1931: entry = _filterChainCache.get(invocation
1932: .getContextURI());
1933:
1934: if (entry != null && !entry.isModified()) {
1935: chain = entry.getFilterChain();
1936: } else {
1937: chain = _servletMapper.mapServlet(invocation);
1938:
1939: if (_rewriteDispatch != null) {
1940: chain = _rewriteDispatch.map(invocation
1941: .getContextURI(), invocation
1942: .getQueryString(), chain);
1943: }
1944:
1945: // server/13s[o-r]
1946: _filterMapper.buildDispatchChain(invocation, chain);
1947:
1948: chain = invocation.getFilterChain();
1949:
1950: entry = new FilterChainEntry(chain, invocation);
1951: chain = entry.getFilterChain();
1952:
1953: if (!isPrecompile)
1954: _filterChainCache.put(invocation
1955: .getContextURI(), entry);
1956: }
1957:
1958: // the cache must be outside of the WebAppFilterChain because
1959: // the CacheListener in ServletInvocation needs the top to
1960: // be a CacheListener. Otherwise, the cache won't get lru.
1961:
1962: // top-level filter elements
1963: if (_cache != null)
1964: chain = _cache.createFilterChain(chain, this );
1965:
1966: if (CauchoSystem.isDetailedStatistics())
1967: chain = new StatisticsFilterChain(chain, this );
1968:
1969: WebAppFilterChain webAppChain = new WebAppFilterChain(
1970: chain, this );
1971:
1972: webAppChain.setSecurityRoleMap(invocation
1973: .getSecurityRoleMap());
1974:
1975: invocation.setFilterChain(webAppChain);
1976: invocation.setPathInfo(entry.getPathInfo());
1977: invocation.setServletPath(entry.getServletPath());
1978: }
1979:
1980: if (_oldWebApp != null
1981: && Alarm.getCurrentTime() < _oldWebAppExpireTime) {
1982: Invocation oldInvocation = new Invocation();
1983: oldInvocation.copyFrom(invocation);
1984: oldInvocation.setWebApp(_oldWebApp);
1985:
1986: _oldWebApp.buildInvocation(oldInvocation);
1987:
1988: invocation = new VersionInvocation(invocation, this ,
1989: oldInvocation, oldInvocation.getWebApp(),
1990: _oldWebAppExpireTime);
1991: }
1992:
1993: return invocation;
1994: } catch (Throwable e) {
1995: FilterChain chain = new ExceptionFilterChain(e);
1996: chain = new WebAppFilterChain(chain, this );
1997: invocation.setDependency(AlwaysModified.create());
1998: invocation.setFilterChain(chain);
1999:
2000: return invocation;
2001: } finally {
2002: thread.setContextClassLoader(oldLoader);
2003: }
2004: }
2005:
2006: /**
2007: * Clears all caches, including the invocation cache, the filter cache, and the proxy cache.
2008: */
2009: public void clearCache() {
2010: // server/1kg1
2011: synchronized (this ) {
2012: synchronized (_filterChainCache) {
2013: getDispatchServer().clearCache();
2014: _filterChainCache.clear();
2015: _dispatcherCache = null;
2016: }
2017: }
2018: }
2019:
2020: /**
2021: * Fills the invocation for an include request.
2022: */
2023: public void buildIncludeInvocation(Invocation invocation)
2024: throws ServletException {
2025: buildDispatchInvocation(invocation, _includeFilterMapper);
2026: }
2027:
2028: /**
2029: * Fills the invocation for a forward request.
2030: */
2031: public void buildForwardInvocation(Invocation invocation)
2032: throws ServletException {
2033: buildDispatchInvocation(invocation, _forwardFilterMapper);
2034: }
2035:
2036: /**
2037: * Fills the invocation for an error request.
2038: */
2039: public void buildErrorInvocation(Invocation invocation)
2040: throws ServletException {
2041: buildDispatchInvocation(invocation, _errorFilterMapper);
2042: }
2043:
2044: /**
2045: * Fills the invocation for a login request.
2046: */
2047: public void buildLoginInvocation(Invocation invocation)
2048: throws ServletException {
2049: buildDispatchInvocation(invocation, _loginFilterMapper);
2050: }
2051:
2052: /**
2053: * Fills the invocation for subrequests.
2054: */
2055: public void buildDispatchInvocation(Invocation invocation,
2056: FilterMapper filterMapper) throws ServletException {
2057: invocation.setWebApp(this );
2058:
2059: Thread thread = Thread.currentThread();
2060: ClassLoader oldLoader = thread.getContextClassLoader();
2061:
2062: thread.setContextClassLoader(getClassLoader());
2063: try {
2064: FilterChain chain;
2065:
2066: /*
2067: if (! _isActive) {
2068: int code = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
2069: chain = new ErrorFilterChain(code);
2070: invocation.setFilterChain(chain);
2071: invocation.setDependency(AlwaysModified.create());
2072: return;
2073: }
2074: */
2075: if (_configException != null) {
2076: chain = new ExceptionFilterChain(_configException);
2077: invocation.setDependency(AlwaysModified.create());
2078: } else if (!_lifecycle.waitForActive(_activeWaitTime)) {
2079: Exception exn = new UnavailableException(L.l(
2080: "'{0}' is not currently available.",
2081: getContextPath()));
2082: chain = new ExceptionFilterChain(exn);
2083: invocation.setDependency(AlwaysModified.create());
2084: } else {
2085: chain = _servletMapper.mapServlet(invocation);
2086:
2087: filterMapper.buildDispatchChain(invocation, chain);
2088:
2089: chain = invocation.getFilterChain();
2090:
2091: chain = new DispatchFilterChain(chain, this );
2092:
2093: if (_cache != null
2094: && filterMapper == _includeFilterMapper) {
2095: chain = _cache.createFilterChain(chain, this );
2096: }
2097: }
2098:
2099: invocation.setFilterChain(chain);
2100: } finally {
2101: thread.setContextClassLoader(oldLoader);
2102: }
2103: }
2104:
2105: /**
2106: * Returns a dispatcher for the named servlet.
2107: */
2108: public RequestDispatcher getRequestDispatcher(String url) {
2109: if (url == null)
2110: throw new IllegalArgumentException(L
2111: .l("request dispatcher url can't be null."));
2112: else if (!url.startsWith("/"))
2113: throw new IllegalArgumentException(L.l(
2114: "request dispatcher url '{0}' must be absolute",
2115: url));
2116:
2117: RequestDispatcherImpl disp = getDispatcherCache().get(url);
2118:
2119: if (disp != null && !disp.isModified())
2120: return disp;
2121:
2122: Invocation includeInvocation = new SubInvocation();
2123: Invocation forwardInvocation = new SubInvocation();
2124: Invocation errorInvocation = new SubInvocation();
2125: InvocationDecoder decoder = new InvocationDecoder();
2126:
2127: String rawURI = escapeURL(_contextPath + url);
2128:
2129: try {
2130: decoder.splitQuery(includeInvocation, rawURI);
2131: decoder.splitQuery(forwardInvocation, rawURI);
2132: decoder.splitQuery(errorInvocation, rawURI);
2133:
2134: if (_parent != null) {
2135: _parent.buildIncludeInvocation(includeInvocation);
2136: _parent.buildForwardInvocation(forwardInvocation);
2137: _parent.buildErrorInvocation(errorInvocation);
2138: } else {
2139: FilterChain chain = _servletMapper
2140: .mapServlet(includeInvocation);
2141: _includeFilterMapper.buildDispatchChain(
2142: includeInvocation, chain);
2143: includeInvocation.setWebApp(this );
2144:
2145: chain = _servletMapper.mapServlet(forwardInvocation);
2146: _forwardFilterMapper.buildDispatchChain(
2147: forwardInvocation, chain);
2148: forwardInvocation.setWebApp(this );
2149:
2150: chain = _servletMapper.mapServlet(errorInvocation);
2151: _errorFilterMapper.buildDispatchChain(errorInvocation,
2152: chain);
2153: errorInvocation.setWebApp(this );
2154: }
2155:
2156: disp = new RequestDispatcherImpl(includeInvocation,
2157: forwardInvocation, errorInvocation, this );
2158:
2159: getDispatcherCache().put(url, disp);
2160:
2161: return disp;
2162: } catch (Exception e) {
2163: log.log(Level.FINE, e.toString(), e);
2164:
2165: return null;
2166: }
2167: }
2168:
2169: /**
2170: * Access logging for high-level errors
2171: */
2172: public void accessLog(HttpServletRequest req,
2173: HttpServletResponse res) throws IOException {
2174: AbstractAccessLog log = getAccessLog();
2175: if (log != null)
2176: log.log(req, res, this );
2177: }
2178:
2179: private LruCache<String, RequestDispatcherImpl> getDispatcherCache() {
2180: LruCache<String, RequestDispatcherImpl> cache = _dispatcherCache;
2181:
2182: if (cache != null)
2183: return cache;
2184:
2185: synchronized (this ) {
2186: cache = new LruCache<String, RequestDispatcherImpl>(1024);
2187: _dispatcherCache = cache;
2188: return cache;
2189: }
2190: }
2191:
2192: private String escapeURL(String url) {
2193: return url;
2194:
2195: /* jsp/15dx
2196: CharBuffer cb = CharBuffer.allocate();
2197:
2198: int length = url.length();
2199: for (int i = 0; i < length; i++) {
2200: char ch = url.charAt(i);
2201:
2202: if (ch < 0x80)
2203: cb.append(ch);
2204: else if (ch < 0x800) {
2205: cb.append((char) (0xc0 | (ch >> 6)));
2206: cb.append((char) (0x80 | (ch & 0x3f)));
2207: }
2208: else {
2209: cb.append((char) (0xe0 | (ch >> 12)));
2210: cb.append((char) (0x80 | ((ch >> 6) & 0x3f)));
2211: cb.append((char) (0x80 | (ch & 0x3f)));
2212: }
2213: }
2214:
2215: return cb.close();
2216: */
2217: }
2218:
2219: /**
2220: * Returns a dispatcher for the named servlet.
2221: */
2222: public RequestDispatcher getLoginDispatcher(String url) {
2223: if (url == null)
2224: throw new IllegalArgumentException(L
2225: .l("request dispatcher url can't be null."));
2226: else if (!url.startsWith("/"))
2227: throw new IllegalArgumentException(L.l(
2228: "request dispatcher url '{0}' must be absolute",
2229: url));
2230:
2231: Invocation loginInvocation = new Invocation();
2232: Invocation errorInvocation = new Invocation();
2233: InvocationDecoder decoder = new InvocationDecoder();
2234:
2235: String rawURI = _contextPath + url;
2236:
2237: try {
2238: decoder.splitQuery(loginInvocation, rawURI);
2239: decoder.splitQuery(errorInvocation, rawURI);
2240:
2241: if (_parent != null) {
2242: _parent.buildInvocation(loginInvocation);
2243: _parent.buildErrorInvocation(errorInvocation);
2244: } else {
2245: FilterChain chain = _servletMapper
2246: .mapServlet(loginInvocation);
2247: _filterMapper
2248: .buildDispatchChain(loginInvocation, chain);
2249:
2250: chain = _servletMapper.mapServlet(errorInvocation);
2251: _errorFilterMapper.buildDispatchChain(errorInvocation,
2252: chain);
2253: }
2254:
2255: RequestDispatcherImpl disp;
2256: disp = new RequestDispatcherImpl(loginInvocation,
2257: loginInvocation, errorInvocation, this );
2258: disp.setLogin(true);
2259:
2260: return disp;
2261: } catch (Exception e) {
2262: log.log(Level.FINE, e.toString(), e);
2263:
2264: return null;
2265: }
2266: }
2267:
2268: /**
2269: * Returns a dispatcher for the named servlet.
2270: */
2271: public RequestDispatcher getNamedDispatcher(String servletName) {
2272: try {
2273: FilterChain chain = _servletManager
2274: .createServletChain(servletName);
2275:
2276: FilterChain includeChain = _includeFilterMapper
2277: .buildFilterChain(chain, servletName);
2278: FilterChain forwardChain = _forwardFilterMapper
2279: .buildFilterChain(chain, servletName);
2280:
2281: return new NamedDispatcherImpl(includeChain, forwardChain,
2282: null, this );
2283: } catch (Exception e) {
2284: log.log(Level.FINEST, e.toString(), e);
2285:
2286: return null;
2287: }
2288: }
2289:
2290: /**
2291: * Maps from a URI to a real path.
2292: */
2293: @Override
2294: public String getRealPath(String uri) {
2295: String realPath = _realPathCache.get(uri);
2296:
2297: if (realPath != null)
2298: return realPath;
2299:
2300: String fullURI = getContextPath() + "/" + uri;
2301:
2302: try {
2303: fullURI = InvocationDecoder.normalizeUri(fullURI);
2304: } catch (Exception e) {
2305: log.log(Level.WARNING, e.toString(), e);
2306: }
2307:
2308: WebApp app = (WebApp) getContext(fullURI);
2309:
2310: if (app == null)
2311: return null;
2312:
2313: String cp = app.getContextPath();
2314: String tail = fullURI.substring(cp.length());
2315:
2316: realPath = app.getRealPathImpl(tail);
2317:
2318: if (log.isLoggable(Level.FINEST))
2319: log.finest("real-path " + uri + " -> " + realPath);
2320:
2321: _realPathCache.put(uri, realPath);
2322:
2323: return realPath;
2324: }
2325:
2326: /**
2327: * Maps from a URI to a real path.
2328: */
2329: public String getRealPathImpl(String uri) {
2330: return createRewriteRealPath().mapToRealPath(uri);
2331: }
2332:
2333: /**
2334: * Returns the mime type for a uri
2335: */
2336: public String getMimeType(String uri) {
2337: if (uri == null)
2338: return null;
2339:
2340: String fullURI = getContextPath() + "/" + uri;
2341:
2342: try {
2343: fullURI = InvocationDecoder.normalizeUri(fullURI);
2344: } catch (Exception e) {
2345: log.log(Level.WARNING, e.toString(), e);
2346: }
2347:
2348: WebApp app = (WebApp) getContext(fullURI);
2349:
2350: if (app == null)
2351: return null;
2352:
2353: int p = uri.lastIndexOf('.');
2354:
2355: if (p < 0)
2356: return null;
2357: else
2358: return app.getMimeTypeImpl(uri.substring(p));
2359: }
2360:
2361: /**
2362: * Maps from a URI to a real path.
2363: */
2364: public String getMimeTypeImpl(String ext) {
2365: return _mimeMapping.get(ext);
2366: }
2367:
2368: /**
2369: * Error logging
2370: *
2371: * @param message message to log
2372: * @param e stack trace of the error
2373: */
2374: public void log(String message, Throwable e) {
2375: if (e != null)
2376: log.log(Level.WARNING, this + " " + message, e);
2377: else
2378: log.info(this + " " + message);
2379: }
2380:
2381: /**
2382: * Gets the login manager.
2383: */
2384: public AbstractLogin getLogin() {
2385: if (_loginFactory != null) {
2386: synchronized (_loginFactory) {
2387: _login = _loginFactory.getLoginObject();
2388: }
2389:
2390: return _login;
2391: } else
2392: return _loginManager;
2393: }
2394:
2395: /**
2396: * Gets the authenticator
2397: */
2398: public ServletAuthenticator getAuthenticator() {
2399: AbstractLogin login = getLogin();
2400:
2401: if (login != null)
2402: return login.getAuthenticator();
2403: else
2404: return null;
2405: }
2406:
2407: /**
2408: * Gets the session manager.
2409: */
2410: public SessionManager getSessionManager() {
2411: if (_sessionManager == null) {
2412: if (_lifecycle.isStopped())
2413: throw new IllegalStateException(L
2414: .l("Resin is shutting down."));
2415:
2416: if (_isInheritSession && _parent != null)
2417: _sessionManager = _parent.getSessionManager();
2418:
2419: if (_sessionManager == null) {
2420: Thread thread = Thread.currentThread();
2421: ClassLoader oldLoader = thread.getContextClassLoader();
2422:
2423: try {
2424: thread.setContextClassLoader(getClassLoader());
2425:
2426: _sessionManager = new SessionManager(this );
2427: } catch (Throwable e) {
2428: log.log(Level.WARNING, e.toString(), e);
2429: } finally {
2430: thread.setContextClassLoader(oldLoader);
2431: }
2432: }
2433: }
2434:
2435: return _sessionManager;
2436: }
2437:
2438: /**
2439: * Gets the error page manager.
2440: */
2441: public ErrorPageManager getErrorPageManager() {
2442: return _errorPageManager;
2443: }
2444:
2445: /**
2446: * Called when a request starts the webApp.
2447: */
2448: final boolean enterWebApp() {
2449: synchronized (_countLock) {
2450: _requestCount++;
2451: _lastRequestTime = Alarm.getCurrentTime();
2452: }
2453:
2454: return _lifecycle.isActive();
2455: }
2456:
2457: /**
2458: * Called when a request starts the webApp.
2459: */
2460: final void exitWebApp() {
2461: synchronized (_countLock) {
2462: _requestCount--;
2463: }
2464: }
2465:
2466: /**
2467: * Returns the request count.
2468: */
2469: public int getRequestCount() {
2470: return _requestCount;
2471: }
2472:
2473: /**
2474: * Returns the maximum length for a cache.
2475: */
2476: public void addCacheMapping(CacheMapping mapping) throws Exception {
2477: if (mapping.getUrlRegexp() != null)
2478: _cacheMappingMap.addRegexp(mapping.getUrlRegexp(), mapping);
2479: else
2480: _cacheMappingMap.addMap(mapping.getUrlPattern(), mapping);
2481: }
2482:
2483: /**
2484: * Returns the time for a cache mapping.
2485: */
2486: public long getMaxAge(String uri) {
2487: CacheMapping map = (CacheMapping) _cacheMappingMap.map(uri);
2488:
2489: if (map != null)
2490: return map.getMaxAge();
2491: else
2492: return Long.MIN_VALUE;
2493: }
2494:
2495: /**
2496: * Returns the time for a cache mapping.
2497: */
2498: public long getSMaxAge(String uri) {
2499: CacheMapping map = (CacheMapping) _cacheMappingMap.map(uri);
2500:
2501: if (map != null)
2502: return map.getSMaxAge();
2503: else
2504: return Long.MIN_VALUE;
2505: }
2506:
2507: /**
2508: * Returns the maximum length for a cache.
2509: */
2510: public long getCacheMaxLength() {
2511: return _cache.getMaxEntrySize();
2512: }
2513:
2514: /**
2515: * Returns the classloader hack packages.
2516: */
2517: public String[] getClassLoaderHackPackages() {
2518: return _classLoaderHackPackages;
2519: }
2520:
2521: /**
2522: * Returns the active session count.
2523: */
2524: public int getActiveSessionCount() {
2525: SessionManager manager = getSessionManager();
2526:
2527: if (manager != null)
2528: return manager.getActiveSessionCount();
2529: else
2530: return 0;
2531: }
2532:
2533: void updateStatistics(long time, int readBytes, int writeBytes,
2534: boolean isClientDisconnect) {
2535: _controller.updateStatistics(time, readBytes, writeBytes,
2536: isClientDisconnect);
2537: }
2538:
2539: /**
2540: * Stops the webApp.
2541: */
2542: public void stop() {
2543: Thread thread = Thread.currentThread();
2544: ClassLoader oldLoader = thread.getContextClassLoader();
2545:
2546: try {
2547: thread.setContextClassLoader(getClassLoader());
2548:
2549: if (!_lifecycle.toStopping())
2550: return;
2551:
2552: long beginStop = Alarm.getCurrentTime();
2553:
2554: while (_requestCount > 0
2555: && Alarm.getCurrentTime() < beginStop
2556: + _shutdownWaitTime && !Alarm.isTest()) {
2557: try {
2558: Thread.interrupted();
2559: Thread.sleep(100);
2560: } catch (Throwable e) {
2561: }
2562: }
2563:
2564: if (_requestCount > 0) {
2565: log.warning(L.l(
2566: "{0} closing with {1} active requests.",
2567: toString(), _requestCount));
2568: }
2569:
2570: ServletContextEvent event = new ServletContextEvent(this );
2571:
2572: SessionManager sessionManager = _sessionManager;
2573: _sessionManager = null;
2574:
2575: if (sessionManager != null
2576: && (!_isInheritSession || _controller.getParent() == null))
2577: sessionManager.close();
2578:
2579: _servletManager.destroy();
2580: _filterManager.destroy();
2581:
2582: // server/10g8 -- webApp listeners after session
2583: for (int i = _webAppListeners.size() - 1; i >= 0; i--) {
2584: ServletContextListener listener = _webAppListeners
2585: .get(i);
2586:
2587: try {
2588: listener.contextDestroyed(event);
2589: } catch (Exception e) {
2590: log.log(Level.WARNING, e.toString(), e);
2591: }
2592: }
2593:
2594: try {
2595: _classLoader.stop();
2596: } catch (Throwable e) {
2597: log.log(Level.WARNING, e.toString(), e);
2598: }
2599: } finally {
2600: thread.setContextClassLoader(oldLoader);
2601:
2602: _lifecycle.toStop();
2603: }
2604: }
2605:
2606: /**
2607: * Closes the webApp.
2608: */
2609: public void destroy() {
2610: stop();
2611:
2612: if (!_lifecycle.toDestroy())
2613: return;
2614:
2615: if (_parent != null)
2616: _parent.clearCache();
2617:
2618: Thread thread = Thread.currentThread();
2619: ClassLoader oldLoader = thread.getContextClassLoader();
2620:
2621: try {
2622: thread.setContextClassLoader(getClassLoader());
2623:
2624: for (int i = _appGenerators.size() - 1; i >= 0; i--) {
2625: try {
2626: DeployGenerator deploy = _appGenerators.get(i);
2627: _parent.removeWebAppDeploy(deploy);
2628: deploy.destroy();
2629: } catch (Throwable e) {
2630: log.log(Level.WARNING, e.toString(), e);
2631: }
2632: }
2633:
2634: if (_accessLog != null) {
2635: _accessLog.flush();
2636: }
2637: } finally {
2638: thread.setContextClassLoader(oldLoader);
2639:
2640: _classLoader.destroy();
2641: }
2642: }
2643:
2644: //
2645: // statistics
2646: //
2647:
2648: public void addStatus500() {
2649: synchronized (this ) {
2650: _status500CountTotal++;
2651: _status500LastTime = Alarm.getExactTime();
2652: }
2653: }
2654:
2655: long getStatus500CountTotal() {
2656: return _status500CountTotal;
2657: }
2658:
2659: long getStatus500LastTime() {
2660: return _status500LastTime;
2661: }
2662:
2663: /**
2664: * Serialize to a handle
2665: */
2666: private Object writeReplace() {
2667: return new WebBeansHandle(WebApp.class);
2668: }
2669:
2670: public String toString() {
2671: return "WebApp[" + getURL() + "]";
2672: }
2673:
2674: static class FilterChainEntry {
2675: FilterChain _filterChain;
2676: String _pathInfo;
2677: String _servletPath;
2678: HashMap<String, String> _securityRoleMap;
2679: final Dependency _dependency;
2680:
2681: FilterChainEntry(FilterChain filterChain, Invocation invocation) {
2682: _filterChain = filterChain;
2683: _pathInfo = invocation.getPathInfo();
2684: _servletPath = invocation.getServletPath();
2685: _dependency = invocation.getDependency();
2686: }
2687:
2688: boolean isModified() {
2689: return _dependency != null && _dependency.isModified();
2690: }
2691:
2692: FilterChain getFilterChain() {
2693: return _filterChain;
2694: }
2695:
2696: HashMap<String, String> getSecurityRoleMap() {
2697: return _securityRoleMap;
2698: }
2699:
2700: void setSecurityRoleMap(HashMap<String, String> roleMap) {
2701: _securityRoleMap = roleMap;
2702: }
2703:
2704: String getPathInfo() {
2705: return _pathInfo;
2706: }
2707:
2708: String getServletPath() {
2709: return _servletPath;
2710: }
2711: }
2712:
2713: static {
2714: _classLoaderHackPackages = new String[] { "java.",
2715: "javax.servlet.", "javax.naming.", "javax.sql.",
2716: "javax.transaction.", };
2717: }
2718: }
|