/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/ package org.apache.catalina.core;
/** * Standard implementation of the <b>Context</b> interface. Each child container must be a Wrapper implementation to * process the requests directed to a particular servlet. * * @author Craig R. McClanahan * @author Remy Maucherat
*/ publicclass StandardContext extends ContainerBase implements Context, NotificationEmitter {
/** * Create a new StandardContext component with the default basic Valve.
*/ public StandardContext() {
super();
pipeline.setBasic(new StandardContextValve());
broadcaster = new NotificationBroadcasterSupport(); // Set defaults if (!Globals.STRICT_SERVLET_COMPLIANCE) { // Strict servlet compliance requires all extension mapped servlets // to be checked against welcome files
resourceOnlyServlets.add("jsp");
}
}
/** * Allow multipart/form-data requests to be parsed even when the target servlet doesn't specify @MultipartConfig or * have a <multipart-config> element.
*/ protectedboolean allowCasualMultipartParsing = false;
/** * Control whether remaining request data will be read (swallowed) even if the request violates a data size * constraint.
*/ privateboolean swallowAbortedUploads = true;
/** * The antiResourceLocking flag for this Context.
*/ privateboolean antiResourceLocking = false;
/** * The list of unique application listener class names configured for this application, in the order they were * encountered in the resulting merged web.xml file.
*/ private CopyOnWriteArrayList<String> applicationListeners = new CopyOnWriteArrayList<>();
/** * The set of application listeners that are required to have limited access to ServletContext methods. See Servlet * 3.1 section 4.4.
*/ privatefinal Set<Object> noPluggabilityListeners = new HashSet<>();
/** * The list of instantiated application event listener objects. Note that SCIs and other code may use the * pluggability APIs to add listener instances directly to this list before the application starts.
*/ private List<Object> applicationEventListenersList = new CopyOnWriteArrayList<>();
/** * The set of instantiated application lifecycle listener objects. Note that SCIs and other code may use the * pluggability APIs to add listener instances directly to this list before the application starts.
*/ private Object applicationLifecycleListenersObjects[] = new Object[0];
/** * The ordered set of ServletContainerInitializers for this web application.
*/ private Map<ServletContainerInitializer,Set<Class<?>>> initializers = new LinkedHashMap<>();
/** * The set of application parameters defined for this application.
*/ private ApplicationParameter applicationParameters[] = new ApplicationParameter[0];
privatefinal Object applicationParametersLock = new Object();
/** * The broadcaster that sends j2ee notifications.
*/ private NotificationBroadcasterSupport broadcaster = null;
/** * The Locale to character set mapper for this application.
*/ private CharsetMapper charsetMapper = null;
/** * The Java class name of the CharsetMapper class to be created.
*/ private String charsetMapperClass = "org.apache.catalina.util.CharsetMapper";
/** * The URL of the XML descriptor for this context.
*/ private URL configFile = null;
/** * The "correctly configured" flag for this Context.
*/ privateboolean configured = false;
/** * The security constraints for this web application.
*/ privatevolatile SecurityConstraint constraints[] = new SecurityConstraint[0];
privatefinal Object constraintsLock = new Object();
/** * The ServletContext implementation associated with this Context.
*/ protected ApplicationContext context = null;
/** * The wrapped version of the associated ServletContext that is presented to listeners that are required to have * limited access to ServletContext methods. See Servlet 3.1 section 4.4.
*/ private NoPluggabilityServletContext noPluggabilityServletContext = null;
/** * Should we attempt to use cookies for session id communication?
*/ privateboolean cookies = true;
/** * Should we allow the <code>ServletContext.getContext()</code> method to access the context of other web * applications in this server?
*/ privateboolean crossContext = false;
/** * Unencoded path for this web application.
*/ private String path = null;
/** * The "follow standard delegation model" flag that will be used to configure our ClassLoader. Graal cannot actually * load a class from the webapp classloader, so delegate by default.
*/ privateboolean delegate = JreCompat.isGraalAvailable();
privateboolean denyUncoveredHttpMethods;
/** * The display name of this web application.
*/ private String displayName = null;
/** * Override the default context xml location.
*/ private String defaultContextXml;
/** * Override the default web xml location.
*/ private String defaultWebXml;
/** * The distributable flag for this web application.
*/ privateboolean distributable = false;
/** * The document root for this web application.
*/ private String docBase = null;
privatefinal ErrorPageSupport errorPageSupport = new ErrorPageSupport();
/** * The set of filter configurations (and associated filter instances) we have initialized, keyed by filter name.
*/ private Map<String,ApplicationFilterConfig> filterConfigs = new HashMap<>(); // Guarded by filterDefs
/** * The set of filter definitions for this application, keyed by filter name.
*/ private Map<String,FilterDef> filterDefs = new HashMap<>();
/** * The set of filter mappings for this application, in the order they were defined in the deployment descriptor with * additional mappings added via the {@link ServletContext} possibly both before and after those defined in the * deployment descriptor.
*/ privatefinal ContextFilterMaps filterMaps = new ContextFilterMaps();
/** * The Loader implementation with which this Container is associated.
*/ private Loader loader = null; privatefinal ReadWriteLock loaderLock = new ReentrantReadWriteLock();
/** * The login configuration descriptor for this web application.
*/ private LoginConfig loginConfig = null;
/** * The Manager implementation with which this Container is associated.
*/ protected Manager manager = null; privatefinal ReadWriteLock managerLock = new ReentrantReadWriteLock();
/** * The naming context listener for this web application.
*/ private NamingContextListener namingContextListener = null;
/** * The naming resources for this web application.
*/ private NamingResourcesImpl namingResources = null;
/** * The message destinations for this web application.
*/ private HashMap<String,MessageDestination> messageDestinations = new HashMap<>();
/** * The MIME mappings for this web application, keyed by extension.
*/ private Map<String,String> mimeMappings = new HashMap<>();
/** * The context initialization parameters for this web application, keyed by name.
*/ privatefinal Map<String,String> parameters = new ConcurrentHashMap<>();
/** * The request processing pause flag (while reloading occurs)
*/ privatevolatileboolean paused = false;
/** * The public identifier of the DTD for the web application deployment descriptor version we are currently parsing. * This is used to support relaxed validation rules when processing version 2.2 web.xml files.
*/ private String publicId = null;
/** * The reloadable flag for this web application.
*/ privateboolean reloadable = false;
/** * Unpack WAR property.
*/ privateboolean unpackWAR = true;
/** * The default context override flag for this web application.
*/ privateboolean override = false;
/** * The original document root for this web application.
*/ private String originalDocBase = null;
/** * The privileged flag for this web application.
*/ privateboolean privileged = false;
/** * Should the next call to <code>addWelcomeFile()</code> cause replacement of any existing welcome files? This will * be set before processing the web application's deployment descriptor, so that application specified choices * <strong>replace</strong>, rather than append to, those defined in the global descriptor.
*/ privateboolean replaceWelcomeFiles = false;
/** * The security role mappings for this application, keyed by role name (as used within the application).
*/ private Map<String,String> roleMappings = new HashMap<>();
/** * The security roles for this application, keyed by role name.
*/ private String securityRoles[] = new String[0];
privatefinal Object securityRolesLock = new Object();
/** * The servlet mappings for this web application, keyed by matching pattern.
*/ private Map<String,String> servletMappings = new HashMap<>();
privatefinal Object servletMappingsLock = new Object();
/** * The session timeout (in minutes) for this web application.
*/ privateint sessionTimeout = 30;
/** * The notification sequence number.
*/ private AtomicLong sequenceNumber = new AtomicLong(0);
/** * Set flag to true to cause the system.out and system.err to be redirected to the logger when executing a servlet.
*/ privateboolean swallowOutput = false;
/** * Amount of ms that the container will wait for servlets to unload.
*/ privatelong unloadDelay = 2000;
/** * The watched resources for this application.
*/ private String watchedResources[] = new String[0];
privatefinal Object watchedResourcesLock = new Object();
/** * The welcome files for this application.
*/ private String welcomeFiles[] = new String[0];
privatefinal Object welcomeFilesLock = new Object();
/** * The set of classnames of LifecycleListeners that will be added to each newly created Wrapper by * <code>createWrapper()</code>.
*/ private String wrapperLifecycles[] = new String[0];
privatefinal Object wrapperLifecyclesLock = new Object();
/** * The set of classnames of ContainerListeners that will be added to each newly created Wrapper by * <code>createWrapper()</code>.
*/ private String wrapperListeners[] = new String[0];
privatefinal Object wrapperListenersLock = new Object();
/** * The pathname to the work directory for this context (relative to the server's home if not absolute).
*/ private String workDir = null;
/** * Java class name of the Wrapper class implementation we use.
*/ private String wrapperClassName = StandardWrapper.class.getName(); privateClass<?> wrapperClass = null;
/** * JNDI use flag.
*/ privateboolean useNaming = true;
/** * Name of the associated naming context.
*/ private String namingContextName = null;
private WebResourceRoot resources; privatefinal ReadWriteLock resourcesLock = new ReentrantReadWriteLock();
/** * Name of the engine. If null, the domain is used.
*/ private String j2EEApplication = "none"; private String j2EEServer = "none";
/** * Attribute value used to turn on/off XML validation for web.xml and web-fragment.xml files.
*/ privateboolean webXmlValidation = Globals.STRICT_SERVLET_COMPLIANCE;
/** * Attribute value used to turn on/off XML namespace validation
*/ privateboolean webXmlNamespaceAware = Globals.STRICT_SERVLET_COMPLIANCE;
/** * Attribute used to turn on/off the use of external entities.
*/ privateboolean xmlBlockExternal = true;
/** * Attribute value used to turn on/off XML validation
*/ privateboolean tldValidation = Globals.STRICT_SERVLET_COMPLIANCE;
/** * The name to use for session cookies. <code>null</code> indicates that the name is controlled by the application.
*/ private String sessionCookieName;
/** * The flag that indicates that session cookies should use HttpOnly
*/ privateboolean useHttpOnly = true;
/** * The domain to use for session cookies. <code>null</code> indicates that the domain is controlled by the * application.
*/ private String sessionCookieDomain;
/** * The path to use for session cookies. <code>null</code> indicates that the path is controlled by the application.
*/ private String sessionCookiePath;
/** * Is a / added to the end of the session cookie path to ensure browsers, particularly IE, don't send a session * cookie for context /foo with requests intended for context /foobar.
*/ privateboolean sessionCookiePathUsesTrailingSlash = false;
/** * The Jar scanner to use to search for Jars that might contain configuration information such as TLDs or * web-fragment.xml files.
*/ private JarScanner jarScanner = null;
/** * Enables the RMI Target memory leak detection to be controlled. This is necessary since the detection can only * work if some of the modularity checks are disabled.
*/ privateboolean clearReferencesRmiTargets = true;
/** * Should Tomcat attempt to terminate threads that have been started by the web application? Stopping threads is * performed via the deprecated (for good reason) <code>Thread.stop()</code> method and is likely to result in * instability. As such, enabling this should be viewed as an option of last resort in a development environment and * is not recommended in a production environment. If not specified, the default value of <code>false</code> will be * used.
*/ privateboolean clearReferencesStopThreads = false;
/** * Should Tomcat attempt to terminate any {@link java.util.TimerThread}s that have been started by the web * application? If not specified, the default value of <code>false</code> will be used.
*/ privateboolean clearReferencesStopTimerThreads = false;
/** * If an HttpClient keep-alive timer thread has been started by this web application and is still running, should * Tomcat change the context class loader from the current {@link ClassLoader} to {@link ClassLoader#getParent()} to * prevent a memory leak? Note that the keep-alive timer thread will stop on its own once the keep-alives all expire * however, on a busy system that might not happen for some time.
*/ privateboolean clearReferencesHttpClientKeepAliveThread = true;
/** * Should Tomcat renew the threads of the thread pool when the application is stopped to avoid memory leaks because * of uncleaned ThreadLocal variables. This also requires that the threadRenewalDelay property of the * StandardThreadExecutor or ThreadPoolExecutor be set to a positive value.
*/ privateboolean renewThreadsWhenStoppingContext = true;
/** * Should Tomcat attempt to clear references to classes loaded by the web application class loader from the * ObjectStreamClass caches?
*/ privateboolean clearReferencesObjectStreamClassCaches = true;
/** * Should Tomcat attempt to clear references to classes loaded by this class loader from ThreadLocals?
*/ privateboolean clearReferencesThreadLocals = true;
/** * Should Tomcat skip the memory leak checks when the web application is stopped as part of the process of shutting * down the JVM?
*/ privateboolean skipMemoryLeakChecksOnJvmShutdown = false;
/** * Should the effective web.xml be logged when the context starts?
*/ privateboolean logEffectiveWebXml = false;
/** * Servlets created via {@link ApplicationContext#createServlet(Class)} for tracking purposes.
*/ private Set<Servlet> createdServlets = new HashSet<>();
privateboolean preemptiveAuthentication = false;
privateboolean sendRedirectBody = false;
privateboolean jndiExceptionOnFailedWrite = true;
private Map<String,String> postConstructMethods = new HashMap<>(); private Map<String,String> preDestroyMethods = new HashMap<>();
@Override public String getResponseCharacterEncoding() { return responseEncoding;
}
@Override publicvoid setResponseCharacterEncoding(String responseEncoding) { /* * This ensures that the context response encoding is represented by a unique String object. This enables the * Default Servlet to differentiate between a Response using this default encoding and one that has been * explicitly configured.
*/ if (responseEncoding == null) { this.responseEncoding = null;
} else { this.responseEncoding = new String(responseEncoding);
}
}
/** * {@inheritDoc} * <p> * The default value for this implementation is {@code true}.
*/
@Override publicboolean getDispatchersUseEncodedPaths() { return dispatchersUseEncodedPaths;
}
/** * {@inheritDoc} * <p> * The default value for this implementation is {@code true}.
*/
@Override publicboolean getUseRelativeRedirects() { return useRelativeRedirects;
}
/** * {@inheritDoc} * <p> * The default value for this implementation is {@code false}.
*/
@Override publicboolean getMapperContextRootRedirectEnabled() { return mapperContextRootRedirectEnabled;
}
/** * {@inheritDoc} * <p> * The default value for this implementation is {@code false}.
*/
@Override publicboolean getMapperDirectoryRedirectEnabled() { return mapperDirectoryRedirectEnabled;
}
/** * {@inheritDoc} * <p> * The default value for this implementation is {@code true}.
*/
@Override publicboolean getValidateClientProvidedNewSessionId() { return validateClientProvidedNewSessionId;
}
@Override public String getEncodedPath() { return encodedPath;
}
/** * Set to <code>true</code> to allow requests mapped to servlets that do not explicitly declare @MultipartConfig or * have <multipart-config> specified in web.xml to parse multipart/form-data requests. * * @param allowCasualMultipartParsing <code>true</code> to allow such casual parsing, <code>false</code> otherwise.
*/
@Override publicvoid setAllowCasualMultipartParsing(boolean allowCasualMultipartParsing) { this.allowCasualMultipartParsing = allowCasualMultipartParsing;
}
/** * Returns <code>true</code> if requests mapped to servlets without "multipart config" to parse multipart/form-data * requests anyway. * * @return <code>true</code> if requests mapped to servlets without "multipart config" to parse multipart/form-data * requests, <code>false</code> otherwise.
*/
@Override publicboolean getAllowCasualMultipartParsing() { returnthis.allowCasualMultipartParsing;
}
/** * Set to <code>false</code> to disable request data swallowing after an upload was aborted due to size constraints. * * @param swallowAbortedUploads <code>false</code> to disable swallowing, <code>true</code> otherwise (default).
*/
@Override publicvoid setSwallowAbortedUploads(boolean swallowAbortedUploads) { this.swallowAbortedUploads = swallowAbortedUploads;
}
/** * Returns <code>true</code> if remaining request data will be read (swallowed) even the request violates a data * size constraint. * * @return <code>true</code> if data will be swallowed (default), <code>false</code> otherwise.
*/
@Override publicboolean getSwallowAbortedUploads() { returnthis.swallowAbortedUploads;
}
/** * Add a ServletContainerInitializer instance to this web application. * * @param sci The instance to add * @param classes The classes in which the initializer expressed an interest
*/
@Override publicvoid addServletContainerInitializer(ServletContainerInitializer sci, Set<Class<?>> classes) {
initializers.put(sci, classes);
}
/** * Return the "follow standard delegation model" flag used to configure our ClassLoader. * * @return <code>true</code> if classloading delegates to the parent classloader first
*/ publicboolean getDelegate() { returnthis.delegate;
}
/** * Set the "follow standard delegation model" flag used to configure our ClassLoader. * * @param delegate The new flag
*/ publicvoid setDelegate(boolean delegate) {
/** * @return true if the internal naming support is used.
*/ publicboolean isUseNaming() { return useNaming;
}
/** * Enables or disables naming. * * @param useNaming <code>true</code> to enable the naming environment
*/ publicvoid setUseNaming(boolean useNaming) { this.useNaming = useNaming;
}
@Override public Object[] getApplicationEventListeners() { return applicationEventListenersList.toArray();
}
/** * {@inheritDoc} Note that this implementation is not thread safe. If two threads call this method concurrently, the * result may be either set of listeners or a the union of both.
*/
@Override publicvoid setApplicationEventListeners(Object listeners[]) {
applicationEventListenersList.clear(); if (listeners != null && listeners.length > 0) {
applicationEventListenersList.addAll(Arrays.asList(listeners));
}
}
/** * Add a listener to the end of the list of initialized application event listeners. * * @param listener The listener to add
*/ publicvoid addApplicationEventListener(Object listener) {
applicationEventListenersList.add(listener);
}
@Override public Object[] getApplicationLifecycleListeners() { return applicationLifecycleListenersObjects;
}
/** * Store the set of initialized application lifecycle listener objects, in the order they were specified in the web * application deployment descriptor, for this application. * * @param listeners The set of instantiated listener objects.
*/
@Override publicvoid setApplicationLifecycleListeners(Object listeners[]) {
applicationLifecycleListenersObjects = listeners;
}
/** * Add a listener to the end of the list of initialized application lifecycle listeners. * * @param listener The listener to add
*/ publicvoid addApplicationLifecycleListener(Object listener) { int len = applicationLifecycleListenersObjects.length;
Object[] newListeners = Arrays.copyOf(applicationLifecycleListenersObjects, len + 1);
newListeners[len] = listener;
applicationLifecycleListenersObjects = newListeners;
}
/** * @return the antiResourceLocking flag for this Context.
*/ publicboolean getAntiResourceLocking() { returnthis.antiResourceLocking;
}
/** * Set the antiResourceLocking feature for this Context. * * @param antiResourceLocking The new flag value
*/ publicvoid setAntiResourceLocking(boolean antiResourceLocking) {
/** * @return the Locale to character set mapper for this Context.
*/ public CharsetMapper getCharsetMapper() {
// Create a mapper the first time it is requested if (this.charsetMapper == null) { try { Class<?> clazz = Class.forName(charsetMapperClass); this.charsetMapper = (CharsetMapper) clazz.getConstructor().newInstance();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t); this.charsetMapper = new CharsetMapper();
}
}
returnthis.charsetMapper;
}
/** * Set the Locale to character set mapper for this Context. * * @param mapper The new mapper
*/ publicvoid setCharsetMapper(CharsetMapper mapper) {
/** * Set the "correctly configured" flag for this Context. This can be set to false by startup listeners that detect a * fatal configuration error to avoid the application from being made available. * * @param configured The new correctly configured flag
*/
@Override publicvoid setConfigured(boolean configured) {
/** * Gets the name to use for session cookies. Overrides any setting that may be specified by the application. * * @return The value of the default session cookie name or null if not specified
*/
@Override public String getSessionCookieName() { return sessionCookieName;
}
/** * Sets the name to use for session cookies. Overrides any setting that may be specified by the application. * * @param sessionCookieName The name to use
*/
@Override publicvoid setSessionCookieName(String sessionCookieName) {
String oldSessionCookieName = this.sessionCookieName; this.sessionCookieName = sessionCookieName;
support.firePropertyChange("sessionCookieName", oldSessionCookieName, sessionCookieName);
}
/** * Gets the value of the use HttpOnly cookies for session cookies flag. * * @return <code>true</code> if the HttpOnly flag should be set on session cookies
*/
@Override publicboolean getUseHttpOnly() { return useHttpOnly;
}
/** * Sets the use HttpOnly cookies for session cookies flag. * * @param useHttpOnly Set to <code>true</code> to use HttpOnly cookies for session cookies
*/
@Override publicvoid setUseHttpOnly(boolean useHttpOnly) { boolean oldUseHttpOnly = this.useHttpOnly; this.useHttpOnly = useHttpOnly;
support.firePropertyChange("useHttpOnly", oldUseHttpOnly, this.useHttpOnly);
}
/** * Gets the domain to use for session cookies. Overrides any setting that may be specified by the application. * * @return The value of the default session cookie domain or null if not specified
*/
@Override public String getSessionCookieDomain() { return sessionCookieDomain;
}
/** * Sets the domain to use for session cookies. Overrides any setting that may be specified by the application. * * @param sessionCookieDomain The domain to use
*/
@Override publicvoid setSessionCookieDomain(String sessionCookieDomain) {
String oldSessionCookieDomain = this.sessionCookieDomain; this.sessionCookieDomain = sessionCookieDomain;
support.firePropertyChange("sessionCookieDomain", oldSessionCookieDomain, sessionCookieDomain);
}
/** * Gets the path to use for session cookies. Overrides any setting that may be specified by the application. * * @return The value of the default session cookie path or null if not specified
*/
@Override public String getSessionCookiePath() { return sessionCookiePath;
}
/** * Sets the path to use for session cookies. Overrides any setting that may be specified by the application. * * @param sessionCookiePath The path to use
*/
@Override publicvoid setSessionCookiePath(String sessionCookiePath) {
String oldSessionCookiePath = this.sessionCookiePath; this.sessionCookiePath = sessionCookiePath;
support.firePropertyChange("sessionCookiePath", oldSessionCookiePath, sessionCookiePath);
}
/** * Set the "allow crossing servlet contexts" flag. * * @param crossContext The new cross contexts flag
*/
@Override publicvoid setCrossContext(boolean crossContext) {
public String getDefaultContextXml() { return defaultContextXml;
}
/** * Set the location of the default context xml that will be used. If not absolute, it'll be made relative to the * engine's base dir ( which defaults to catalina.base system property ). * * @param defaultContextXml The default web xml
*/ publicvoid setDefaultContextXml(String defaultContextXml) { this.defaultContextXml = defaultContextXml;
}
public String getDefaultWebXml() { return defaultWebXml;
}
/** * Set the location of the default web xml that will be used. If not absolute, it'll be made relative to the * engine's base dir ( which defaults to catalina.base system property ). * * @param defaultWebXml The default web xml
*/ publicvoid setDefaultWebXml(String defaultWebXml) { this.defaultWebXml = defaultWebXml;
}
/** * Gets the time (in milliseconds) it took to start this context. * * @return Time (in milliseconds) it took to start this context.
*/ publiclong getStartupTime() { return startupTime;
}
/** * @return the display name of this web application.
*/
@Override public String getDisplayName() { returnthis.displayName;
}
/** * @return the alternate Deployment Descriptor name.
*/
@Override public String getAltDDName() { return altDDName;
}
/** * Set an alternate Deployment Descriptor name. * * @param altDDName The new name
*/
@Override publicvoid setAltDDName(String altDDName) { this.altDDName = altDDName; if (context != null) {
context.setAttribute(Globals.ALT_DD_ATTR, altDDName);
}
}
/** * Set the display name of this web application. * * @param displayName The new display name
*/
@Override publicvoid setDisplayName(String displayName) {
/** * @return the distributable flag for this web application.
*/
@Override publicboolean getDistributable() { returnthis.distributable;
}
/** * Set the distributable flag for this web application. * * @param distributable The new distributable flag
*/
@Override publicvoid setDistributable(boolean distributable) { boolean oldDistributable = this.distributable; this.distributable = distributable;
support.firePropertyChange("distributable", oldDistributable, this.distributable);
}
@Override public String getDocBase() { returnthis.docBase;
}
// Stop the old component if necessary if (oldManager instanceof Lifecycle) { try {
((Lifecycle) oldManager).stop();
((Lifecycle) oldManager).destroy();
} catch (LifecycleException e) {
log.error(sm.getString("standardContext.setManager.stop"), e);
}
}
// Start the new component if necessary if (manager != null) {
manager.setContext(this);
} if (getState().isAvailable() && manager instanceof Lifecycle) { try {
((Lifecycle) manager).start();
} catch (LifecycleException e) {
log.error(sm.getString("standardContext.setManager.start"), e);
}
}
} finally {
writeLock.unlock();
}
// Report this property change to interested listeners
support.firePropertyChange("manager", oldManager, manager);
}
/** * @return the boolean on the annotations parsing.
*/
@Override publicboolean getIgnoreAnnotations() { returnthis.ignoreAnnotations;
}
/** * Set the boolean on the annotations parsing for this web application. * * @param ignoreAnnotations The boolean on the annotations parsing
*/
@Override publicvoid setIgnoreAnnotations(boolean ignoreAnnotations) { boolean oldIgnoreAnnotations = this.ignoreAnnotations; this.ignoreAnnotations = ignoreAnnotations;
support.firePropertyChange("ignoreAnnotations", oldIgnoreAnnotations, this.ignoreAnnotations);
}
/** * @return the login configuration descriptor for this web application.
*/
@Override public LoginConfig getLoginConfig() { returnthis.loginConfig;
}
/** * Set the login configuration descriptor for this web application. * * @param config The new login configuration
*/
@Override publicvoid setLoginConfig(LoginConfig config) {
// Validate the incoming property value if (config == null) { thrownew IllegalArgumentException(sm.getString("standardContext.loginConfig.required"));
}
String loginPage = config.getLoginPage(); if ((loginPage != null) && !loginPage.startsWith("/")) { if (isServlet22()) { if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.loginConfig.loginWarning", loginPage));
}
config.setLoginPage("/" + loginPage);
} else { thrownew IllegalArgumentException(sm.getString("standardContext.loginConfig.loginPage", loginPage));
}
}
String errorPage = config.getErrorPage(); if ((errorPage != null) && !errorPage.startsWith("/")) { if (isServlet22()) { if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.loginConfig.errorWarning", errorPage));
}
config.setErrorPage("/" + errorPage);
} else { thrownew IllegalArgumentException(sm.getString("standardContext.loginConfig.errorPage", errorPage));
}
}
// Process the property setting change
LoginConfig oldLoginConfig = this.loginConfig; this.loginConfig = config;
support.firePropertyChange("loginConfig", oldLoginConfig, this.loginConfig);
}
/** * @return the naming resources associated with this web application.
*/
@Override public NamingResourcesImpl getNamingResources() { if (namingResources == null) {
setNamingResources(new NamingResourcesImpl());
} return namingResources;
}
/** * Set the naming resources for this web application. * * @param namingResources The new naming resources
*/
@Override publicvoid setNamingResources(NamingResourcesImpl namingResources) {
// Process the property setting change
NamingResourcesImpl oldNamingResources = this.namingResources; this.namingResources = namingResources; if (namingResources != null) {
namingResources.setContainer(this);
}
support.firePropertyChange("namingResources", oldNamingResources, this.namingResources);
if (getState() == LifecycleState.NEW || getState() == LifecycleState.INITIALIZING ||
getState() == LifecycleState.INITIALIZED) { // NEW will occur if Context is defined in server.xml // At this point getObjectKeyPropertiesNameOnly() will trigger an // NPE. // INITIALIZED will occur if the Context is defined in a context.xml // file // If started now, a second start will be attempted when the context // starts
// In both cases, return and let context init the namingResources // when it starts return;
}
/** * @return the context path for this Context.
*/
@Override public String getPath() { return path;
}
/** * Set the context path for this Context. * * @param path The new context path
*/
@Override publicvoid setPath(String path) { boolean invalid = false; if (path == null || path.equals("/")) {
invalid = true; this.path = "";
} elseif (path.isEmpty() || path.startsWith("/")) { this.path = path;
} else {
invalid = true; this.path = "/" + path;
} if (this.path.endsWith("/")) {
invalid = true; this.path = this.path.substring(0, this.path.length() - 1);
} if (invalid) {
log.warn(sm.getString("standardContext.pathInvalid", path, this.path));
}
encodedPath = URLEncoder.DEFAULT.encode(this.path, StandardCharsets.UTF_8); if (getName() == null) {
setName(this.path);
}
}
/** * @return the public identifier of the deployment descriptor DTD that is currently being parsed.
*/
@Override public String getPublicId() { returnthis.publicId;
}
/** * Set the public identifier of the deployment descriptor DTD that is currently being parsed. * * @param publicId The public identifier
*/
@Override publicvoid setPublicId(String publicId) {
if (log.isDebugEnabled()) {
log.debug("Setting deployment descriptor public ID to '" + publicId + "'");
}
/** * @return the reloadable flag for this web application.
*/
@Override publicboolean getReloadable() { returnthis.reloadable;
}
/** * @return the default context override flag for this web application.
*/
@Override publicboolean getOverride() { returnthis.override;
}
/** * @return the original document root for this Context. This can be an absolute pathname, a relative pathname, or a * URL. Is only set as deployment has change docRoot!
*/ public String getOriginalDocBase() { returnthis.originalDocBase;
}
/** * Set the original document root for this Context. This can be an absolute pathname, a relative pathname, or a URL. * * @param docBase The original document root
*/ publicvoid setOriginalDocBase(String docBase) {
this.originalDocBase = docBase;
}
/** * @return the parent class loader (if any) for this web application. This call is meaningful only * <strong>after</strong> a Loader has been configured.
*/
@Override public ClassLoader getParentClassLoader() { if (parentClassLoader != null) { return parentClassLoader;
} if (getPrivileged()) { returnthis.getClass().getClassLoader();
} elseif (parent != null) { return parent.getParentClassLoader();
} return ClassLoader.getSystemClassLoader();
}
/** * @return the privileged flag for this web application.
*/
@Override publicboolean getPrivileged() { returnthis.privileged;
}
/** * Set the privileged flag for this web application. * * @param privileged The new privileged flag
*/
@Override publicvoid setPrivileged(boolean privileged) {
/** * Set the reloadable flag for this web application. * * @param reloadable The new reloadable flag
*/
@Override publicvoid setReloadable(boolean reloadable) {
/** * Set the default context override flag for this web application. * * @param override The new override flag
*/
@Override publicvoid setOverride(boolean override) {
/** * Set the "replace welcome files" property. * * @param replaceWelcomeFiles The new property value
*/ publicvoid setReplaceWelcomeFiles(boolean replaceWelcomeFiles) {
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.