1 29 30 package com.caucho.server.webapp; 31 32 import com.caucho.config.ConfigException; 33 import com.caucho.config.SchemaBean; 34 import com.caucho.config.types.InitParam; 35 import com.caucho.config.types.InitProgram; 36 import com.caucho.config.types.PathBuilder; 37 import com.caucho.config.types.Period; 38 import com.caucho.config.types.ResourceRef; 39 import com.caucho.config.types.Validator; 40 import com.caucho.java.WorkDir; 41 import com.caucho.jsp.JspServlet; 42 import com.caucho.jsp.cfg.JspConfig; 43 import com.caucho.jsp.cfg.JspPropertyGroup; 44 import com.caucho.jsp.cfg.JspTaglib; 45 import com.caucho.jsp.el.JspApplicationContextImpl; 46 import com.caucho.lifecycle.Lifecycle; 47 import com.caucho.loader.Environment; 48 import com.caucho.loader.EnvironmentBean; 49 import com.caucho.loader.EnvironmentClassLoader; 50 import com.caucho.loader.EnvironmentLocal; 51 import com.caucho.make.AlwaysModified; 52 import com.caucho.make.DependencyContainer; 53 import com.caucho.management.server.HostMXBean; 54 import com.caucho.server.cache.AbstractCache; 55 import com.caucho.server.cluster.Cluster; 56 import com.caucho.server.cluster.Server; 57 import com.caucho.server.deploy.DeployContainer; 58 import com.caucho.server.deploy.DeployGenerator; 59 import com.caucho.server.deploy.EnvironmentDeployInstance; 60 import com.caucho.server.dispatch.*; 61 import com.caucho.server.host.Host; 62 import com.caucho.server.log.AbstractAccessLog; 63 import com.caucho.server.log.AccessLog; 64 import com.caucho.server.resin.Resin; 65 import com.caucho.server.security.AbstractLogin; 66 import com.caucho.server.security.ConstraintManager; 67 import com.caucho.server.security.LoginConfig; 68 import com.caucho.server.security.SecurityConstraint; 69 import com.caucho.server.security.ServletAuthenticator; 70 import com.caucho.server.security.TransportConstraint; 71 import com.caucho.server.session.SessionManager; 72 import com.caucho.server.util.CauchoSystem; 73 import com.caucho.soa.client.WebServiceClient; 74 import com.caucho.transaction.TransactionManagerImpl; 75 import com.caucho.util.Alarm; 76 import com.caucho.util.L10N; 77 import com.caucho.util.Log; 78 import com.caucho.util.LruCache; 79 import com.caucho.vfs.Dependency; 80 import com.caucho.vfs.Encoding; 81 import com.caucho.vfs.Path; 82 import com.caucho.vfs.Vfs; 83 84 import javax.annotation.PostConstruct; 85 import javax.management.ObjectName ; 86 import javax.naming.InitialContext ; 87 import javax.servlet.*; 88 import javax.servlet.http.HttpServletResponse ; 89 import javax.servlet.http.HttpSessionActivationListener ; 90 import javax.servlet.http.HttpSessionAttributeListener ; 91 import javax.servlet.http.HttpSessionListener ; 92 import java.io.File ; 93 import java.util.ArrayList ; 94 import java.util.HashMap ; 95 import java.util.Iterator ; 96 import java.util.Locale ; 97 import java.util.logging.Level ; 98 import java.util.logging.Logger ; 99 100 103 public class WebApp extends ServletContextImpl 104 implements Dependency, EnvironmentBean, SchemaBean, DispatchBuilder, 105 EnvironmentDeployInstance 106 { 107 private static final String DEFAULT_VERSION = "2.4"; 108 109 private static final L10N L = new L10N(WebApp.class); 110 private static final Logger log = Log.open(WebApp.class); 111 112 private static final int JSP_NONE = 0; 113 private static final int JSP_1 = 1; 114 private static final int JSP_2 = 2; 115 116 private static EnvironmentLocal<AbstractAccessLog> _accessLogLocal 117 = new EnvironmentLocal<AbstractAccessLog>("caucho.server.access-log"); 118 119 private static EnvironmentLocal<WebApp> _appLocal 120 = new EnvironmentLocal<WebApp>("caucho.application"); 121 122 static String []_classLoaderHackPackages; 123 124 private ClassLoader _parentClassLoader; 125 126 private EnvironmentClassLoader _classLoader; 128 129 private WebAppContainer _parent; 131 132 private WebAppController _controller; 134 135 private String _contextPath = ""; 137 138 private String _description = ""; 140 141 private String _servletVersion; 142 143 private Path _appDir; 145 private boolean _isAppDirSet; 146 private boolean _isDynamicDeploy; 147 148 private ArrayList <DeployGenerator> _appGenerators 150 = new ArrayList <DeployGenerator>(); 151 152 private ArrayList <WebAppConfig> _webAppDefaultList 154 = new ArrayList <WebAppConfig>(); 155 156 private ServletManager _servletManager; 158 private ServletMapper _servletMapper; 160 private boolean _isStrictMapping; 162 private boolean _servletAllowEL = false; 164 165 private FilterManager _filterManager; 167 private FilterMapper _filterMapper; 169 private FilterMapper _loginFilterMapper; 171 private FilterMapper _includeFilterMapper; 173 private FilterMapper _forwardFilterMapper; 175 private FilterMapper _errorFilterMapper; 177 private boolean _dispatchWrapsFilters; 179 180 private TransactionManagerImpl _tm; 182 183 private SessionManager _sessionManager; 185 private boolean _isInheritSession; 187 188 private AbstractCache _cache; 190 191 private LruCache<String ,FilterChainEntry> _filterChainCache 192 = new LruCache<String ,FilterChainEntry>(256); 193 194 private UrlMap<CacheMapping> _cacheMappingMap = new UrlMap<CacheMapping>(); 195 196 private LruCache<String ,RequestDispatcherImpl> _dispatcherCache; 197 198 private AbstractLogin _loginManager; 200 201 private ConstraintManager _constraintManager; 203 204 private boolean _isSecure; 206 207 private ErrorPageManager _errorPageManager; 209 210 private Throwable _configException; 212 213 private RewriteInvocation _rewriteInvocation; 215 216 private LruCache<String ,String > _realPathCache = 217 new LruCache<String ,String >(1024); 218 private RewriteRealPath _rewriteRealPath; 220 221 private HashMap <String ,String > _mimeMapping = new HashMap <String ,String >(); 223 private HashMap <String ,String > _localeMapping 225 = new HashMap <String ,String >(); 226 227 private ArrayList <Listener> _listeners = new ArrayList <Listener>(); 229 230 private ArrayList <ServletContextListener> _webAppListeners 232 = new ArrayList <ServletContextListener>(); 233 234 private ArrayList <ServletContextAttributeListener> _attributeListeners 236 = new ArrayList <ServletContextAttributeListener>(); 237 238 private ArrayList <ServletRequestListener> _requestListeners 240 = new ArrayList <ServletRequestListener>(); 241 242 private ServletRequestListener []_requestListenerArray 243 = new ServletRequestListener[0]; 244 245 private ArrayList <ServletRequestAttributeListener> _requestAttributeListeners 247 = new ArrayList <ServletRequestAttributeListener>(); 248 249 private ServletRequestAttributeListener []_requestAttributeListenerArray 250 = new ServletRequestAttributeListener[0]; 251 252 private ArrayList <Validator> _resourceValidators 253 = new ArrayList <Validator>(); 254 255 private DependencyContainer _invocationDependency; 256 257 private AbstractAccessLog _accessLog; 258 private Path _tempDir; 259 260 private boolean _cookieHttpOnly; 261 262 private int _jspState; 264 private JspPropertyGroup _jsp; 265 private ArrayList <JspTaglib> _taglibList; 266 private JspApplicationContextImpl _jspApplicationContext; 267 private HashMap <String ,Object > _extensions = new HashMap <String ,Object >(); 268 269 private MultipartForm _multipartForm; 270 271 private ArrayList <String > _regexp; 272 273 private long _shutdownWaitTime = 15000L; 274 private long _activeWaitTime = 15000L; 275 276 private long _idleTime = 2 * 3600 * 1000L; 277 278 private final Object _countLock = new Object (); 279 private final Lifecycle _lifecycle; 280 281 private int _requestCount; 282 private long _lastRequestTime = Alarm.getCurrentTime(); 283 284 287 public WebApp() 288 { 289 this(new WebAppController("/", null, null)); 290 } 291 292 295 WebApp(WebAppController controller) 296 { 297 try { 298 _classLoader = new EnvironmentClassLoader(controller.getParentClassLoader()); 299 300 JspServlet.initStatic(); 302 303 String contextPath = controller.getContextPath(); 304 setContextPathId(contextPath); 305 306 _controller = controller; 307 308 _classLoader.addParentPriorityPackages(_classLoaderHackPackages); 309 310 _appLocal.set(this, _classLoader); 311 312 314 _appDir = controller.getRootDirectory(); 315 316 if (_appDir.equals(CauchoSystem.getResinHome())) 317 log.warning(L.l("web-app root directory should not be the same as resin.home\n{0}", _appDir)); 318 319 _servletManager = new ServletManager(); 320 _servletMapper = new ServletMapper(); 321 _servletMapper.setServletContext(this); 322 _servletMapper.setServletManager(_servletManager); 323 324 _filterManager = new FilterManager(); 325 _filterMapper = new FilterMapper(); 326 _filterMapper.setServletContext(this); 327 _filterMapper.setFilterManager(_filterManager); 328 329 _loginFilterMapper = new FilterMapper(); 330 _loginFilterMapper.setServletContext(this); 331 _loginFilterMapper.setFilterManager(_filterManager); 332 333 _includeFilterMapper = new FilterMapper(); 334 _includeFilterMapper.setServletContext(this); 335 _includeFilterMapper.setFilterManager(_filterManager); 336 337 _forwardFilterMapper = new FilterMapper(); 338 _forwardFilterMapper.setServletContext(this); 339 _forwardFilterMapper.setFilterManager(_filterManager); 340 341 _errorFilterMapper = new FilterMapper(); 342 _errorFilterMapper.setServletContext(this); 343 _errorFilterMapper.setFilterManager(_filterManager); 344 345 _constraintManager = new ConstraintManager(); 346 _errorPageManager = new ErrorPageManager(); 347 _errorPageManager.setWebApp(this); 348 349 setParent(controller.getContainer()); 350 351 _invocationDependency = new DependencyContainer(); 352 _invocationDependency.add(this); 353 354 _jspApplicationContext = new JspApplicationContextImpl(this); 355 } catch (Throwable e) { 356 log.log(Level.WARNING, e.toString(), e); 357 setConfigException(e); 358 } finally { 359 _lifecycle = new Lifecycle(log, toString(), Level.INFO); 360 } 361 } 362 363 366 public void setParent(WebAppContainer parent) 367 { 368 _parent = parent; 369 370 if (parent == null) 371 return; 372 373 if (! _isAppDirSet) { 374 setAppDir(parent.getDocumentDirectory()); 375 Vfs.setPwd(parent.getDocumentDirectory(), _classLoader); 376 _isAppDirSet = false; 377 } 378 379 _errorPageManager.setParent(parent.getErrorPageManager()); 380 } 381 382 385 public void setDynamicDeploy(boolean isDynamicDeploy) 386 { 387 _isDynamicDeploy = isDynamicDeploy; 388 } 389 390 393 public boolean isDynamicDeploy() 394 { 395 return _isDynamicDeploy; 396 } 397 398 401 public WebAppContainer getParent() 402 { 403 return _parent; 404 } 405 406 409 public static WebApp getLocal() 410 { 411 return _appLocal.get(); 412 } 413 414 417 public DispatchServer getDispatchServer() 418 { 419 if (_parent != null) 420 return _parent.getDispatchServer(); 421 else 422 return null; 423 } 424 425 428 public Server getServer() 429 { 430 if (_parent != null && _parent.getDispatchServer() instanceof Server) 431 return (Server) _parent.getDispatchServer(); 432 else 433 return null; 434 } 435 436 439 public void setId(String id) 440 { 441 } 442 443 446 private void setContextPathId(String id) 447 { 448 if (! id.equals("") && ! id.startsWith("/")) 449 id = "/" + id; 450 451 if (id.endsWith("/")) 452 id = id.substring(0, id.length() - 1); 453 454 setContextPath(id); 455 456 if (! _isAppDirSet && _parent != null) { 457 setAppDir(_parent.getDocumentDirectory().lookup("./" + id)); 458 _isAppDirSet = false; 459 } 460 } 461 462 465 public ClassLoader getClassLoader() 466 { 467 return _classLoader; 468 } 469 470 473 public void setEnvironmentClassLoader(EnvironmentClassLoader loader) 474 { 475 throw new IllegalStateException (); 476 } 477 478 481 public EnvironmentClassLoader getEnvironmentClassLoader() 482 { 483 return _classLoader; 484 } 485 486 489 public String getSchema() 490 { 491 return "com/caucho/server/webapp/resin-web-xml.rnc"; 492 } 493 494 497 public void setConfigNode(org.w3c.dom.Node node) 498 { 499 String ns = node.getNamespaceURI(); 500 501 if (ns == null || ns.equals("")) { 502 _jspState = JSP_1; 503 } 504 } 505 506 509 public Path getAppDir() 510 { 511 return _appDir; 512 } 513 514 517 public DependencyContainer getInvocationDependency() 518 { 519 return _invocationDependency; 520 } 521 522 525 public void setRegexp(ArrayList <String > regexp) 526 { 527 _regexp = regexp; 528 } 529 530 533 public ArrayList <String > getRegexp() 534 { 535 return _regexp; 536 } 537 538 541 public void setDocumentDirectory(Path appDir) 542 { 543 setAppDir(appDir); 544 } 545 546 549 public void setRootDirectory(Path appDir) 550 { 551 setAppDir(appDir); 552 } 553 554 557 public void setAppDir(Path appDir) 558 { 559 _appDir = appDir; 560 _isAppDirSet = true; 561 562 WorkDir.setLocalWorkDir(appDir.lookup("WEB-INF/work"), getClassLoader()); 563 564 } 567 568 571 public ObjectName getObjectName() 572 { 573 return _controller.getObjectName(); 574 } 575 576 579 public String getContextPath() 580 { 581 return _contextPath; 582 } 583 584 587 private void setContextPath(String contextPath) 588 { 589 _contextPath = contextPath; 590 591 if (getServletContextName() == null) 592 setDisplayName(contextPath); 593 594 _classLoader.setId("web-app:" + getURL()); 595 } 596 597 600 public void setVersion(String version) 601 { 602 _servletVersion = version; 603 } 604 605 608 public String getVersion() 609 { 610 return _servletVersion; 611 } 612 613 616 public void setSchemaLocation(String location) 617 { 618 } 619 620 623 public String getURL() 624 { 625 if (_parent != null) 626 return _parent.getURL() + _contextPath; 627 else 628 return _contextPath; 629 } 630 631 634 public String getHostName() 635 { 636 if (_parent != null) 637 return _parent.getHostName(); 638 else 639 return null; 640 } 641 642 645 public HostMXBean getHostAdmin() 646 { 647 if (_parent != null && _parent.getHost() != null) 648 return _parent.getHost().getAdmin(); 649 else 650 return null; 651 } 652 653 656 public String getDescription() 657 { 658 return _description; 659 } 660 661 664 public void setDescription(String description) 665 { 666 _description = description; 667 } 668 669 672 public void setIcon(com.caucho.config.types.Icon icon) 673 { 674 } 675 676 679 public void setAllowServletEL(boolean allow) 680 { 681 _servletAllowEL = allow; 682 } 683 684 687 public ServletConfigImpl createServlet() 688 throws ServletException 689 { 690 ServletConfigImpl config = new ServletConfigImpl(); 691 692 config.setAllowEL(_servletAllowEL); 693 694 return config; 695 } 696 697 700 public void addServlet(ServletConfigImpl config) 701 throws ServletException 702 { 703 config.setServletContext(this); 704 705 _servletManager.addServlet(config); 706 } 707 708 711 public void setStrictMapping(boolean isStrict) 712 throws ServletException 713 { 714 _isStrictMapping = isStrict; 715 } 716 717 720 public boolean getStrictMapping() 721 { 722 return _isStrictMapping; 723 } 724 725 728 public void setLazyServletValidate(boolean isLazy) 729 { 730 _servletManager.setLazyValidate(isLazy); 731 } 732 733 736 public void addServletMapping(ServletMapping servletMapping) 737 throws ServletException 738 { 739 741 servletMapping.setServletContext(this); 742 servletMapping.setStrictMapping(getStrictMapping()); 743 servletMapping.init(_servletMapper); 744 } 745 746 749 public WebServiceClient createWebServiceClient() 750 { 751 return new WebServiceClient(); 752 } 753 754 757 public void addServletRegexp(ServletRegexp servletRegexp) 758 throws ServletException, ClassNotFoundException 759 { 760 ServletMapping mapping = new ServletMapping(); 761 762 mapping.addURLRegexp(servletRegexp.getURLRegexp()); 763 mapping.setServletName(servletRegexp.getServletName()); 764 mapping.setServletClass(servletRegexp.getServletClass()); 765 mapping.setServletContext(this); 766 mapping.setInit(new InitProgram(servletRegexp.getBuilderProgram())); 767 mapping.setStrictMapping(getStrictMapping()); 768 mapping.init(_servletMapper); 769 770 } 772 773 776 public void addFilter(FilterConfigImpl config) 777 { 778 config.setServletContext(this); 779 780 _filterManager.addFilter(config); 781 } 782 783 786 public void addFilterMapping(FilterMapping filterMapping) 787 throws ServletException 788 { 789 filterMapping.setServletContext(this); 790 791 if (filterMapping.isRequest()) { 792 _filterMapper.addFilterMapping(filterMapping); 793 _loginFilterMapper.addFilterMapping(filterMapping); 794 } 795 796 if (filterMapping.isInclude()) 797 _includeFilterMapper.addFilterMapping(filterMapping); 798 799 if (filterMapping.isForward()) 800 _forwardFilterMapper.addFilterMapping(filterMapping); 801 802 if (filterMapping.isError()) 803 _errorFilterMapper.addFilterMapping(filterMapping); 804 } 805 806 809 public void setDispatchWrapsFilters(boolean wrap) 810 { 811 _dispatchWrapsFilters = wrap; 812 } 813 814 817 public boolean getDispatchWrapsFilters() 818 { 819 return _dispatchWrapsFilters; 820 } 821 822 825 public void setDirectoryServlet(String className) 826 throws Exception 827 { 828 ServletConfigImpl config = new ServletConfigImpl(); 829 config.setServletName("directory"); 830 if (className.equals("none")) 831 config.setServletClass("com.caucho.servlets.ErrorStatusServlet"); 832 else 833 config.setServletClass(className); 834 835 addServlet(config); 836 } 837 838 841 public void addWelcomeFileList(WelcomeFileList list) 842 { 843 ArrayList <String > fileList = list.getWelcomeFileList(); 844 845 _servletMapper.setWelcomeFileList(fileList); 846 } 847 848 851 public LocaleEncodingMappingList createLocaleEncodingMappingList() 852 { 853 return new LocaleEncodingMappingList(this); 854 } 855 856 859 public void setInheritSession(boolean isInheritSession) 860 { 861 _isInheritSession = isInheritSession; 862 } 863 864 867 public boolean isInheritSession() 868 { 869 return _isInheritSession; 870 } 871 872 875 public SessionManager createSessionConfig() 876 throws Exception 877 { 878 if (_isInheritSession) 879 return new SessionManager(this); 880 881 return getSessionManager(); 882 } 883 884 887 public void addSessionConfig(SessionManager manager) 888 throws ConfigException 889 { 890 if (_isInheritSession) { 891 manager.close(); 892 } 893 } 894 895 898 public void setCookieHttpOnly(boolean isHttpOnly) 899 { 900 _cookieHttpOnly = isHttpOnly; 901 } 902 903 906 public boolean getCookieHttpOnly() 907 { 908 return _cookieHttpOnly; 909 } 910 911 914 public InitParam createContextParam() 915 { 916 InitParam initParam = new InitParam(); 917 918 initParam.setAllowEL(_servletAllowEL); 919 920 return initParam; 921 } 922 923 926 public void addContextParam(InitParam initParam) 927 { 928 HashMap <String ,String > map = initParam.getParameters(); 929 930 Iterator <String > iter = map.keySet().iterator(); 931 while (iter.hasNext()) { 932 String key = iter.next(); 933 String value = map.get(key); 934 935 setInitParameter(key, value); 936 } 937 } 938 939 942 public void addErrorPage(ErrorPage errorPage) 943 { 944 _errorPageManager.addErrorPage(errorPage); 945 } 946 947 950 public AccessLog createAccessLog() 951 { 952 return new AccessLog(); 953 } 954 955 958 public void setAccessLog(AbstractAccessLog log) 959 { 960 _accessLog = log; 961 962 _accessLogLocal.set(log); 963 } 964 965 968 public void addMimeMapping(MimeMapping mimeMapping) 969 { 970 _mimeMapping.put(mimeMapping.getExtension(), 971 mimeMapping.getMimeType()); 972 } 973 974 977 public void putLocaleEncoding(String locale, String encoding) 978 { 979 _localeMapping.put(locale.toLowerCase(), encoding); 980 } 981 982 985 public String getLocaleEncoding(Locale locale) 986 { 987 String encoding; 988 989 String key = locale.toString(); 990 encoding = _localeMapping.get(key.toLowerCase()); 991 992 if (encoding != null) 993 return encoding; 994 995 if (locale.getVariant() != null) { 996 key = locale.getLanguage() + '_' + locale.getCountry(); 997 encoding = _localeMapping.get(key.toLowerCase()); 998 if (encoding != null) 999 return encoding; 1000 } 1001 1002 if (locale.getCountry() != null) { 1003 key = locale.getLanguage(); 1004 encoding = _localeMapping.get(key.toLowerCase()); 1005 if (encoding != null) 1006 return encoding; 1007 } 1008 1009 return Encoding.getMimeName(locale); 1010 } 1011 1012 1015 public RewriteInvocation createRewriteDispatch() 1016 { 1017 if (_rewriteInvocation == null) 1018 _rewriteInvocation = new RewriteInvocation(this); 1019 1020 return _rewriteInvocation; 1021 } 1022 1023 1026 public RewriteRealPath createRewriteRealPath() 1027 { 1028 if (_rewriteRealPath == null) 1029 _rewriteRealPath = new RewriteRealPath(getAppDir()); 1030 1031 return _rewriteRealPath; 1032 } 1033 1034 1037 public void addPathMapping(PathMapping pathMapping) 1038 throws Exception 1039 { 1040 String urlPattern = pathMapping.getUrlPattern(); 1041 String urlRegexp = pathMapping.getUrlRegexp(); 1042 String realPath = pathMapping.getRealPath(); 1043 1044 if (urlPattern != null) 1045 createRewriteRealPath().addPathPattern(urlPattern, realPath); 1046 else if (urlRegexp != null) 1047 createRewriteRealPath().addPathRegexp(urlRegexp, realPath); 1048 else 1049 throw new NullPointerException (); 1050 } 1051 1052 1055 public void setLoginConfig(LoginConfig loginConfig) 1056 throws Throwable 1057 { 1058 _loginManager = loginConfig.getLogin(); 1059 } 1060 1061 1064 public void addSecurityConstraint(SecurityConstraint constraint) 1065 { 1066 _constraintManager.addConstraint(constraint); 1067 } 1068 1069 1072 public void addSecurityRole(SecurityRole role) 1073 { 1074 } 1075 1076 1079 public void setSecure(boolean isSecure) 1080 { 1081 _isSecure = isSecure; 1082 1083 if (isSecure) { 1084 TransportConstraint transConstraint = new TransportConstraint("secure"); 1085 1086 SecurityConstraint constraint = new SecurityConstraint(); 1087 constraint.setURLPattern("/*"); 1088 constraint.addConstraint(transConstraint); 1089 1090 _constraintManager.addConstraint(constraint); 1091 } 1092 } 1093 1094 public void addListener(Listener listener) 1095 throws Exception 1096 { 1097 if (! hasListener(listener.getListenerClass())) { 1098 _listeners.add(listener); 1099 1100 if (_lifecycle.isStarting() || _lifecycle.isActive()) { 1101 addListenerObject(listener.createListenerObject(), true); 1102 } 1103 } 1104 } 1105 1106 1109 public boolean hasListener(Class listenerClass) 1110 { 1111 for (int i = 0; i < _listeners.size(); i++) { 1112 Listener listener = _listeners.get(i); 1113 1114 if (listenerClass.equals(listener.getListenerClass())) 1115 return true; 1116 } 1117 1118 return false; 1119 } 1120 1121 1124 private void addListenerObject(Object listenerObj, boolean start) 1125 { 1126 if (listenerObj instanceof ServletContextListener) { 1127 ServletContextListener scListener = (ServletContextListener) listenerObj; 1128 _webAppListeners.add(scListener); 1129 1130 if (start) { 1131 ServletContextEvent event = new ServletContextEvent(this); 1132 1133 try { 1134 scListener.contextInitialized(event); 1135 } catch (Throwable e) { 1136 log.log(Level.FINE, e.toString(), e); 1137 } 1138 } 1139 } 1140 1141 if (listenerObj instanceof ServletContextAttributeListener) 1142 addAttributeListener((ServletContextAttributeListener) listenerObj); 1143 1144 if (listenerObj instanceof ServletRequestListener) { 1145 _requestListeners.add((ServletRequestListener) listenerObj); 1146 1147 _requestListenerArray = new ServletRequestListener[_requestListeners.size()]; 1148 _requestListeners.toArray(_requestListenerArray); 1149 } 1150 1151 if (listenerObj instanceof ServletRequestAttributeListener) { 1152 _requestAttributeListeners.add((ServletRequestAttributeListener) listenerObj); 1153 1154 _requestAttributeListenerArray = new ServletRequestAttributeListener[_requestAttributeListeners.size()]; 1155 _requestAttributeListeners.toArray(_requestAttributeListenerArray); 1156 } 1157 1158 if (listenerObj instanceof HttpSessionListener ) 1159 getSessionManager().addListener((HttpSessionListener ) listenerObj); 1160 1161 if (listenerObj instanceof HttpSessionAttributeListener ) 1162 getSessionManager().addAttributeListener((HttpSessionAttributeListener ) listenerObj); 1163 1164 if (listenerObj instanceof HttpSessionActivationListener ) 1165 getSessionManager().addActivationListener((HttpSessionActivationListener ) listenerObj); 1166 } 1167 1168 1171 public ServletRequestListener []getRequestListeners() 1172 { 1173 return _requestListenerArray; 1174 } 1175 1176 1179 public ServletRequestAttributeListener []getRequestAttributeListeners() 1180 { 1181 return _requestAttributeListenerArray; 1182 } 1183 1184 1187 public void addResourceRef(ResourceRef ref) 1188 { 1189 _resourceValidators.add(ref); 1190 } 1191 1192 1194 1197 public MultipartForm createMultipartForm() 1198 { 1199 if (_multipartForm == null) 1200 _multipartForm = new MultipartForm(); 1201 1202 return _multipartForm; 1203 } 1204 1205 1208 public boolean doMultipartForm() 1209 { 1210 return _multipartForm != null && _multipartForm.isEnable(); 1211 } 1212 1213 1216 public long getFormUploadMax() 1217 { 1218 if (_multipartForm != null) 1219 return _multipartForm.getUploadMax(); 1220 else 1221 return -1; 1222 } 1223 1224 1227 public AbstractAccessLog getAccessLog() 1228 { 1229 return _accessLog; 1230 } 1231 1232 1235 public void setTempDir(Path path) 1236 { 1237 _tempDir = path; 1238 } 1239 1240 1243 public JspPropertyGroup createJsp() 1244 { 1245 if (_jsp == null) { 1246 _jsp = new JspPropertyGroup(); 1247 } 1248 1249 return _jsp; 1250 } 1251 1252 1255 public JspPropertyGroup getJsp() 1256 { 1257 return _jsp; 1258 } 1259 1260 1263 public JspApplicationContextImpl getJspApplicationContext() 1264 { 1265 return _jspApplicationContext; 1266 } 1267 1268 1271 public boolean has23Config() 1272 { 1273 return _jspState == JSP_1; 1274 } 1275 1276 1279 public void addTaglib(JspTaglib taglib) 1280 { 1281 if (_taglibList == null) { 1282 _taglibList = new ArrayList <JspTaglib>(); 1283 } 1284 1285 _taglibList.add(taglib); 1286 } 1287 1288 1291 public ArrayList <JspTaglib> getTaglibList() 1292 { 1293 return _taglibList; 1294 } 1295 1296 public JspConfig createJspConfig() 1297 { 1298 return new JspConfig(this); 1299 } 1300 1301 1304 public void addJspConfig(JspConfig config) 1305 { 1306 _extensions.put("jsp-config", config); 1307 } 1308 1309 1312 public Object getExtension(String key) 1313 { 1314 return _extensions.get(key); 1315 } 1316 1317 1320 public WebAppExpandDeployGenerator createWebAppDeploy() 1321 { 1322 return _parent.createWebAppDeploy(); 1323 } 1324 1325 1328 public void addWebAppDeploy(WebAppExpandDeployGenerator deploy) 1329 throws Exception 1330 { 1331 String contextPath = getContextPath(); 1332 String prefix = deploy.getURLPrefix(); 1333 1334 deploy.setURLPrefix(contextPath + prefix); 1335 deploy.setParent(_controller); 1336 1337 1339 deploy.setParentClassLoader(getClassLoader()); 1340 1345 for (WebAppConfig configDefault : _webAppDefaultList) 1346 deploy.addWebAppDefault(configDefault); 1347 1348 Environment.addEnvironmentListener(deploy, getClassLoader()); 1349 1350 _appGenerators.add(deploy); 1351 } 1352 1353 1356 public void addWebAppDefault(WebAppConfig config) 1357 { 1358 _webAppDefaultList.add(config); 1359 } 1360 1361 1364 public ArrayList <WebAppConfig> getWebAppDefaultList() 1365 { 1366 return _webAppDefaultList; 1367 } 1368 1369 1372 public void addWebApp(WebAppConfig config) 1373 throws Exception 1374 { 1375 String contextPath = getContextPath(); 1376 String prefix = config.getId(); 1377 1378 if (prefix == null || prefix.equals("") || prefix.equals("/")) 1379 throw new ConfigException(L.l("'{0}' is an illegal sub web-app id.", 1380 prefix)); 1381 1382 WebAppContainer container = _parent; 1383 DeployContainer<WebAppController> appGenerator; 1384 appGenerator = _parent.getWebAppGenerator(); 1385 1386 WebAppSingleDeployGenerator deploy; 1387 deploy = new WebAppSingleDeployGenerator(appGenerator, 1388 container, config); 1389 1390 deploy.setURLPrefix(contextPath + prefix); 1391 1393 1396 deploy.setParentWebApp(_controller); 1397 deploy.setParentClassLoader(getClassLoader()); 1398 deploy.setContainer(container); 1399 1400 for (WebAppConfig configDefault : _webAppDefaultList) 1401 deploy.addWebAppDefault(configDefault); 1402 1403 String appDir = config.getDocumentDirectory(); 1404 1405 if (appDir == null) 1406 appDir = "./" + prefix; 1407 1408 Path root = PathBuilder.lookupPath(appDir, null, getAppDir()); 1409 1410 deploy.setRootDirectory(root); 1411 1412 deploy.init(); 1413 1414 _parent.addDeploy(deploy); 1415 1416 1418 } 1420 1421 1424 public void setConfigException(Throwable e) 1425 { 1426 if (_configException == null) 1427 _configException = e; 1428 1429 if (e != null) { 1434 _classLoader.addDependency(AlwaysModified.create()); 1435 } 1436 } 1437 1438 1441 public Throwable getConfigException() 1442 { 1443 return _configException; 1444 } 1445 1446 1449 public Cluster getCluster() 1450 { 1451 return Cluster.getCluster(getClassLoader()); 1452 } 1453 1454 1457 public boolean isIgnoreClientDisconnect() 1458 { 1459 DispatchServer server = getDispatchServer(); 1460 1461 if (server == null) 1462 return true; 1463 else 1464 return server.isIgnoreClientDisconnect(); 1465 } 1466 1467 1470 public void setShutdownWaitMax(Period wait) 1471 { 1472 _shutdownWaitTime = wait.getPeriod(); 1473 1474 Resin resin = Resin.getLocal(); 1475 if (resin != null && 1476 resin.getShutdownWaitMax() < _shutdownWaitTime) { 1477 log.warning(L.l("web-app shutdown-wait-max '{0}' is longer than resin shutdown-wait-max '{1}'.", 1478 _shutdownWaitTime, 1479 resin.getShutdownWaitMax())); 1480 } 1481 } 1482 1483 1486 public void setActiveWaitTime(Period wait) 1487 { 1488 _activeWaitTime = wait.getPeriod(); 1489 } 1490 1491 1494 public void setIdleTime(Period idle) 1495 { 1496 _idleTime = idle.getPeriod(); 1497 } 1498 1499 1502 public void addConfigFile(Path path) 1503 throws Exception 1504 { 1505 com.caucho.config.core.ResinImport rImport; 1506 rImport = new com.caucho.config.core.ResinImport(); 1507 rImport.setPath(path); 1508 rImport.setOptional(true); 1509 rImport.setParent(this); 1510 rImport.init(); 1511 1512 log.config("<config-file> is deprecated. Please use resin:import."); 1513 } 1514 1515 1518 public String getState() 1519 { 1520 return _lifecycle.getStateName(); 1521 } 1522 1523 1526 public boolean isInit() 1527 { 1528 return _lifecycle.isInit() || _configException != null; 1529 } 1530 1531 1534 public boolean isInitializing() 1535 { 1536 return _lifecycle.isBeforeActive(); 1537 } 1538 1539 1542 public boolean isActive() 1543 { 1544 return _lifecycle.isActive(); 1545 } 1546 1547 1550 public boolean isClosed() 1551 { 1552 return _lifecycle.isDestroyed(); 1553 } 1554 1555 1558 @PostConstruct 1559 public void init() 1560 throws Exception 1561 { 1562 if (! _lifecycle.toInitializing()) 1563 return; 1564 1565 try { 1566 _classLoader.setId("web-app:" + getURL()); 1567 1568 _invocationDependency.setCheckInterval(getEnvironmentClassLoader().getDependencyCheckInterval()); 1569 1570 if (_tempDir == null) 1571 _tempDir = (Path) Environment.getLevelAttribute("caucho.temp-dir"); 1572 1573 if (_tempDir == null) 1574 _tempDir = getAppDir().lookup("WEB-INF/tmp"); 1575 1576 _tempDir.mkdirs(); 1577 setAttribute("javax.servlet.context.tempdir", new File (_tempDir.getNativePath())); 1578 1579 FilterChainBuilder securityBuilder = _constraintManager.getFilterBuilder(); 1580 1581 if (securityBuilder != null) 1582 _filterMapper.addTopFilter(securityBuilder); 1583 1584 _cache = (AbstractCache) Environment.getAttribute("caucho.server.cache"); 1585 1586 for (int i = 0; i < _appGenerators.size(); i++) 1587 _parent.addDeploy(_appGenerators.get(i)); 1588 1589 _classLoader.setId("web-app:" + getURL()); 1590 1591 try { 1592 InitialContext ic = new InitialContext (); 1593 ServletAuthenticator auth; 1594 auth = (ServletAuthenticator) ic.lookup("java:comp/env/caucho/auth"); 1595 1596 setAttribute("caucho.authenticator", auth); 1597 } catch (Exception e) { 1598 log.finest(e.toString()); 1599 } 1600 1601 WebAppController parent = null; 1602 if (_controller != null) 1603 parent = _controller.getParent(); 1604 if (_isInheritSession && parent != null && 1605 _sessionManager != parent.getWebApp().getSessionManager()) { 1606 SessionManager sessionManager = _sessionManager; 1607 _sessionManager = parent.getWebApp().getSessionManager(); 1608 1609 if (sessionManager != null) 1610 sessionManager.close(); 1611 } 1612 1613 if (getSessionManager() != null) 1614 getSessionManager().init(); 1615 1616 for (int i = 0; i < _resourceValidators.size(); i++) { 1617 Validator validator = _resourceValidators.get(i); 1618 1619 validator.validate(); 1620 } 1621 } finally { 1622 _lifecycle.toInit(); 1623 } 1624 } 1625 1626 public WebAppAdmin getAdmin() 1627 { 1628 return _controller.getAdmin(); 1629 } 1630 1631 public void start() 1632 { 1633 if (! _lifecycle.isAfterInit()) 1634 throw new IllegalStateException (L.l("webApp must be initialized before starting. Currently in state {0}.", _lifecycle.getStateName())); 1635 1636 Thread thread = Thread.currentThread(); 1637 ClassLoader oldLoader = thread.getContextClassLoader(); 1638 boolean isOkay = true; 1639 1640 try { 1641 thread.setContextClassLoader(_classLoader); 1642 1643 if (! _lifecycle.toStarting()) 1644 return; 1645 1646 isOkay = false; 1647 1648 if (_accessLog == null) 1649 _accessLog = _accessLogLocal.get(); 1650 1651 long interval = _classLoader.getDependencyCheckInterval(); 1652 _invocationDependency.setCheckInterval(interval); 1653 1654 if (_parent != null) 1655 _invocationDependency.add(_parent.getWebAppGenerator()); 1656 1657 _invocationDependency.clearModified(); 1659 _classLoader.clearModified(); 1660 1661 String serverId = (String ) new EnvironmentLocal("caucho.server-id").get(); 1662 if (serverId != null) 1663 setAttribute("caucho.server-id", serverId); 1664 1665 _classLoader.start(); 1666 1667 if (_configException == null) 1670 _configException = Environment.getConfigException(); 1671 1672 try { 1673 getSessionManager().start(); 1674 } catch (Throwable e) { 1675 log.log(Level.WARNING, e.toString(), e); 1676 } 1677 1678 ServletContextEvent event = new ServletContextEvent(this); 1679 1680 for (Listener listener : _listeners) { 1681 try { 1682 addListenerObject(listener.createListenerObject(), false); 1683 } catch (Exception e) { 1684 throw new ConfigException(e); 1685 } 1686 } 1687 1688 for (int i = 0; i < _webAppListeners.size(); i++) { 1689 ServletContextListener listener = _webAppListeners.get(i); 1690 1691 try { 1692 listener.contextInitialized(event); 1693 } catch (Throwable e) { 1694 log.log(Level.WARNING, e.toString(), e); 1695 } 1696 } 1697 1698 try { 1699 _servletManager.init(); 1700 _filterManager.init(); 1701 } catch (Throwable e) { 1702 log.log(Level.WARNING, e.toString(), e); 1703 setConfigException(e); 1704 } 1705 1706 _lifecycle.toActive(); 1707 1708 if (_parent instanceof Host) { 1709 Host host = (Host) _parent; 1710 1711 host.setConfigETag(null); 1712 } 1713 1714 if (_parent != null) 1715 _parent.clearCache(); 1716 1717 isOkay = true; 1718 } finally { 1719 if (! isOkay) 1720 _lifecycle.toError(); 1721 1722 thread.setContextClassLoader(oldLoader); 1723 } 1724 } 1725 1726 1729 public boolean isModified() 1730 { 1731 1733 if (_lifecycle.isAfterActive()) 1736 return true; 1737 else if (_classLoader.isModified()) 1738 return true; 1739 else 1740 return false; 1741 } 1742 1743 1746 public boolean isModifiedNow() 1747 { 1748 _classLoader.isModifiedNow(); 1750 _invocationDependency.isModifiedNow(); 1751 1752 return isModified(); 1753 } 1754 1755 1758 public boolean isDeployError() 1759 { 1760 return _configException != null; 1761 } 1762 1763 1766 public boolean isDeployIdle() 1767 { 1768 if (_idleTime < 0) 1769 return false; 1770 else 1771 return _lastRequestTime + _idleTime < Alarm.getCurrentTime(); 1772 } 1773 1774 1777 public ServletContext getContext(String uri) 1778 { 1779 if (uri == null) 1780 throw new IllegalArgumentException (L.l("getContext URI must not be null.")); 1781 else if (uri.startsWith("/")) { 1782 } 1783 1784 else if (uri.equals("")) 1785 uri = "/"; 1786 1787 else 1788 throw new IllegalArgumentException (L.l("getContext URI `{0}' must be absolute.", uri)); 1789 1790 try { 1791 if (_parent != null) 1792 return _parent.findSubWebAppByURI(uri); 1793 else 1794 return this; 1795 } catch (Exception e) { 1796 log.log(Level.WARNING, e.toString(), e); 1797 1798 return null; 1799 } 1800 } 1801 1802 1805 public String getServletPattern(String uri) 1806 { 1807 return _servletMapper.getServletPattern(uri); 1808 } 1809 1810 1813 public ArrayList <String > getServletMappingPatterns() 1814 { 1815 return _servletMapper.getURLPatterns(); 1816 } 1817 1818 1821 public ArrayList <String > getServletIgnoreMappingPatterns() 1822 { 1823 return _servletMapper.getIgnorePatterns(); 1824 } 1825 1826 1829 public void buildInvocation(Invocation invocation) 1830 { 1831 Thread thread = Thread.currentThread(); 1832 ClassLoader oldLoader = thread.getContextClassLoader(); 1833 1834 thread.setContextClassLoader(getClassLoader()); 1835 try { 1836 FilterChain chain = null; 1837 1838 if (_configException != null) { 1839 chain = new ExceptionFilterChain(_configException); 1840 invocation.setFilterChain(chain); 1841 invocation.setDependency(AlwaysModified.create()); 1842 return; 1843 } 1844 else if (! _lifecycle.waitForActive(_activeWaitTime)) { 1845 int code = HttpServletResponse.SC_SERVICE_UNAVAILABLE; 1846 chain = new ErrorFilterChain(code); 1847 invocation.setFilterChain(chain); 1848 invocation.setDependency(AlwaysModified.create()); 1849 return; 1850 } 1851 else { 1852 FilterChainEntry entry = null; 1853 1854 String query = invocation.getQueryString(); 1856 1857 boolean isPrecompile = false; 1858 if (query != null && query.indexOf("jsp_precompile") >= 0) 1859 isPrecompile = true; 1860 1861 if (! isPrecompile) 1862 entry = _filterChainCache.get(invocation.getContextURI()); 1863 1864 if (entry != null && ! entry.isModified()) { 1865 chain = entry.getFilterChain(); 1866 } else { 1867 if (_rewriteInvocation != null) { 1868 chain = _rewriteInvocation.map(invocation.getContextURI(), 1869 invocation); 1870 } 1871 1872 if (chain == null) 1873 chain = _servletMapper.mapServlet(invocation); 1874 1875 _filterMapper.buildDispatchChain(invocation, chain); 1877 1878 chain = invocation.getFilterChain(); 1879 1880 entry = new FilterChainEntry(chain, invocation); 1881 chain = entry.getFilterChain(); 1882 1883 if (! isPrecompile) 1884 _filterChainCache.put(invocation.getContextURI(), entry); 1885 } 1886 1887 1891 if (_cache != null) 1893 chain = _cache.createFilterChain(chain, this); 1894 1895 if (CauchoSystem.isDetailedStatistics()) 1896 chain = new StatisticsFilterChain(chain, this); 1897 1898 WebAppFilterChain webAppChain = new WebAppFilterChain(chain, this); 1899 1900 webAppChain.setSecurityRoleMap(invocation.getSecurityRoleMap()); 1901 1902 invocation.setFilterChain(webAppChain); 1903 invocation.setPathInfo(entry.getPathInfo()); 1904 invocation.setServletPath(entry.getServletPath()); 1905 } 1906 } catch (Throwable e) { 1907 FilterChain chain = new ExceptionFilterChain(e); 1908 chain = new WebAppFilterChain(chain, this); 1909 invocation.setDependency(AlwaysModified.create()); 1910 invocation.setFilterChain(chain); 1911 } finally { 1912 thread.setContextClassLoader(oldLoader); 1913 } 1914 } 1915 1916 1919 public void buildIncludeInvocation(Invocation invocation) 1920 throws ServletException 1921 { 1922 buildDispatchInvocation(invocation, _includeFilterMapper); 1923 } 1924 1925 1928 public void buildForwardInvocation(Invocation invocation) 1929 throws ServletException 1930 { 1931 buildDispatchInvocation(invocation, _forwardFilterMapper); 1932 } 1933 1934 1937 public void buildErrorInvocation(Invocation invocation) 1938 throws ServletException 1939 { 1940 buildDispatchInvocation(invocation, _errorFilterMapper); 1941 } 1942 1943 1946 public void buildLoginInvocation(Invocation invocation) 1947 throws ServletException 1948 { 1949 buildDispatchInvocation(invocation, _loginFilterMapper); 1950 } 1951 1952 1955 public void buildDispatchInvocation(Invocation invocation, 1956 FilterMapper filterMapper) 1957 throws ServletException 1958 { 1959 invocation.setWebApp(this); 1960 1961 Thread thread = Thread.currentThread(); 1962 ClassLoader oldLoader = thread.getContextClassLoader(); 1963 1964 thread.setContextClassLoader(getClassLoader()); 1965 try { 1966 FilterChain chain; 1967 1968 1977 if (_configException != null) { 1978 chain = new ExceptionFilterChain(_configException); 1979 invocation.setDependency(AlwaysModified.create()); 1980 } 1981 else if (! _lifecycle.waitForActive(_activeWaitTime)) { 1982 Exception exn = new UnavailableException(L.l("'{0}' is not currently available.", 1983 getContextPath())); 1984 chain = new ExceptionFilterChain(exn); 1985 invocation.setDependency(AlwaysModified.create()); 1986 } 1987 else { 1988 chain = _servletMapper.mapServlet(invocation); 1989 1990 filterMapper.buildDispatchChain(invocation, chain); 1991 1992 chain = invocation.getFilterChain(); 1993 1994 chain = new DispatchFilterChain(chain, this); 1995 1996 if (_cache != null && filterMapper == _includeFilterMapper) { 1997 chain = _cache.createFilterChain(chain, this); 1998 } 1999 } 2000 2001 invocation.setFilterChain(chain); 2002 } finally { 2003 thread.setContextClassLoader(oldLoader); 2004 } 2005 } 2006 2007 2010 public RequestDispatcher getRequestDispatcher(String url) 2011 { 2012 if (url == null) 2013 throw new IllegalArgumentException (L.l("request dispatcher url can't be null.")); 2014 else if (! url.startsWith("/")) 2015 throw new IllegalArgumentException (L.l("request dispatcher url `{0}' must be absolute", url)); 2016 2017 RequestDispatcherImpl disp = getDispatcherCache().get(url); 2018 2019 if (disp != null && ! disp.isModified()) 2020 return disp; 2021 2022 Invocation includeInvocation = new SubInvocation(); 2023 Invocation forwardInvocation = new SubInvocation(); 2024 Invocation errorInvocation = new SubInvocation(); 2025 InvocationDecoder decoder = new InvocationDecoder(); 2026 2027 String rawURI = escapeURL(_contextPath + url); 2028 2029 try { 2030 decoder.splitQuery(includeInvocation, rawURI); 2031 decoder.splitQuery(forwardInvocation, rawURI); 2032 decoder.splitQuery(errorInvocation, rawURI); 2033 2034 if (_parent != null) { 2035 _parent.buildIncludeInvocation(includeInvocation); 2036 _parent.buildForwardInvocation(forwardInvocation); 2037 _parent.buildErrorInvocation(errorInvocation); 2038 } 2039 else { 2040 FilterChain chain = _servletMapper.mapServlet(includeInvocation); 2041 _includeFilterMapper.buildDispatchChain(includeInvocation, chain); 2042 includeInvocation.setWebApp(this); 2043 2044 chain = _servletMapper.mapServlet(forwardInvocation); 2045 _forwardFilterMapper.buildDispatchChain(forwardInvocation, chain); 2046 forwardInvocation.setWebApp(this); 2047 2048 chain = _servletMapper.mapServlet(errorInvocation); 2049 _errorFilterMapper.buildDispatchChain(errorInvocation, chain); 2050 errorInvocation.setWebApp(this); 2051 } 2052 2053 disp = new RequestDispatcherImpl(includeInvocation, 2054 forwardInvocation, 2055 errorInvocation, 2056 this); 2057 2058 getDispatcherCache().put(url, disp); 2059 2060 return disp; 2061 } catch (Exception e) { 2062 log.log(Level.FINE, e.toString(), e); 2063 2064 return null; 2065 } 2066 } 2067 2068 private LruCache<String ,RequestDispatcherImpl> getDispatcherCache() 2069 { 2070 LruCache<String ,RequestDispatcherImpl> cache = _dispatcherCache; 2071 2072 if (cache != null) 2073 return cache; 2074 2075 synchronized (this) { 2076 cache = new LruCache<String ,RequestDispatcherImpl>(1024); 2077 _dispatcherCache = cache; 2078 return cache; 2079 } 2080 } 2081 2082 private String escapeURL(String url) 2083 { 2084 return url; 2085 2086 2108 } 2109 2110 2113 public RequestDispatcher getLoginDispatcher(String url) 2114 { 2115 if (url == null) 2116 throw new IllegalArgumentException (L.l("request dispatcher url can't be null.")); 2117 else if (! url.startsWith("/")) 2118 throw new IllegalArgumentException (L.l("request dispatcher url `{0}' must be absolute", url)); 2119 2120 Invocation loginInvocation = new Invocation(); 2121 Invocation errorInvocation = new Invocation(); 2122 InvocationDecoder decoder = new InvocationDecoder(); 2123 2124 String rawURI = _contextPath + url; 2125 2126 try { 2127 decoder.splitQuery(loginInvocation, rawURI); 2128 decoder.splitQuery(errorInvocation, rawURI); 2129 2130 if (_parent != null) { 2131 _parent.buildInvocation(loginInvocation); 2132 _parent.buildErrorInvocation(errorInvocation); 2133 } 2134 else { 2135 FilterChain chain = _servletMapper.mapServlet(loginInvocation); 2136 _filterMapper.buildDispatchChain(loginInvocation, chain); 2137 2138 chain = _servletMapper.mapServlet(errorInvocation); 2139 _errorFilterMapper.buildDispatchChain(errorInvocation, chain); 2140 } 2141 2142 RequestDispatcherImpl disp; 2143 disp = new RequestDispatcherImpl(loginInvocation, 2144 loginInvocation, 2145 errorInvocation, 2146 this); 2147 disp.setLogin(true); 2148 2149 return disp; 2150 } catch (Exception e) { 2151 log.log(Level.FINE, e.toString(), e); 2152 2153 return null; 2154 } 2155 } 2156 2157 2160 public RequestDispatcher getNamedDispatcher(String servletName) 2161 { 2162 FilterChain chain; 2163 2164 try { 2165 chain = _servletManager.createServletChain(servletName); 2166 } catch (Exception e) { 2167 log.log(Level.FINEST, e.toString(), e); 2168 2169 return null; 2170 } 2171 2172 return new NamedDispatcherImpl(chain, null, this); 2173 } 2174 2175 2178 public String getRealPath(String uri) 2179 { 2180 String realPath = _realPathCache.get(uri); 2181 2182 if (realPath != null) 2183 return realPath; 2184 2185 String fullURI = getContextPath() + "/" + uri; 2186 2187 try { 2188 fullURI = InvocationDecoder.normalizeUri(fullURI); 2189 } catch (Exception e) { 2190 log.log(Level.WARNING, e.toString(), e); 2191 } 2192 2193 WebApp app = (WebApp) getContext(fullURI); 2194 2195 if (app == null) 2196 return null; 2197 2198 String cp = app.getContextPath(); 2199 String tail = fullURI.substring(cp.length()); 2200 2201 realPath = app.getRealPathImpl(tail); 2202 2203 if (log.isLoggable(Level.FINEST)) 2204 log.finest("real-path " + uri + " -> " + realPath); 2205 2206 _realPathCache.put(uri, realPath); 2207 2208 return realPath; 2209 } 2210 2211 2214 public String getRealPathImpl(String uri) 2215 { 2216 return createRewriteRealPath().mapToRealPath(uri); 2217 } 2218 2219 2222 public String getMimeType(String uri) 2223 { 2224 if (uri == null) 2225 return null; 2226 2227 String fullURI = getContextPath() + "/" + uri; 2228 2229 try { 2230 fullURI = InvocationDecoder.normalizeUri(fullURI); 2231 } catch (Exception e) { 2232 log.log(Level.WARNING, e.toString(), e); 2233 } 2234 2235 WebApp app = (WebApp) getContext(fullURI); 2236 2237 if (app == null) 2238 return null; 2239 2240 int p = uri.lastIndexOf('.'); 2241 2242 if (p < 0) 2243 return null; 2244 else 2245 return app.getMimeTypeImpl(uri.substring(p)); 2246 } 2247 2248 2251 public String getMimeTypeImpl(String ext) 2252 { 2253 return _mimeMapping.get(ext); 2254 } 2255 2256 2262 public void log(String message, Throwable e) 2263 { 2264 if (e != null) 2265 log.log(Level.WARNING, message, e); 2266 else 2267 log.info(message); 2268 } 2269 2270 2273 public AbstractLogin getLogin() 2274 { 2275 return _loginManager; 2276 } 2277 2278 2281 public ServletAuthenticator getAuthenticator() 2282 { 2283 AbstractLogin login = getLogin(); 2284 2285 if (login != null) 2286 return login.getAuthenticator(); 2287 else 2288 return null; 2289 } 2290 2291 2294 public SessionManager getSessionManager() 2295 { 2296 if (_sessionManager == null) { 2297 if (_lifecycle.isStopped()) 2298 throw new IllegalStateException (L.l("Resin is shutting down.")); 2299 2300 if (_isInheritSession && _parent != null) 2301 _sessionManager = _parent.getSessionManager(); 2302 2303 if (_sessionManager == null) { 2304 Thread thread = Thread.currentThread(); 2305 ClassLoader oldLoader = thread.getContextClassLoader(); 2306 2307 try { 2308 thread.setContextClassLoader(getClassLoader()); 2309 2310 _sessionManager = new SessionManager(this); 2311 } catch (Throwable e) { 2312 log.log(Level.WARNING, e.toString(), e); 2313 } finally { 2314 thread.setContextClassLoader(oldLoader); 2315 } 2316 } 2317 } 2318 2319 return _sessionManager; 2320 } 2321 2322 2325 public ErrorPageManager getErrorPageManager() 2326 { 2327 return _errorPageManager; 2328 } 2329 2330 2333 final boolean enterWebApp() 2334 { 2335 synchronized (_countLock) { 2336 _requestCount++; 2337 _lastRequestTime = Alarm.getCurrentTime(); 2338 } 2339 2340 return _lifecycle.isActive(); 2341 } 2342 2343 2346 final void exitWebApp() 2347 { 2348 synchronized (_countLock) { 2349 _requestCount--; 2350 } 2351 } 2352 2353 2356 public int getRequestCount() 2357 { 2358 return _requestCount; 2359 } 2360 2361 2364 public void addCacheMapping(CacheMapping mapping) 2365 throws Exception 2366 { 2367 if (mapping.getUrlRegexp() != null) 2368 _cacheMappingMap.addRegexp(mapping.getUrlRegexp(), mapping); 2369 else 2370 _cacheMappingMap.addMap(mapping.getUrlPattern(), mapping); 2371 } 2372 2373 2376 public long getMaxAge(String uri) 2377 { 2378 CacheMapping map = (CacheMapping) _cacheMappingMap.map(uri); 2379 2380 if (map != null) 2381 return map.getMaxAge(); 2382 else 2383 return Long.MIN_VALUE; 2384 } 2385 2386 2389 public long getSMaxAge(String uri) 2390 { 2391 CacheMapping map = (CacheMapping) _cacheMappingMap.map(uri); 2392 2393 if (map != null) 2394 return map.getSMaxAge(); 2395 else 2396 return Long.MIN_VALUE; 2397 } 2398 2399 2402 public long getCacheMaxLength() 2403 { 2404 return _cache.getMaxEntrySize(); 2405 } 2406 2407 2410 public String []getClassLoaderHackPackages() 2411 { 2412 return _classLoaderHackPackages; 2413 } 2414 2415 2418 public int getActiveSessionCount() 2419 { 2420 SessionManager manager = getSessionManager(); 2421 2422 if (manager != null) 2423 return manager.getActiveSessionCount(); 2424 else 2425 return 0; 2426 } 2427 2428 void updateStatistics(long time, 2429 int readBytes, 2430 int writeBytes, 2431 boolean isClientDisconnect) 2432 { 2433 _controller.updateStatistics(time, readBytes, writeBytes, isClientDisconnect); 2434 } 2435 2436 2439 public void stop() 2440 { 2441 Thread thread = Thread.currentThread(); 2442 ClassLoader oldLoader = thread.getContextClassLoader(); 2443 2444 try { 2445 thread.setContextClassLoader(getClassLoader()); 2446 2447 if (! _lifecycle.toStopping()) 2448 return; 2449 2450 long beginStop = Alarm.getCurrentTime(); 2451 2452 while (_requestCount > 0 && 2453 Alarm.getCurrentTime() < beginStop + _shutdownWaitTime && 2454 ! Alarm.isTest()) { 2455 try { 2456 Thread.interrupted(); 2457 Thread.sleep(100); 2458 } catch (Throwable e) { 2459 } 2460 } 2461 2462 if (_requestCount > 0) { 2463 log.warning(L.l("{0} closing with {1} active requests.", 2464 toString(), _requestCount)); 2465 } 2466 2467 ServletContextEvent event = new ServletContextEvent(this); 2468 2469 SessionManager sessionManager = _sessionManager; 2470 _sessionManager = null; 2471 2472 if (sessionManager != null && 2473 (! _isInheritSession || _controller.getParent() == null)) 2474 sessionManager.close(); 2475 2476 _servletManager.destroy(); 2477 _filterManager.destroy(); 2478 2479 for (int i = _webAppListeners.size() - 1; i >= 0; i--) { 2481 ServletContextListener listener = _webAppListeners.get(i); 2482 2483 try { 2484 listener.contextDestroyed(event); 2485 } catch (Exception e) { 2486 log.log(Level.WARNING, e.toString(), e); 2487 } 2488 } 2489 2490 try { 2491 _classLoader.stop(); 2492 } catch (Throwable e) { 2493 log.log(Level.WARNING, e.toString(), e); 2494 } 2495 } finally { 2496 thread.setContextClassLoader(oldLoader); 2497 2498 _lifecycle.toStop(); 2499 } 2500 } 2501 2502 2505 public void destroy() 2506 { 2507 stop(); 2508 2509 if (! _lifecycle.toDestroy()) 2510 return; 2511 2512 if (_parent != null) 2513 _parent.clearCache(); 2514 2515 Thread thread = Thread.currentThread(); 2516 ClassLoader oldLoader = thread.getContextClassLoader(); 2517 2518 try { 2519 thread.setContextClassLoader(getClassLoader()); 2520 2521 for (int i = _appGenerators.size() - 1; i >= 0; i--) { 2522 try { 2523 DeployGenerator deploy = _appGenerators.get(i); 2524 _parent.removeWebAppDeploy(deploy); 2525 deploy.destroy(); 2526 } catch (Throwable e) { 2527 log.log(Level.WARNING, e.toString(), e); 2528 } 2529 } 2530 2531 if (_accessLog != null) { 2532 _accessLog.flush(); 2533 } 2534 } finally { 2535 thread.setContextClassLoader(oldLoader); 2536 2537 _classLoader.destroy(); 2538 } 2539 } 2540 2541 public String toString() 2542 { 2543 return "WebApp[" + getURL() + "]"; 2544 } 2545 2546 2547 static class FilterChainEntry { 2548 FilterChain _filterChain; 2549 String _pathInfo; 2550 String _servletPath; 2551 HashMap <String ,String > _securityRoleMap; 2552 final Dependency _dependency; 2553 2554 FilterChainEntry(FilterChain filterChain, Invocation invocation) 2555 { 2556 _filterChain = filterChain; 2557 _pathInfo = invocation.getPathInfo(); 2558 _servletPath = invocation.getServletPath(); 2559 _dependency = invocation.getDependency(); 2560 } 2561 2562 boolean isModified() 2563 { 2564 return _dependency != null && _dependency.isModified(); 2565 } 2566 2567 FilterChain getFilterChain() 2568 { 2569 return _filterChain; 2570 } 2571 2572 HashMap <String ,String > getSecurityRoleMap() 2573 { 2574 return _securityRoleMap; 2575 } 2576 2577 void setSecurityRoleMap(HashMap <String ,String > roleMap) 2578 { 2579 _securityRoleMap = roleMap; 2580 } 2581 2582 String getPathInfo() 2583 { 2584 return _pathInfo; 2585 } 2586 2587 String getServletPath() 2588 { 2589 return _servletPath; 2590 } 2591 } 2592 2593 static { 2594 _classLoaderHackPackages = new String [] { 2595 "java.", 2596 "javax.servlet.", 2597 "javax.naming.", 2598 "javax.sql.", 2599 "javax.transaction.", 2600 }; 2601 } 2602} 2603 | Popular Tags |