| /* |
| * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved. |
| * Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed 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; |
| |
| import static com.sun.logging.LogCleanerUtil.neutralizeForLog; |
| import org.glassfish.grizzly.http.server.util.AlternateDocBase; |
| import org.glassfish.grizzly.http.server.util.Mapper; |
| import org.glassfish.grizzly.http.server.util.MappingData; |
| import org.apache.catalina.*; |
| import org.apache.catalina.deploy.*; |
| import org.apache.catalina.loader.WebappLoader; |
| import org.apache.catalina.session.ManagerBase; |
| import org.apache.catalina.session.PersistentManagerBase; |
| import org.apache.catalina.session.StandardManager; |
| import org.apache.catalina.servlets.DefaultServlet; |
| import org.apache.catalina.startup.ContextConfig; |
| import org.apache.catalina.util.*; |
| import org.apache.naming.ContextBindings; |
| import org.apache.naming.resources.BaseDirContext; |
| import org.apache.naming.resources.DirContextURLStreamHandler; |
| import org.apache.naming.resources.FileDirContext; |
| import org.apache.naming.resources.WebDirContext; |
| import org.apache.naming.resources.ProxyDirContext; |
| import org.apache.naming.resources.Resource; |
| import org.apache.naming.resources.WARDirContext; |
| import org.glassfish.hk2.classmodel.reflect.Types; |
| import org.glassfish.web.loader.WebappClassLoader; |
| import org.glassfish.web.loader.ServletContainerInitializerUtil; |
| import org.glassfish.web.valve.GlassFishValve; |
| |
| import javax.management.*; |
| import javax.naming.Binding; |
| import javax.naming.NamingException; |
| import javax.naming.directory.DirContext; |
| import jakarta.servlet.*; |
| import jakarta.servlet.descriptor.JspConfigDescriptor; |
| import jakarta.servlet.http.HttpSession; |
| import jakarta.servlet.http.HttpSessionAttributeListener; |
| import jakarta.servlet.http.HttpSessionIdListener; |
| import jakarta.servlet.http.HttpSessionListener; |
| import jakarta.servlet.http.HttpUpgradeHandler; |
| import java.io.*; |
| import java.net.MalformedURLException; |
| import java.net.URLDecoder; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.text.MessageFormat; |
| import java.util.*; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ConcurrentMap; |
| import java.util.concurrent.atomic.AtomicInteger; |
| import java.util.logging.Level; |
| import jakarta.servlet.http.HttpServletMapping; |
| import org.apache.catalina.connector.MappingImpl; |
| import org.glassfish.grizzly.http.util.CharChunk; |
| import org.glassfish.grizzly.http.util.MessageBytes; |
| |
| /** |
| * 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 |
| * @version $Revision: 1.48 $ $Date: 2007/07/25 00:52:04 $ |
| */ |
| |
| public class StandardContext |
| extends ContainerBase |
| implements Context, ServletContext |
| { |
| private static final String DEFAULT_RESPONSE_CHARACTER_ENCODING = "ISO-8859-1"; |
| |
| // have two similar messages |
| // have two similar messages |
| // have to similar messages |
| |
| private static final ClassLoader standardContextClassLoader = |
| StandardContext.class.getClassLoader(); |
| |
| private static final Set<SessionTrackingMode> DEFAULT_SESSION_TRACKING_MODES = |
| EnumSet.of(SessionTrackingMode.COOKIE); |
| |
| /** |
| * Array containing the safe characters set. |
| */ |
| protected static final URLEncoder urlEncoder; |
| |
| /** |
| * The descriptive information string for this implementation. |
| */ |
| private static final String info = |
| "org.apache.catalina.core.StandardContext/1.0"; |
| |
| private static final RuntimePermission GET_CLASSLOADER_PERMISSION = |
| new RuntimePermission("getClassLoader"); |
| |
| /** |
| * GMT timezone - all HTTP dates are on GMT |
| */ |
| static { |
| urlEncoder = new URLEncoder(); |
| urlEncoder.addSafeCharacter('~'); |
| urlEncoder.addSafeCharacter('-'); |
| urlEncoder.addSafeCharacter('_'); |
| urlEncoder.addSafeCharacter('.'); |
| urlEncoder.addSafeCharacter('*'); |
| urlEncoder.addSafeCharacter('/'); |
| } |
| |
| |
| // ----------------------------------------------------------- Constructors |
| |
| /** |
| * Create a new StandardContext component with the default basic Valve. |
| */ |
| public StandardContext() { |
| pipeline.setBasic(new StandardContextValve()); |
| namingResources.setContainer(this); |
| if (Globals.IS_SECURITY_ENABLED) { |
| mySecurityManager = AccessController.doPrivileged( |
| new PrivilegedCreateSecurityManager()); |
| } |
| } |
| |
| // ----------------------------------------------------- Instance Variables |
| |
| /** |
| * The alternate deployment descriptor name. |
| */ |
| private String altDDName = null; |
| |
| /** |
| * The antiJARLocking flag for this Context. |
| */ |
| private boolean antiJARLocking = false; |
| |
| /** |
| * Associated host name. |
| */ |
| private String hostName; |
| |
| /** |
| * The list of instantiated application event listeners |
| */ |
| private List<EventListener> eventListeners = |
| new ArrayList<EventListener>(); |
| |
| /** |
| * The list of ServletContextListeners |
| */ |
| protected ArrayList<ServletContextListener> contextListeners = |
| new ArrayList<ServletContextListener>(); |
| |
| /** |
| * The list of HttpSessionListeners |
| */ |
| private List<HttpSessionListener> sessionListeners = |
| new ArrayList<HttpSessionListener>(); |
| |
| /** |
| * The set of application parameters defined for this application. |
| */ |
| private List<ApplicationParameter> applicationParameters = |
| new ArrayList<ApplicationParameter>(); |
| |
| /** |
| * The application available flag for this Context. |
| */ |
| private boolean available = false; |
| |
| /** |
| * 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 = CharsetMapper.class.getName(); |
| |
| /** |
| * The request character encoding. |
| */ |
| private String requestCharacterEncoding = null; |
| |
| /** |
| * The response character encoding. |
| */ |
| private String responseCharacterEncoding = null; |
| |
| /** |
| * The path to a file to save this Context information. |
| */ |
| private String configFile = null; |
| |
| /** |
| * The "correctly configured" flag for this Context. |
| */ |
| private boolean configured = false; |
| |
| /** |
| * The security constraints for this web application. |
| */ |
| private List<SecurityConstraint> constraints = |
| new ArrayList<SecurityConstraint>(); |
| |
| /** |
| * The ServletContext implementation associated with this Context. |
| */ |
| // START RIMOD 4894300 |
| /* |
| private transient ApplicationContext context = null; |
| */ |
| protected ApplicationContext context = null; |
| // END RIMOD 4894300 |
| |
| /** |
| * Is the context initialized. |
| */ |
| private boolean isContextInitializedCalled = false; |
| |
| /** |
| * Compiler classpath to use. |
| */ |
| private String compilerClasspath = null; |
| |
| /** |
| * Should we attempt to use cookies for session id communication? |
| */ |
| private boolean cookies = true; |
| |
| /** |
| * true if the rewriting of URLs with the jsessionids of HTTP |
| * sessions belonging to this context is enabled, false otherwise |
| */ |
| private boolean enableURLRewriting = true; |
| |
| /** |
| * Should we allow the <code>ServletContext.getContext()</code> method |
| * to access the context of other web applications in this server? |
| */ |
| private boolean crossContext = false; |
| |
| /** |
| * The "follow standard delegation model" flag that will be used to |
| * configure our ClassLoader. |
| */ |
| private boolean delegate = false; |
| |
| /** |
| * The display name of this web application. |
| */ |
| private String displayName = null; |
| |
| /** |
| * Override the default web xml location. ContextConfig is not configurable |
| * so the setter is not used. |
| */ |
| private String defaultWebXml; |
| |
| /** |
| * The distributable flag for this web application. |
| */ |
| private boolean distributable = false; |
| |
| /** |
| * Thread local data used during request dispatch. |
| */ |
| private ThreadLocal<DispatchData> dispatchData = |
| new ThreadLocal<DispatchData>(); |
| |
| /** |
| * The document root for this web application. |
| */ |
| private String docBase = null; |
| |
| /** |
| * The exception pages for this web application, keyed by fully qualified |
| * class name of the Java exception. |
| */ |
| private Map<String, ErrorPage> exceptionPages = |
| new HashMap<String, ErrorPage>(); |
| |
| /** |
| * The default error page (error page that was declared |
| * without any exception-type and error-code). |
| */ |
| private ErrorPage defaultErrorPage; |
| |
| /** |
| * The set of filter configurations (and associated filter instances) we |
| * have initialized, keyed by filter name. |
| */ |
| private Map<String, FilterConfig> filterConfigs = |
| new HashMap<String, FilterConfig>(); |
| |
| /** |
| * The set of filter definitions for this application, keyed by |
| * filter name. |
| */ |
| private Map<String, FilterDef> filterDefs = new HashMap<String, FilterDef>(); |
| |
| /** |
| * The list of filter mappings for this application, in the order |
| * they were defined in the deployment descriptor. |
| */ |
| private List<FilterMap> filterMaps = new ArrayList<FilterMap>(); |
| |
| /** |
| * The list of classnames of InstanceListeners that will be added |
| * to each newly created Wrapper by <code>createWrapper()</code>. |
| */ |
| private ArrayList<String> instanceListeners = new ArrayList<String>(); |
| |
| /** |
| * The set of already instantiated InstanceListeners that will be added |
| * to each newly created Wrapper by <code>createWrapper()</code>. |
| */ |
| private List<InstanceListener> instanceListenerInstances = new ArrayList<InstanceListener>(); |
| |
| /** |
| * The login configuration descriptor for this web application. |
| */ |
| private LoginConfig loginConfig = null; |
| |
| /** |
| * The mapper associated with this context. |
| */ |
| private Mapper mapper = new Mapper(); |
| |
| /** |
| * The naming context listener for this web application. |
| */ |
| private NamingContextListener namingContextListener = null; |
| |
| /** |
| * The naming resources for this web application. |
| */ |
| private NamingResources namingResources = new NamingResources(); |
| |
| /** |
| * The message destinations for this web application. |
| */ |
| private Map<String, MessageDestination> messageDestinations = new HashMap<String, MessageDestination>(); |
| |
| /** |
| * The MIME mappings for this web application, keyed by extension. |
| */ |
| private Map<String,String> mimeMappings = new HashMap<String,String>(); |
| |
| /** |
| * The context initialization parameters for this web application, |
| * keyed by name. |
| */ |
| private HashMap<String, String> parameters = new HashMap<String, String>(); |
| |
| /** |
| * The request processing pause flag (while reloading occurs) |
| */ |
| private boolean 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. |
| */ |
| private boolean reloadable = false; |
| |
| /** |
| * Unpack WAR property. |
| */ |
| private boolean unpackWAR = true; |
| |
| /** |
| * The DefaultContext override flag for this web application. |
| */ |
| private boolean override = false; |
| |
| /** |
| * The original document root for this web application. |
| */ |
| private String originalDocBase = null; |
| |
| /** |
| * The privileged flag for this web application. |
| */ |
| private boolean 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. |
| */ |
| private boolean replaceWelcomeFiles = false; |
| |
| /** |
| * With proxy caching disabled, setting this flag to true adds |
| * Pragma and Cache-Control headers with "No-cache" as value. |
| * Setting this flag to false does not add any Pragma header, |
| * but sets the Cache-Control header to "private". |
| */ |
| private boolean securePagesWithPragma = true; |
| |
| /** |
| * The security role mappings for this application, keyed by role |
| * name (as used within the application). |
| */ |
| private Map<String, String> roleMappings = new HashMap<String, String>(); |
| |
| /** |
| * The security roles for this application |
| */ |
| private List<String> securityRoles = new ArrayList<String>(); |
| |
| /** |
| * The servlet mappings for this web application, keyed by |
| * matching pattern. |
| */ |
| private final Map<String, String> servletMappings = new HashMap<String, String>(); |
| |
| /** |
| * The session timeout (in minutes) for this web application. |
| */ |
| private int sessionTimeout = 30; |
| |
| /** |
| * Has the session timeout (in minutes) for this web application |
| * been over-ridden by web-xml |
| * HERCULES:add |
| */ |
| private boolean sessionTimeoutOveridden = false; |
| |
| /** |
| * The notification sequence number. |
| */ |
| private long sequenceNumber = 0; |
| |
| /** |
| * The status code error pages for this web application, keyed by |
| * HTTP status code (as an Integer). |
| */ |
| private final Map<Integer, ErrorPage> statusPages = |
| new HashMap<Integer, ErrorPage>(); |
| |
| /** |
| * Amount of ms that the container will wait for servlets to unload. |
| */ |
| private long unloadDelay = 2000; |
| |
| /** |
| * The watched resources for this application. |
| */ |
| private List<String> watchedResources = |
| Collections.synchronizedList(new ArrayList<String>()); |
| |
| /** |
| * The welcome files for this application. |
| */ |
| private String[] welcomeFiles = new String[0]; |
| |
| /** |
| * The list of classnames of LifecycleListeners that will be added |
| * to each newly created Wrapper by <code>createWrapper()</code>. |
| */ |
| private ArrayList<String> wrapperLifecycles = new ArrayList<String>(); |
| |
| /** |
| * The list of classnames of ContainerListeners that will be added |
| * to each newly created Wrapper by <code>createWrapper()</code>. |
| */ |
| private List<String> wrapperListeners = new ArrayList<String>(); |
| |
| /** |
| * The pathname to the work directory for this context (relative to |
| * the server's home if not absolute). |
| */ |
| private String workDir = null; |
| |
| /** |
| * JNDI use flag. |
| */ |
| private boolean useNaming = true; |
| |
| /** |
| * Filesystem based flag. |
| */ |
| private boolean filesystemBased = false; |
| |
| /** |
| * Name of the associated naming context. |
| */ |
| private String namingContextName = null; |
| |
| /** |
| * Frequency of the session expiration, and related manager operations. |
| * Manager operations will be done once for the specified amount of |
| * backgrondProcess calls (ie, the lower the amount, the most often the |
| * checks will occur). |
| */ |
| private int managerChecksFrequency = 6; |
| |
| /** |
| * Iteration count for background processing. |
| */ |
| private int count = 0; |
| |
| /** |
| * Caching allowed flag. |
| */ |
| private boolean cachingAllowed = true; |
| |
| /** |
| * Case sensitivity. |
| */ |
| protected boolean caseSensitive = true; |
| |
| /** |
| * Allow linking. |
| */ |
| protected boolean allowLinking = false; |
| |
| /** |
| * Cache max size in KB. |
| */ |
| protected int cacheMaxSize = 10240; // 10 MB |
| |
| /** |
| * Cache TTL in ms. |
| */ |
| protected int cacheTTL = 5000; |
| |
| /** |
| * Non proxied resources. |
| */ |
| private DirContext webappResources = null; |
| |
| /* |
| * Time (in milliseconds) it took to start this context |
| */ |
| private long startupTime; |
| |
| /* |
| * Time (in milliseconds since January 1, 1970, 00:00:00) when this |
| * context was started |
| */ |
| private long startTimeMillis; |
| |
| private long tldScanTime; |
| |
| // START SJSWS 6324431 |
| // Should the filter and security mapping be done |
| // in a case sensitive manner |
| protected boolean caseSensitiveMapping = true; |
| // END SJSWS 6324431 |
| |
| // START S1AS8PE 4817642 |
| /** |
| * The flag that specifies whether to reuse the session id (if any) from |
| * the request for newly created sessions |
| */ |
| private boolean reuseSessionID = false; |
| // END S1AS8PE 4817642 |
| |
| // START RIMOD 4642650 |
| /** |
| * The flag that specifies whether this context allows sendRedirect() to |
| * redirect to a relative URL. |
| */ |
| private boolean allowRelativeRedirect = false; |
| |
| // END RIMOD 4642650 |
| |
| /** Name of the engine. If null, the domain is used. |
| */ |
| private String engineName = null; |
| /* SJSAS 6340499 |
| private String j2EEApplication="none"; |
| */ |
| // START SJSAS 6340499 |
| private String j2EEApplication="null"; |
| // END SJSAS 6340499 |
| private String j2EEServer="none"; |
| |
| // START IASRI 4823322 |
| /** |
| * List of configured Auditors for this context. |
| */ |
| private Auditor[] auditors = null; |
| // END IASRI 4823322 |
| |
| // START RIMOD 4868393 |
| /** |
| * used to create unique id for each app instance. |
| */ |
| private static AtomicInteger instanceIDCounter = new AtomicInteger(1); |
| // END RIMOD 4868393 |
| |
| /** |
| * Attribute value used to turn on/off XML validation |
| */ |
| private boolean webXmlValidation = false; |
| |
| private String jvmRoute; |
| |
| /** |
| * Attribute value used to turn on/off XML namespace validation |
| */ |
| private boolean webXmlNamespaceAware = false; |
| |
| /** |
| * Attribute value used to turn on/off XML validation |
| */ |
| private boolean tldValidation = false; |
| |
| /** |
| * Attribute value used to turn on/off TLD XML namespace validation |
| */ |
| private boolean tldNamespaceAware = false; |
| |
| /** |
| * Is the context contains the JSF servlet. |
| */ |
| protected boolean isJsfApplication = false; |
| |
| // START S1AS8PE 4965017 |
| private boolean isReload = false; |
| // END S1AS8PE 4965017 |
| |
| /** |
| * Alternate doc base resources |
| */ |
| private ArrayList<AlternateDocBase> alternateDocBases = null; |
| |
| private boolean useMyFaces; |
| |
| private Set<SessionTrackingMode> sessionTrackingModes; |
| |
| /** |
| * Encoded path. |
| */ |
| private String encodedPath = null; |
| |
| /** |
| * Session cookie config |
| */ |
| private SessionCookieConfig sessionCookieConfig; |
| |
| /** |
| * The name of the session tracking cookies created by this context |
| * Cache the name here as the getSessionCookieConfig() is synchronized. |
| */ |
| private String sessionCookieName = Globals.SESSION_COOKIE_NAME; |
| |
| private boolean sessionCookieNameInitialized = false; |
| |
| protected ConcurrentMap<String, ServletRegistrationImpl> servletRegisMap = |
| new ConcurrentHashMap<String, ServletRegistrationImpl>(); |
| |
| protected ConcurrentMap<String, FilterRegistrationImpl> filterRegisMap = |
| new ConcurrentHashMap<String, FilterRegistrationImpl>(); |
| |
| /** |
| * The list of ordered libs, which is used as the value of the |
| * ServletContext attribute with name jakarta.servlet.context.orderedLibs |
| */ |
| private List<String> orderedLibs; |
| |
| // <jsp-config> related info aggregated from web.xml and web-fragment.xml |
| private JspConfigDescriptor jspConfigDesc; |
| |
| // ServletContextListeners may be registered (via |
| // ServletContext#addListener) only within the scope of |
| // ServletContainerInitializer#onStartup |
| private boolean isProgrammaticServletContextListenerRegistrationAllowed = false; |
| |
| /* |
| * Security manager responsible for enforcing permission check on |
| * ServletContext#getClassLoader |
| */ |
| private MySecurityManager mySecurityManager; |
| |
| // Iterable over all ServletContainerInitializers that were discovered |
| private Iterable<ServletContainerInitializer> servletContainerInitializers = null; |
| |
| // The major Servlet spec version of the web.xml |
| private int effectiveMajorVersion = 0; |
| |
| // The minor Servlet spec version of the web.xml |
| private int effectiveMinorVersion = 0; |
| |
| // Created via embedded API |
| private boolean isEmbedded = false; |
| |
| protected boolean directoryDeployed = false; |
| |
| protected boolean showArchivedRealPathEnabled = true; |
| |
| protected int servletReloadCheckSecs = 1; |
| |
| // ----------------------------------------------------- Context Properties |
| |
| public String getEncodedPath() { |
| return encodedPath; |
| } |
| |
| @Override |
| public void setName( String name ) { |
| super.setName( name ); |
| encodedPath = urlEncoder.encode(name); |
| } |
| |
| /** |
| * Is caching allowed ? |
| */ |
| public boolean isCachingAllowed() { |
| return cachingAllowed; |
| } |
| |
| /** |
| * Set caching allowed flag. |
| */ |
| public void setCachingAllowed(boolean cachingAllowed) { |
| this.cachingAllowed = cachingAllowed; |
| } |
| |
| /** |
| * Set case sensitivity. |
| */ |
| public void setCaseSensitive(boolean caseSensitive) { |
| this.caseSensitive = caseSensitive; |
| } |
| |
| /** |
| * Is case sensitive ? |
| */ |
| public boolean isCaseSensitive() { |
| return caseSensitive; |
| } |
| |
| // START SJSWS 6324431 |
| /** |
| * Set case sensitivity for filter and security constraint mappings. |
| */ |
| public void setCaseSensitiveMapping(boolean caseSensitiveMap) { |
| caseSensitiveMapping = caseSensitiveMap; |
| } |
| |
| /** |
| * Are filters and security constraints mapped in a case sensitive manner? |
| */ |
| public boolean isCaseSensitiveMapping() { |
| return caseSensitiveMapping; |
| } |
| // END SJSWS 6324431 |
| |
| /** |
| * Set allow linking. |
| */ |
| public void setAllowLinking(boolean allowLinking) { |
| this.allowLinking = allowLinking; |
| } |
| |
| /** |
| * Is linking allowed. |
| */ |
| public boolean isAllowLinking() { |
| return allowLinking; |
| } |
| |
| /** |
| * Set cache TTL. |
| */ |
| public void setCacheTTL(int cacheTTL) { |
| this.cacheTTL = cacheTTL; |
| } |
| |
| /** |
| * Get cache TTL. |
| */ |
| public int getCacheTTL() { |
| return cacheTTL; |
| } |
| |
| /** |
| * Return the maximum size of the cache in KB. |
| */ |
| public int getCacheMaxSize() { |
| return cacheMaxSize; |
| } |
| |
| /** |
| * Set the maximum size of the cache in KB. |
| */ |
| public void setCacheMaxSize(int cacheMaxSize) { |
| this.cacheMaxSize = cacheMaxSize; |
| } |
| |
| /** |
| * Return the "follow standard delegation model" flag used to configure |
| * our ClassLoader. |
| */ |
| public boolean getDelegate() { |
| return delegate; |
| } |
| |
| /** |
| * Set the "follow standard delegation model" flag used to configure |
| * our ClassLoader. |
| * |
| * @param delegate The new flag |
| */ |
| public void setDelegate(boolean delegate) { |
| boolean oldDelegate = this.delegate; |
| this.delegate = delegate; |
| support.firePropertyChange("delegate", Boolean.valueOf(oldDelegate), |
| Boolean.valueOf(this.delegate)); |
| } |
| |
| /** |
| * Returns true if the internal naming support is used. |
| */ |
| public boolean isUseNaming() { |
| synchronized (this) { |
| return useNaming; |
| } |
| } |
| |
| /** |
| * Enables or disables naming. |
| */ |
| public void setUseNaming(boolean useNaming) { |
| this.useNaming = useNaming; |
| } |
| |
| /** |
| * @return true if the resources associated with this context are |
| * filesystem based, false otherwise |
| */ |
| public boolean isFilesystemBased() { |
| return filesystemBased; |
| } |
| |
| /** |
| * @return the list of initialized application event listeners |
| * of this application, in the order in which they have been specified |
| * in the deployment descriptor |
| */ |
| @Override |
| public List<EventListener> getApplicationEventListeners() { |
| return eventListeners; |
| } |
| |
| public List<HttpSessionListener> getSessionListeners() { |
| return sessionListeners; |
| } |
| |
| /** |
| * Return the application available flag for this Context. |
| */ |
| @Override |
| public boolean getAvailable() { |
| return available; |
| } |
| |
| /** |
| * Set the application available flag for this Context. |
| * |
| * @param available The new application available flag |
| */ |
| @Override |
| public void setAvailable(boolean available) { |
| boolean oldAvailable = this.available; |
| this.available = available; |
| support.firePropertyChange("available", Boolean.valueOf(oldAvailable), |
| Boolean.valueOf(this.available)); |
| } |
| |
| /** |
| * Return the antiJARLocking flag for this Context. |
| */ |
| public boolean getAntiJARLocking() { |
| |
| return (this.antiJARLocking); |
| |
| } |
| |
| /** |
| * Set the antiJARLocking feature for this Context. |
| * |
| * @param antiJARLocking The new flag value |
| */ |
| public void setAntiJARLocking(boolean antiJARLocking) { |
| |
| boolean oldAntiJARLocking = this.antiJARLocking; |
| this.antiJARLocking = antiJARLocking; |
| support.firePropertyChange("antiJARLocking", |
| oldAntiJARLocking, |
| this.antiJARLocking); |
| |
| } |
| |
| /** |
| * Return the Locale to character set mapper for this Context. |
| */ |
| @Override |
| 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.newInstance(); |
| } catch (Throwable t) { |
| this.charsetMapper = new CharsetMapper(); |
| } |
| } |
| |
| return (this.charsetMapper); |
| } |
| |
| /** |
| * Set the Locale to character set mapper for this Context. |
| * |
| * @param mapper The new mapper |
| */ |
| @Override |
| public void setCharsetMapper(CharsetMapper mapper) { |
| CharsetMapper oldCharsetMapper = this.charsetMapper; |
| this.charsetMapper = mapper; |
| if( mapper != null ) |
| this.charsetMapperClass= mapper.getClass().getName(); |
| support.firePropertyChange("charsetMapper", oldCharsetMapper, |
| this.charsetMapper); |
| } |
| |
| @Override |
| public String getRequestCharacterEncoding() { |
| return this.requestCharacterEncoding; |
| } |
| |
| @Override |
| public void setRequestCharacterEncoding(String encoding) { |
| this.requestCharacterEncoding = encoding; |
| } |
| |
| @Override |
| public String getResponseCharacterEncoding() { |
| return this.responseCharacterEncoding; |
| } |
| |
| @Override |
| public void setResponseCharacterEncoding(String encoding) { |
| this.responseCharacterEncoding = encoding; |
| } |
| |
| /** |
| * @return the path to a file to save this Context information |
| */ |
| @Override |
| public String getConfigFile() { |
| return configFile; |
| } |
| |
| /** |
| * Set the path to a file to save this Context information. |
| * |
| * @param configFile The path to a file to save this Context information |
| */ |
| @Override |
| public void setConfigFile(String configFile) { |
| this.configFile = configFile; |
| } |
| |
| /** |
| * @return the "correctly configured" flag for this Context |
| */ |
| @Override |
| public boolean getConfigured() { |
| return configured; |
| } |
| |
| /** |
| * Sets 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 |
| public void setConfigured(boolean configured) { |
| boolean oldConfigured = this.configured; |
| this.configured = configured; |
| support.firePropertyChange("configured", |
| Boolean.valueOf(oldConfigured), Boolean.valueOf(this.configured)); |
| } |
| |
| /** |
| * @return the "use cookies for session ids" flag |
| */ |
| @Override |
| public boolean getCookies() { |
| return cookies; |
| } |
| |
| /** |
| * Set the "use cookies for session ids" flag. |
| * |
| * @param cookies The new flag |
| */ |
| @Override |
| public void setCookies(boolean cookies) { |
| boolean oldCookies = this.cookies; |
| this.cookies = cookies; |
| support.firePropertyChange("cookies", |
| Boolean.valueOf(oldCookies), |
| Boolean.valueOf(this.cookies)); |
| } |
| |
| /** |
| * Checks whether the rewriting of URLs with the jsessionids of |
| * HTTP sessions belonging to this context is enabled or not. |
| * |
| * @return true if the rewriting of URLs with the jsessionids of HTTP |
| * sessions belonging to this context is enabled, false otherwise |
| */ |
| @Override |
| public boolean isEnableURLRewriting() { |
| return enableURLRewriting; |
| } |
| |
| /** |
| * Enables or disables the rewriting of URLs with the jsessionids of |
| * HTTP sessions belonging to this context. |
| * |
| * @param enableURLRewriting true if the rewriting of URLs with the |
| * jsessionids of HTTP sessions belonging to this context should be |
| * enabled, false otherwise |
| */ |
| @Override |
| public void setEnableURLRewriting(boolean enableURLRewriting) { |
| boolean oldEnableURLRewriting = this.enableURLRewriting; |
| this.enableURLRewriting = enableURLRewriting; |
| support.firePropertyChange("enableURLRewriting", |
| Boolean.valueOf(oldEnableURLRewriting), |
| Boolean.valueOf(this.enableURLRewriting)); |
| } |
| |
| |
| /** |
| * @return the "allow crossing servlet contexts" flag |
| */ |
| @Override |
| public boolean getCrossContext() { |
| return (this.crossContext); |
| } |
| |
| /** |
| * Sets the "allow crossing servlet contexts" flag. |
| * |
| * @param crossContext The new cross contexts flag |
| */ |
| @Override |
| public void setCrossContext(boolean crossContext) { |
| |
| boolean oldCrossContext = this.crossContext; |
| this.crossContext = crossContext; |
| support.firePropertyChange("crossContext", |
| Boolean.valueOf(oldCrossContext), |
| Boolean.valueOf(this.crossContext)); |
| } |
| |
| 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 ). |
| * |
| * XXX If a file is not found - we can attempt a getResource() |
| * |
| * @param defaultWebXml |
| */ |
| public void 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. |
| */ |
| public long getStartupTime() { |
| return startupTime; |
| } |
| |
| public void setStartupTime(long startupTime) { |
| this.startupTime = startupTime; |
| } |
| |
| public long getTldScanTime() { |
| return tldScanTime; |
| } |
| |
| public void setTldScanTime(long tldScanTime) { |
| this.tldScanTime = tldScanTime; |
| } |
| |
| /** |
| * Return the display name of this web application. |
| */ |
| @Override |
| public String getDisplayName() { |
| |
| return (this.displayName); |
| |
| } |
| |
| /** |
| * Return the alternate Deployment Descriptor name. |
| */ |
| @Override |
| public String getAltDDName(){ |
| return altDDName; |
| } |
| |
| /** |
| * Set an alternate Deployment Descriptor name. |
| */ |
| @Override |
| public void setAltDDName(String altDDName) { |
| this.altDDName = altDDName; |
| if (context != null) { |
| context.setAttribute(Globals.ALT_DD_ATTR,altDDName); |
| context.setAttributeReadOnly(Globals.ALT_DD_ATTR); |
| } |
| } |
| |
| /** |
| * Return the compiler classpath. |
| */ |
| public String getCompilerClasspath(){ |
| return compilerClasspath; |
| } |
| |
| /** |
| * Set the compiler classpath. |
| */ |
| public void setCompilerClasspath(String compilerClasspath) { |
| this.compilerClasspath = compilerClasspath; |
| } |
| |
| /** |
| * Set the display name of this web application. |
| * |
| * @param displayName The new display name |
| */ |
| @Override |
| public void setDisplayName(String displayName) { |
| String oldDisplayName = this.displayName; |
| this.displayName = displayName; |
| support.firePropertyChange("displayName", oldDisplayName, |
| this.displayName); |
| } |
| |
| /** |
| * Return the distributable flag for this web application. |
| */ |
| @Override |
| public boolean getDistributable() { |
| return distributable; |
| } |
| |
| /** |
| * Set the distributable flag for this web application. |
| * |
| * @param distributable The new distributable flag |
| */ |
| @Override |
| public void setDistributable(boolean distributable) { |
| boolean oldDistributable = this.distributable; |
| this.distributable = distributable; |
| support.firePropertyChange("distributable", |
| Boolean.valueOf(oldDistributable), |
| Boolean.valueOf(this.distributable)); |
| |
| // Bugzilla 32866 |
| if(getManager() != null) { |
| if(log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Propagating distributable=" + distributable |
| + " to manager"); |
| } |
| getManager().setDistributable(distributable); |
| } |
| } |
| |
| /** |
| * Return the document root for this Context. This can be an absolute |
| * pathname, a relative pathname, or a URL. |
| */ |
| @Override |
| public String getDocBase() { |
| return docBase; |
| } |
| |
| /** |
| * Set the document root for this Context. This can be an absolute |
| * pathname, a relative pathname, or a URL. |
| * |
| * @param docBase The new document root |
| */ |
| @Override |
| public void setDocBase(String docBase) { |
| synchronized (this) { |
| this.docBase = docBase; |
| } |
| } |
| |
| /** |
| * Configures this context's alternate doc base mappings. |
| * |
| * @param urlPattern |
| * @param docBase |
| */ |
| public void addAlternateDocBase(String urlPattern, String docBase) { |
| |
| if (urlPattern == null || docBase == null) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.MISS_PATH_OR_URL_PATTERN_EXCEPTION)); |
| } |
| |
| AlternateDocBase alternateDocBase = new AlternateDocBase(); |
| alternateDocBase.setUrlPattern(urlPattern); |
| alternateDocBase.setDocBase(docBase); |
| alternateDocBase.setBasePath(getBasePath(docBase)); |
| |
| if (alternateDocBases == null) { |
| alternateDocBases = new ArrayList<AlternateDocBase>(); |
| } |
| alternateDocBases.add(alternateDocBase); |
| } |
| |
| /** |
| * Gets this context's configured alternate doc bases. |
| * |
| * @return This context's configured alternate doc bases |
| */ |
| public ArrayList<AlternateDocBase> getAlternateDocBases() { |
| return alternateDocBases; |
| } |
| |
| /** |
| * Return the frequency of manager checks. |
| */ |
| public int getManagerChecksFrequency() { |
| return managerChecksFrequency; |
| } |
| |
| /** |
| * Set the manager checks frequency. |
| * |
| * @param managerChecksFrequency the new manager checks frequency |
| */ |
| public void setManagerChecksFrequency(int managerChecksFrequency) { |
| |
| if (managerChecksFrequency <= 0) { |
| return; |
| } |
| |
| int oldManagerChecksFrequency = this.managerChecksFrequency; |
| this.managerChecksFrequency = managerChecksFrequency; |
| support.firePropertyChange("managerChecksFrequency", |
| Integer.valueOf(oldManagerChecksFrequency), |
| Integer.valueOf(this.managerChecksFrequency)); |
| } |
| |
| /** |
| * Return descriptive information about this Container implementation and |
| * the corresponding version number, in the format |
| * <code><description>/<version></code>. |
| */ |
| @Override |
| public String getInfo() { |
| return (info); |
| } |
| |
| public void setJvmRoute(String jvmRoute) { |
| this.jvmRoute = jvmRoute; |
| } |
| |
| public String getJvmRoute() { |
| return jvmRoute; |
| } |
| |
| public String getEngineName() { |
| if( engineName != null ) return engineName; |
| return domain; |
| } |
| |
| public void setEngineName(String engineName) { |
| this.engineName = engineName; |
| } |
| |
| public String getJ2EEApplication() { |
| return j2EEApplication; |
| } |
| |
| public void setJ2EEApplication(String j2EEApplication) { |
| this.j2EEApplication = j2EEApplication; |
| } |
| |
| public String getJ2EEServer() { |
| return j2EEServer; |
| } |
| |
| public void setJ2EEServer(String j2EEServer) { |
| this.j2EEServer = j2EEServer; |
| } |
| |
| /** |
| * Return the login configuration descriptor for this web application. |
| */ |
| @Override |
| public LoginConfig getLoginConfig() { |
| return (this.loginConfig); |
| } |
| |
| /** |
| * Set the login configuration descriptor for this web application. |
| * |
| * @param config The new login configuration |
| */ |
| @Override |
| public void setLoginConfig(LoginConfig config) { |
| |
| // Validate the incoming property value |
| if (config == null) |
| throw new IllegalArgumentException |
| (rb.getString(LogFacade.LOGIN_CONFIG_REQUIRED_EXCEPTION)); |
| String loginPage = config.getLoginPage(); |
| if ((loginPage != null) && !loginPage.startsWith("/")) { |
| if (isServlet22()) { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, LogFacade.FORM_LOGIN_PAGE_FINE, loginPage); |
| } |
| config.setLoginPage("/" + loginPage); |
| } else { |
| String msg = MessageFormat.format(rb.getString(LogFacade.LOGIN_CONFIG_LOGIN_PAGE_EXCEPTION), loginPage); |
| throw new IllegalArgumentException(msg); |
| } |
| } |
| String errorPage = config.getErrorPage(); |
| if ((errorPage != null) && !errorPage.startsWith("/")) { |
| if (isServlet22()) { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, LogFacade.FORM_ERROR_PAGE_FINE, errorPage); |
| } |
| config.setErrorPage("/" + errorPage); |
| } else { |
| String msg = MessageFormat.format(rb.getString(LogFacade.LOGIN_CONFIG_ERROR_PAGE_EXCEPTION), errorPage); |
| throw new IllegalArgumentException(msg); |
| } |
| } |
| |
| // Process the property setting change |
| LoginConfig oldLoginConfig = this.loginConfig; |
| this.loginConfig = config; |
| support.firePropertyChange("loginConfig", |
| oldLoginConfig, this.loginConfig); |
| } |
| |
| /** |
| * Get the mapper associated with the context. |
| */ |
| @Override |
| public Mapper getMapper() { |
| return mapper; |
| } |
| |
| /** |
| * Sets a new pipeline |
| */ |
| public void restrictedSetPipeline(Pipeline pl) { |
| synchronized (this) { |
| pl.setBasic(new StandardContextValve()); |
| pipeline = pl; |
| hasCustomPipeline = true; |
| } |
| } |
| |
| /** |
| * Return the naming resources associated with this web application. |
| */ |
| @Override |
| public NamingResources getNamingResources() { |
| return namingResources; |
| } |
| |
| /** |
| * Set the naming resources for this web application. |
| * |
| * @param namingResources The new naming resources |
| */ |
| @Override |
| public void setNamingResources(NamingResources namingResources) { |
| |
| // Process the property setting change |
| NamingResources oldNamingResources = this.namingResources; |
| this.namingResources = namingResources; |
| support.firePropertyChange("namingResources", |
| oldNamingResources, this.namingResources); |
| } |
| |
| /** |
| * Return the context path for this Context. |
| */ |
| @Override |
| public String getPath() { |
| return (getName()); |
| } |
| |
| /** |
| * Set the context path for this Context. |
| * <p> |
| * <b>IMPLEMENTATION NOTE</b>: The context path is used as the "name" of |
| * a Context, because it must be unique. |
| * |
| * @param path The new context path |
| */ |
| @Override |
| public void setPath(String path) { |
| // XXX Use host in name |
| /* GlassFish Issue 2339 |
| setName(RequestUtil.URLDecode(path)); |
| */ |
| // START GlassFish Issue 2339 |
| setName(RequestUtil.urlDecode(path, "UTF-8")); |
| // END GlassFish Issue 2339 |
| } |
| |
| /** |
| * Return the public identifier of the deployment descriptor DTD that is |
| * currently being parsed. |
| */ |
| @Override |
| public String getPublicId() { |
| return publicId; |
| } |
| |
| /** |
| * Set the public identifier of the deployment descriptor DTD that is |
| * currently being parsed. |
| * |
| * @param publicId The public identifier |
| */ |
| @Override |
| public void setPublicId(String publicId) { |
| if (log.isLoggable(Level.FINEST)) |
| log.log(Level.FINEST, "Setting deployment descriptor public ID to '" + |
| publicId + "'"); |
| |
| String oldPublicId = this.publicId; |
| this.publicId = publicId; |
| support.firePropertyChange("publicId", oldPublicId, publicId); |
| } |
| |
| /** |
| * Return the reloadable flag for this web application. |
| */ |
| @Override |
| public boolean getReloadable() { |
| return reloadable; |
| } |
| |
| /** |
| * Return the DefaultContext override flag for this web application. |
| */ |
| @Override |
| public boolean getOverride() { |
| return override; |
| } |
| |
| /** |
| * Gets the original document root for this Context, which can be an |
| * absolute pathname, a relative pathname, or a URL. |
| * |
| * Is only set as deployment has change docRoot! |
| */ |
| public String getOriginalDocBase() { |
| return (this.originalDocBase); |
| } |
| |
| /** |
| * Set the original document root for this Context, which can be an |
| * absolute pathname, a relative pathname, or a URL. |
| * |
| * @param docBase The original document root |
| */ |
| public void setOriginalDocBase(String docBase) { |
| this.originalDocBase = docBase; |
| } |
| |
| /** |
| * Return the privileged flag for this web application. |
| */ |
| @Override |
| public boolean getPrivileged() { |
| return (this.privileged); |
| } |
| |
| /** |
| * Set the privileged flag for this web application. |
| * |
| * @param privileged The new privileged flag |
| */ |
| @Override |
| public void setPrivileged(boolean privileged) { |
| boolean oldPrivileged = this.privileged; |
| this.privileged = privileged; |
| support.firePropertyChange("privileged", |
| Boolean.valueOf(oldPrivileged), |
| Boolean.valueOf(this.privileged)); |
| } |
| |
| /** |
| * Set the reloadable flag for this web application. |
| * |
| * @param reloadable The new reloadable flag |
| */ |
| @Override |
| public void setReloadable(boolean reloadable) { |
| boolean oldReloadable = this.reloadable; |
| this.reloadable = reloadable; |
| support.firePropertyChange("reloadable", |
| Boolean.valueOf(oldReloadable), |
| Boolean.valueOf(this.reloadable)); |
| } |
| |
| /** |
| * Set the DefaultContext override flag for this web application. |
| * |
| * @param override The new override flag |
| */ |
| @Override |
| public void setOverride(boolean override) { |
| boolean oldOverride = this.override; |
| this.override = override; |
| support.firePropertyChange("override", |
| Boolean.valueOf(oldOverride), |
| Boolean.valueOf(this.override)); |
| } |
| |
| // START SJSAS 8.1 5049111 |
| /** |
| * Scan the parent when searching for TLD listeners. |
| */ |
| @Override |
| public boolean isJsfApplication(){ |
| return isJsfApplication; |
| } |
| // END SJSAS 8.1 5049111 |
| |
| |
| // START SJSAS 6253524 |
| /** |
| * Indicates whether this web module contains any ad-hoc paths. |
| * |
| * An ad-hoc path is a servlet path that is mapped to a servlet |
| * not declared in the web module's deployment descriptor. |
| * |
| * A web module all of whose mappings are for ad-hoc paths is called an |
| * ad-hoc web module. |
| * |
| * @return true if this web module contains any ad-hoc paths, false |
| * otherwise |
| */ |
| @Override |
| public boolean hasAdHocPaths() { |
| return false; |
| } |
| |
| /** |
| * Returns the name of the ad-hoc servlet responsible for servicing the |
| * given path. |
| * |
| * @param path The path to service |
| * |
| * @return The name of the ad-hoc servlet responsible for servicing the |
| * given path, or null if the given path is not an ad-hoc path |
| */ |
| @Override |
| public String getAdHocServletName(String path) { |
| return null; |
| } |
| // END SJSAS 6253524 |
| |
| /** |
| * Return the "replace welcome files" property. |
| */ |
| public boolean isReplaceWelcomeFiles() { |
| return replaceWelcomeFiles; |
| } |
| |
| /** |
| * Set the "replace welcome files" property. |
| * |
| * @param replaceWelcomeFiles The new property value |
| */ |
| public void setReplaceWelcomeFiles(boolean replaceWelcomeFiles) { |
| |
| boolean oldReplaceWelcomeFiles = this.replaceWelcomeFiles; |
| this.replaceWelcomeFiles = replaceWelcomeFiles; |
| support.firePropertyChange("replaceWelcomeFiles", |
| Boolean.valueOf(oldReplaceWelcomeFiles), |
| Boolean.valueOf(this.replaceWelcomeFiles)); |
| } |
| |
| /** |
| * Returns the value of the securePagesWithPragma property. |
| */ |
| public boolean isSecurePagesWithPragma() { |
| return securePagesWithPragma; |
| } |
| |
| /** |
| * Sets the securePagesWithPragma property of this Context. |
| * |
| * Setting this property to true will result in Pragma and Cache-Control |
| * headers with a value of "No-cache" if proxy caching has been disabled. |
| * |
| * Setting this property to false will not add any Pragma header, |
| * but will set the Cache-Control header to "private". |
| * |
| * @param securePagesWithPragma true if Pragma and Cache-Control headers |
| * are to be set to "No-cache" if proxy caching has been disabled, false |
| * otherwise |
| */ |
| @Override |
| public void setSecurePagesWithPragma(boolean securePagesWithPragma) { |
| |
| boolean oldSecurePagesWithPragma = this.securePagesWithPragma; |
| this.securePagesWithPragma = securePagesWithPragma; |
| support.firePropertyChange("securePagesWithPragma", |
| Boolean.valueOf(oldSecurePagesWithPragma), |
| Boolean.valueOf(this.securePagesWithPragma)); |
| } |
| |
| public void setUseMyFaces(boolean useMyFaces) { |
| this.useMyFaces = useMyFaces; |
| } |
| |
| public boolean isUseMyFaces() { |
| return useMyFaces; |
| } |
| |
| /** |
| * Return the servlet context for which this Context is a facade. |
| */ |
| @Override |
| public ServletContext getServletContext() { |
| if (context == null) { |
| context = new ApplicationContext(this); |
| if (altDDName != null |
| && context.getAttribute(Globals.ALT_DD_ATTR) == null){ |
| context.setAttribute(Globals.ALT_DD_ATTR,altDDName); |
| context.setAttributeReadOnly(Globals.ALT_DD_ATTR); |
| } |
| } |
| |
| return context.getFacade(); |
| } |
| |
| /** |
| * Return the default session timeout (in minutes) for this |
| * web application. |
| */ |
| @Override |
| public int getSessionTimeout() { |
| return sessionTimeout; |
| } |
| |
| /** |
| * Is the session timeout (in minutes) for this |
| * web application over-ridden from the default |
| * HERCULES:add |
| */ |
| public boolean isSessionTimeoutOveridden() { |
| return sessionTimeoutOveridden; |
| } |
| |
| /** |
| * Set the default session timeout (in minutes) for this |
| * web application. |
| * |
| * @param timeout The new default session timeout |
| */ |
| @Override |
| public void setSessionTimeout(int timeout) { |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"setSessionTimeout", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| int oldSessionTimeout = this.sessionTimeout; |
| |
| /* |
| * SRV.13.4 ("Deployment Descriptor"): |
| * If the timeout is 0 or less, the container ensures the default |
| * behaviour of sessions is never to time out. |
| */ |
| this.sessionTimeout = (timeout == 0) ? -1 : timeout; |
| support.firePropertyChange("sessionTimeout", |
| Integer.valueOf(oldSessionTimeout), |
| Integer.valueOf(this.sessionTimeout)); |
| //HERCULES:add |
| sessionTimeoutOveridden = true; |
| //end HERCULES:add |
| } |
| |
| /** |
| * Return the value of the unloadDelay flag. |
| */ |
| public long getUnloadDelay() { |
| |
| return (this.unloadDelay); |
| |
| } |
| |
| /** |
| * Set the value of the unloadDelay flag, which represents the amount |
| * of ms that the container will wait when unloading servlets. |
| * Setting this to a small value may cause more requests to fail |
| * to complete when stopping a web application. |
| * |
| * @param unloadDelay The new value |
| */ |
| public void setUnloadDelay(long unloadDelay) { |
| |
| long oldUnloadDelay = this.unloadDelay; |
| this.unloadDelay = unloadDelay; |
| support.firePropertyChange("unloadDelay", |
| Long.valueOf(oldUnloadDelay), |
| Long.valueOf(this.unloadDelay)); |
| |
| } |
| |
| /** |
| * Unpack WAR flag accessor. |
| */ |
| public boolean getUnpackWAR() { |
| return unpackWAR; |
| } |
| |
| /** |
| * Unpack WAR flag mutator. |
| */ |
| public void setUnpackWAR(boolean unpackWAR) { |
| this.unpackWAR = unpackWAR; |
| } |
| |
| /** |
| * Set the resources DirContext object with which this Container is |
| * associated. |
| * |
| * @param resources The newly associated DirContext |
| */ |
| @Override |
| public synchronized void setResources(DirContext resources) { |
| |
| if (started) { |
| throw new IllegalStateException(rb.getString(LogFacade.RESOURCES_STARTED)); |
| } |
| |
| DirContext oldResources = this.webappResources; |
| if (oldResources == resources) |
| return; |
| |
| if (resources instanceof BaseDirContext) { |
| BaseDirContext baseDirContext = (BaseDirContext)resources; |
| baseDirContext.setCached(isCachingAllowed()); |
| baseDirContext.setCacheTTL(getCacheTTL()); |
| baseDirContext.setCacheMaxSize(getCacheMaxSize()); |
| } |
| if (resources instanceof FileDirContext) { |
| filesystemBased = true; |
| FileDirContext fileDirContext = (FileDirContext)resources; |
| fileDirContext.setCaseSensitive(isCaseSensitive()); |
| fileDirContext.setAllowLinking(isAllowLinking()); |
| } |
| this.webappResources = resources; |
| |
| // The proxied resources will be refreshed on start |
| this.resources = null; |
| |
| support.firePropertyChange("resources", oldResources, |
| this.webappResources); |
| |
| } |
| |
| private synchronized void setAlternateResources( |
| AlternateDocBase alternateDocBase, |
| DirContext resources) { |
| |
| if (started) { |
| throw new IllegalStateException(rb.getString(LogFacade.RESOURCES_STARTED)); |
| } |
| |
| final DirContext oldResources = ContextsAdapterUtility.unwrap( |
| alternateDocBase.getWebappResources()); |
| |
| if (oldResources == resources) |
| return; |
| |
| if (resources instanceof BaseDirContext) { |
| ((BaseDirContext) resources).setCached(isCachingAllowed()); |
| ((BaseDirContext) resources).setCacheTTL(getCacheTTL()); |
| ((BaseDirContext) resources).setCacheMaxSize(getCacheMaxSize()); |
| } |
| if (resources instanceof FileDirContext) { |
| filesystemBased = true; |
| ((FileDirContext) resources).setCaseSensitive(isCaseSensitive()); |
| ((FileDirContext) resources).setAllowLinking(isAllowLinking()); |
| } |
| alternateDocBase.setWebappResources(ContextsAdapterUtility.wrap(resources)); |
| // The proxied resources will be refreshed on start |
| alternateDocBase.setResources(null); |
| } |
| |
| // START S1AS8PE 4817642 |
| /** |
| * Return the "reuse session IDs when creating sessions" flag |
| */ |
| @Override |
| public boolean getReuseSessionID() { |
| return reuseSessionID; |
| } |
| |
| /** |
| * Set the "reuse session IDs when creating sessions" flag |
| * |
| * @param reuse The new value for the flag |
| */ |
| @Override |
| public void setReuseSessionID(boolean reuse) { |
| reuseSessionID = reuse; |
| } |
| // END S1AS8PE 4817642 |
| |
| |
| |
| // START RIMOD 4642650 |
| /** |
| * Return whether this context allows sendRedirect() to redirect |
| * to a relative URL. |
| * |
| * The default value for this property is 'false'. |
| */ |
| @Override |
| public boolean getAllowRelativeRedirect() { |
| |
| return allowRelativeRedirect; |
| |
| } |
| |
| |
| /** |
| * Set whether this context allows sendRedirect() to redirect |
| * to a relative URL. |
| * |
| * @param allowRelativeURLs The new value for this property. |
| * The default value for this property is |
| * 'false'. |
| */ |
| @Override |
| public void setAllowRelativeRedirect(boolean allowRelativeURLs) { |
| |
| allowRelativeRedirect = allowRelativeURLs; |
| |
| } |
| |
| |
| // END RIMOD 4642650 |
| |
| // START IASRI 4823322 |
| /** |
| * Get Auditors associated with this context, if any. |
| * |
| * @return array of Auditor objects, or null |
| * |
| */ |
| @Override |
| public Auditor[] getAuditors() { |
| return auditors; |
| } |
| |
| |
| /** |
| * Set the Auditors associated with this context. |
| * |
| * @param auditor array of Auditor objects |
| * |
| */ |
| @Override |
| public void setAuditors(Auditor[] auditor) { |
| this.auditors=auditor; |
| } |
| // END IASRI 4823322 |
| |
| |
| // START S1AS8PE 4965017 |
| public void setReload(boolean isReload) { |
| this.isReload = isReload; |
| } |
| |
| public boolean isReload() { |
| return isReload; |
| } |
| // END S1AS8PE 4965017 |
| |
| public void setEmbedded(boolean isEmbedded) { |
| this.isEmbedded = isEmbedded; |
| } |
| |
| public boolean isEmbedded() { |
| return isEmbedded; |
| } |
| |
| /** |
| * Should we generate directory listings? |
| */ |
| protected boolean directoryListing = false; |
| |
| /** |
| * Enables or disables directory listings on this <tt>Context</tt>. |
| */ |
| public void setDirectoryListing(boolean directoryListing) { |
| this.directoryListing = directoryListing; |
| Wrapper wrapper = (Wrapper) findChild( |
| org.apache.catalina.core.Constants.DEFAULT_SERVLET_NAME); |
| if (wrapper !=null) { |
| Servlet servlet = ((StandardWrapper)wrapper).getServlet(); |
| if (servlet instanceof DefaultServlet) { |
| ((DefaultServlet)servlet).setListings(directoryListing); |
| } |
| } |
| } |
| |
| /** |
| * Checks whether directory listings are enabled or disabled on this |
| * <tt>Context</tt>. |
| */ |
| public boolean isDirectoryListing() { |
| return directoryListing; |
| } |
| |
| // ------------------------------------------------------ Public Properties |
| |
| |
| /** |
| * Return the Locale to character set mapper class for this Context. |
| */ |
| public String getCharsetMapperClass() { |
| |
| return (this.charsetMapperClass); |
| |
| } |
| |
| |
| /** |
| * Set the Locale to character set mapper class for this Context. |
| * |
| * @param mapper The new mapper class |
| */ |
| public void setCharsetMapperClass(String mapper) { |
| |
| String oldCharsetMapperClass = this.charsetMapperClass; |
| this.charsetMapperClass = mapper; |
| support.firePropertyChange("charsetMapperClass", |
| oldCharsetMapperClass, |
| this.charsetMapperClass); |
| |
| } |
| |
| |
| /** |
| * Get the absolute path to the work dir. |
| * |
| * @return the absolute path to the work dir |
| */ |
| public String getWorkPath() { |
| if (getWorkDir() == null) { |
| return null; |
| } |
| File workDir = new File(getWorkDir()); |
| if (!workDir.isAbsolute()) { |
| File catalinaHome = engineBase(); |
| String catalinaHomePath = null; |
| try { |
| catalinaHomePath = catalinaHome.getCanonicalPath(); |
| workDir = new File(catalinaHomePath, |
| getWorkDir()); |
| } catch (IOException e) { |
| } |
| } |
| return workDir.getAbsolutePath(); |
| } |
| |
| /** |
| * Return the work directory for this Context. |
| */ |
| public String getWorkDir() { |
| |
| return (this.workDir); |
| |
| } |
| |
| |
| /** |
| * Set the work directory for this Context. |
| * |
| * @param workDir The new work directory |
| */ |
| public void setWorkDir(String workDir) { |
| synchronized (this) { |
| this.workDir = workDir; |
| if (started) { |
| postWorkDirectory(); |
| } |
| } |
| } |
| |
| |
| // -------------------------------------------------------- Context Methods |
| |
| |
| /** |
| * Adds the Listener with the given class name that is declared in the |
| * deployment descriptor to the set of Listeners configured for this |
| * application. |
| * |
| * @param listener the fully qualified class name of the Listener |
| */ |
| public void addApplicationListener(String listener) { |
| addListener(listener, false); |
| } |
| |
| /** |
| * Add a new application parameter for this application. |
| * |
| * @param parameter The new application parameter |
| */ |
| public void addApplicationParameter(ApplicationParameter parameter) { |
| String newName = parameter.getName(); |
| Iterator<ApplicationParameter> i = |
| applicationParameters.iterator(); |
| while (i.hasNext()) { |
| ApplicationParameter applicationParameter = i.next(); |
| if (newName.equals(applicationParameter.getName())) { |
| if (applicationParameter.getOverride()) { |
| applicationParameter.setValue(parameter.getValue()); |
| } |
| return; |
| } |
| } |
| |
| applicationParameters.add(parameter); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addApplicationParameter", parameter); |
| } |
| } |
| |
| /** |
| * Adds the given child Container to this context. |
| * |
| * @param child the child Container to add |
| * |
| * @exception IllegalArgumentException if the given child Container is |
| * not an instance of Wrapper |
| */ |
| @Override |
| public void addChild(Container child) { |
| addChild(child, false, true); |
| } |
| |
| /** |
| * Adds the given child (Servlet) to this context. |
| * |
| * @param child the child (Servlet) to add |
| * @param isProgrammatic true if the given child (Servlet) is being |
| * added via one of the programmatic interfaces, and false if it is |
| * declared in the deployment descriptor |
| * @param createRegistration true if a ServletRegistration needs to be |
| * created for the given child, and false if a (preliminary) |
| * ServletRegistration had already been created (which would be the |
| * case if the Servlet had been declared in the deployment descriptor |
| * without any servlet-class, and the servlet-class was later provided |
| * via ServletContext#addServlet) |
| * |
| * @exception IllegalArgumentException if the given child Container is |
| * not an instance of Wrapper |
| */ |
| protected void addChild(Container child, boolean isProgrammatic, |
| boolean createRegistration) { |
| |
| if (!(child instanceof Wrapper)) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NO_WRAPPER_EXCEPTION)); |
| } |
| |
| Wrapper wrapper = (Wrapper) child; |
| String wrapperName = child.getName(); |
| |
| if (createRegistration) { |
| ServletRegistrationImpl regis = null; |
| if (isProgrammatic || |
| (null == wrapper.getServletClassName() && |
| null == wrapper.getJspFile())) { |
| regis = createDynamicServletRegistrationImpl( |
| (StandardWrapper) wrapper); |
| } else { |
| regis = createServletRegistrationImpl( |
| (StandardWrapper) wrapper); |
| } |
| servletRegisMap.put(wrapperName, regis); |
| if (null == wrapper.getServletClassName() && |
| null == wrapper.getJspFile()) { |
| /* |
| * Preliminary registration for Servlet that was declared |
| * without any servlet-class. Once the registration is |
| * completed via ServletContext#addServlet, addChild will |
| * be called again, and 'wrapper' will have been configured |
| * with a proper class name at that time |
| */ |
| return; |
| } |
| } |
| |
| if ("jakarta.faces.webapp.FacesServlet".equals( |
| wrapper.getServletClassName())) { |
| isJsfApplication = true; |
| } |
| |
| // Global JspServlet |
| Wrapper oldJspServlet = null; |
| |
| // Allow webapp to override JspServlet inherited from global web.xml. |
| boolean isJspServlet = "jsp".equals(wrapperName); |
| if (isJspServlet) { |
| oldJspServlet = (Wrapper) findChild("jsp"); |
| if (oldJspServlet != null) { |
| removeChild(oldJspServlet); |
| } |
| } |
| |
| String jspFile = wrapper.getJspFile(); |
| if ((jspFile != null) && !jspFile.startsWith("/")) { |
| if (isServlet22()) { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, LogFacade.JSP_FILE_FINE, jspFile); |
| } |
| wrapper.setJspFile("/" + jspFile); |
| } else { |
| String msg = MessageFormat.format(rb.getString(LogFacade.WRAPPER_ERROR_EXCEPTION), jspFile); |
| throw new IllegalArgumentException(msg); |
| } |
| } |
| |
| super.addChild(child); |
| |
| // START SJSAS 6342808 |
| /* SJSWS 6362207 |
| if (started) { |
| */ |
| // START SJSWS 6362207 |
| if (getAvailable()) { |
| // END SJSWS 6362207 |
| /* |
| * If this StandardContext has already been started, we need to |
| * register the newly added child with JMX. Any children that were |
| * added before this StandardContext was started have already been |
| * registered with JMX (as part of StandardContext.start()). |
| */ |
| if (wrapper instanceof StandardWrapper) { |
| ((StandardWrapper) wrapper).registerJMX( this ); |
| } |
| } |
| // END SJSAS 6342808 |
| |
| if (isJspServlet && oldJspServlet != null) { |
| /* |
| * The webapp-specific JspServlet inherits all the mappings |
| * specified in the global web.xml, and may add additional ones. |
| */ |
| String[] jspMappings = oldJspServlet.findMappings(); |
| for (int i=0; jspMappings!=null && i<jspMappings.length; i++) { |
| addServletMapping(jspMappings[i], wrapperName); |
| } |
| } |
| } |
| |
| protected ServletRegistrationImpl createServletRegistrationImpl( |
| StandardWrapper wrapper) { |
| return new ServletRegistrationImpl(wrapper, this); |
| } |
| |
| protected ServletRegistrationImpl createDynamicServletRegistrationImpl( |
| StandardWrapper wrapper) { |
| return new DynamicServletRegistrationImpl(wrapper, this); |
| } |
| |
| /** |
| * Add a security constraint to the set for this web application. |
| */ |
| @Override |
| public void addConstraint(SecurityConstraint constraint) { |
| |
| // Validate the proposed constraint |
| SecurityCollection collections[] = constraint.findCollections(); |
| for(SecurityCollection collection : collections) { |
| String patterns[] = collection.findPatterns(); |
| for(int j = 0; j < patterns.length; j++) { |
| patterns[j] = adjustURLPattern(patterns[j]); |
| if(!validateURLPattern(patterns[j])) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SECURITY_CONSTRAINT_PATTERN_EXCEPTION), |
| patterns[j]); |
| throw new IllegalArgumentException(msg); |
| } |
| } |
| } |
| |
| // Add this constraint to the set for our web application |
| constraints.add(constraint); |
| } |
| |
| /** |
| * Add an EJB resource reference for this web application. |
| * |
| * @param ejb New EJB resource reference |
| */ |
| public void addEjb(ContextEjb ejb) { |
| namingResources.addEjb(ejb); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addEjb", ejb.getName()); |
| } |
| } |
| |
| /** |
| * Add an environment entry for this web application. |
| * |
| * @param environment New environment entry |
| */ |
| public void addEnvironment(ContextEnvironment environment) { |
| |
| ContextEnvironment env = findEnvironment(environment.getName()); |
| if ((env != null) && !env.getOverride()) |
| return; |
| namingResources.addEnvironment(environment); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addEnvironment", environment.getName()); |
| } |
| } |
| |
| |
| /** |
| * Add resource parameters for this web application. |
| * |
| * @param resourceParameters New resource parameters |
| */ |
| public void addResourceParams(ResourceParams resourceParameters) { |
| namingResources.addResourceParams(resourceParameters); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addResourceParams", |
| resourceParameters.getName()); |
| } |
| } |
| |
| /** |
| * Add an error page for the specified error or Java exception. |
| * |
| * @param errorPage The error page definition to be added |
| */ |
| @Override |
| public void addErrorPage(ErrorPage errorPage) { |
| // Validate the input parameters |
| if (errorPage == null) |
| throw new IllegalArgumentException |
| (rb.getString(LogFacade.ERROR_PAGE_REQUIRED_EXCEPTION)); |
| String location = errorPage.getLocation(); |
| if ((location != null) && !location.startsWith("/")) { |
| if (isServlet22()) { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, LogFacade.ERROR_PAGE_LOCATION_EXCEPTION); |
| } |
| errorPage.setLocation("/" + location); |
| } else { |
| String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_PAGE_LOCATION_EXCEPTION), location); |
| throw new IllegalArgumentException(msg); |
| } |
| } |
| |
| // Add the specified error page to our internal collections |
| String exceptionType = errorPage.getExceptionType(); |
| if (exceptionType != null) { |
| synchronized (exceptionPages) { |
| exceptionPages.put(exceptionType, errorPage); |
| } |
| } else if (errorPage.getErrorCode() > 0) { |
| synchronized (statusPages) { |
| int errorCode = errorPage.getErrorCode(); |
| if ((errorCode >= 400) && (errorCode < 600)) { |
| statusPages.put(errorCode, errorPage); |
| } else { |
| log.log(Level.SEVERE, LogFacade.INVALID_ERROR_PAGE_CODE_EXCEPTION, errorCode); |
| } |
| } |
| } else { |
| defaultErrorPage = errorPage; |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addErrorPage", errorPage); |
| } |
| } |
| |
| /** |
| * Add a filter definition to this Context. |
| * |
| * @param filterDef The filter definition to be added |
| */ |
| public void addFilterDef(FilterDef filterDef) { |
| addFilterDef(filterDef, false, true); |
| } |
| |
| public void addFilterDef(FilterDef filterDef, boolean isProgrammatic, |
| boolean createRegistration) { |
| if (createRegistration) { |
| FilterRegistrationImpl regis = null; |
| if (isProgrammatic || null == filterDef.getFilterClassName()) { |
| regis = new DynamicFilterRegistrationImpl(filterDef, this); |
| } else { |
| regis = new FilterRegistrationImpl(filterDef, this); |
| } |
| filterRegisMap.put(filterDef.getFilterName(), regis); |
| if (null == filterDef.getFilterClassName()) { |
| /* |
| * Preliminary registration for Filter that was declared |
| * without any filter-class. Once the registration is |
| * completed via ServletContext#addFilter, addFilterDef will |
| * be called again, and 'filterDef' will have been configured |
| * with a proper class name at that time |
| */ |
| return; |
| } |
| } |
| |
| synchronized (filterDefs) { |
| filterDefs.put(filterDef.getFilterName(), filterDef); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addFilterDef", filterDef); |
| } |
| } |
| |
| /** |
| * Add multiple filter mappings to this Context. |
| * |
| * @param filterMaps The filter mappings to be added |
| * |
| * @exception IllegalArgumentException if the specified filter name |
| * does not match an existing filter definition, or the filter mapping |
| * is malformed |
| */ |
| public void addFilterMaps(FilterMaps filterMaps) { |
| String[] servletNames = filterMaps.getServletNames(); |
| String[] urlPatterns = filterMaps.getURLPatterns(); |
| for (String servletName : servletNames) { |
| FilterMap fmap = new FilterMap(); |
| fmap.setFilterName(filterMaps.getFilterName()); |
| fmap.setServletName(servletName); |
| fmap.setDispatcherTypes(filterMaps.getDispatcherTypes()); |
| addFilterMap(fmap); |
| } |
| for (String urlPattern : urlPatterns) { |
| FilterMap fmap = new FilterMap(); |
| fmap.setFilterName(filterMaps.getFilterName()); |
| fmap.setURLPattern(urlPattern); |
| fmap.setDispatcherTypes(filterMaps.getDispatcherTypes()); |
| addFilterMap(fmap); |
| } |
| } |
| |
| /** |
| * Add a filter mapping to this Context. |
| * |
| * @param filterMap The filter mapping to be added |
| * |
| * @exception IllegalArgumentException if the specified filter name |
| * does not match an existing filter definition, or the filter mapping |
| * is malformed |
| */ |
| @Override |
| public void addFilterMap(FilterMap filterMap) { |
| addFilterMap(filterMap, true); |
| } |
| |
| |
| /** |
| * Add a filter mapping to this Context. |
| * |
| * @param filterMap The filter mapping to be added |
| * |
| * @param isMatchAfter true if the given filter mapping should be matched |
| * against requests after any declared filter mappings of this servlet |
| * context, and false if it is supposed to be matched before any declared |
| * filter mappings of this servlet context |
| * |
| * @exception IllegalArgumentException if the specified filter name |
| * does not match an existing filter definition, or the filter mapping |
| * is malformed |
| * |
| */ |
| public void addFilterMap(FilterMap filterMap, boolean isMatchAfter) { |
| |
| // Validate the proposed filter mapping |
| String filterName = filterMap.getFilterName(); |
| String servletName = filterMap.getServletName(); |
| String urlPattern = filterMap.getURLPattern(); |
| if (null == filterRegisMap.get(filterName)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.FILTER_MAPPING_NAME_EXCEPTION), filterName); |
| throw new IllegalArgumentException(msg); |
| } |
| if ((servletName == null) && (urlPattern == null)) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.FILTER_MAPPING_EITHER_EXCEPTION)); |
| } |
| if ((servletName != null) && (urlPattern != null)) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.FILTER_MAPPING_EITHER_EXCEPTION)); |
| } |
| // Because filter-pattern is new in 2.3, no need to adjust |
| // for 2.2 backwards compatibility |
| if ((urlPattern != null) && !validateURLPattern(urlPattern)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.FILTER_MAPPING_INVALID_URL_EXCEPTION), urlPattern); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| // Add this filter mapping to our registered set |
| if (isMatchAfter) { |
| filterMaps.add(filterMap); |
| } else { |
| filterMaps.add(0, filterMap); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addFilterMap", filterMap); |
| } |
| } |
| |
| /** |
| * Gets the current servlet name mappings of the Filter with |
| * the given name. |
| */ |
| public Collection<String> getServletNameFilterMappings(String filterName) { |
| HashSet<String> mappings = new HashSet<String>(); |
| synchronized (filterMaps) { |
| for (FilterMap fm : filterMaps) { |
| if (filterName.equals(fm.getFilterName()) && |
| fm.getServletName() != null) { |
| mappings.add(fm.getServletName()); |
| } |
| } |
| } |
| return mappings; |
| } |
| |
| /** |
| * Gets the current URL pattern mappings of the Filter with the given |
| * name. |
| */ |
| public Collection<String> getUrlPatternFilterMappings(String filterName) { |
| HashSet<String> mappings = new HashSet<String>(); |
| synchronized (filterMaps) { |
| for (FilterMap fm : filterMaps) { |
| if (filterName.equals(fm.getFilterName()) && |
| fm.getURLPattern() != null) { |
| mappings.add(fm.getURLPattern()); |
| } |
| } |
| } |
| return mappings; |
| } |
| |
| /** |
| * Adds the filter with the given name and class name to this servlet |
| * context. |
| */ |
| public FilterRegistration.Dynamic addFilter( |
| String filterName, String className) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addFilter", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (filterName == null || filterName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_FILTER_NAME_EXCEPTION)); |
| } |
| |
| synchronized (filterDefs) { |
| // Make sure filter name is unique for this context |
| if (findFilterDef(filterName) != null) { |
| return null; |
| } |
| |
| DynamicFilterRegistrationImpl regis = |
| (DynamicFilterRegistrationImpl) filterRegisMap.get( |
| filterName); |
| FilterDef filterDef = null; |
| if (null == regis) { |
| filterDef = new FilterDef(); |
| } else { |
| // Complete preliminary filter registration |
| filterDef = regis.getFilterDefinition(); |
| } |
| |
| filterDef.setFilterName(filterName); |
| filterDef.setFilterClassName(className); |
| |
| addFilterDef(filterDef, true, (regis == null)); |
| if (null == regis) { |
| regis = (DynamicFilterRegistrationImpl) |
| filterRegisMap.get(filterName); |
| } |
| |
| return regis; |
| } |
| } |
| |
| /* |
| * Registers the given filter instance with this ServletContext |
| * under the given <tt>filterName</tt>. |
| */ |
| @Override |
| public FilterRegistration.Dynamic addFilter( |
| String filterName, Filter filter) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addFilter", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (filterName == null || filterName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_FILTER_NAME_EXCEPTION)); |
| } |
| |
| if (filter == null) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_FILTER_INSTANCE_EXCEPTION)); |
| } |
| |
| /* |
| * Make sure the given Filter instance is unique across all deployed |
| * contexts |
| */ |
| Container host = getParent(); |
| if (host != null) { |
| for (Container child : host.findChildren()) { |
| if (child == this) { |
| // Our own context will be checked further down |
| continue; |
| } |
| if (((StandardContext) child).hasFilter(filter)) { |
| return null; |
| } |
| } |
| } |
| |
| /* |
| * Make sure the given Filter name and instance are unique within |
| * this context |
| */ |
| synchronized (filterDefs) { |
| for (Map.Entry<String, FilterDef> e : filterDefs.entrySet()) { |
| if (filterName.equals(e.getKey()) || |
| filter == e.getValue().getFilter()) { |
| return null; |
| } |
| } |
| |
| DynamicFilterRegistrationImpl regis = |
| (DynamicFilterRegistrationImpl) filterRegisMap.get( |
| filterName); |
| FilterDef filterDef = null; |
| if (null == regis) { |
| filterDef = new FilterDef(); |
| } else { |
| // Complete preliminary filter registration |
| filterDef = regis.getFilterDefinition(); |
| } |
| |
| filterDef.setFilterName(filterName); |
| filterDef.setFilter(filter); |
| |
| addFilterDef(filterDef, true, (regis == null)); |
| if (null == regis) { |
| regis = (DynamicFilterRegistrationImpl) |
| filterRegisMap.get(filterName); |
| } |
| |
| return regis; |
| } |
| } |
| |
| /** |
| * Checks whether this context contains the given Filter instance |
| */ |
| public boolean hasFilter(Filter filter) { |
| for (Map.Entry<String, FilterDef> e : filterDefs.entrySet()) { |
| if (filter == e.getValue().getFilter()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Adds the filter with the given name and class type to this servlet |
| * context. |
| */ |
| @Override |
| public FilterRegistration.Dynamic addFilter(String filterName, |
| Class <? extends Filter> filterClass) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addFilter", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (filterName == null || filterName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_FILTER_NAME_EXCEPTION)); |
| } |
| |
| synchronized (filterDefs) { |
| if (findFilterDef(filterName) != null) { |
| return null; |
| } |
| |
| DynamicFilterRegistrationImpl regis = |
| (DynamicFilterRegistrationImpl) filterRegisMap.get( |
| filterName); |
| FilterDef filterDef = null; |
| if (null == regis) { |
| filterDef = new FilterDef(); |
| } else { |
| // Complete preliminary filter registration |
| filterDef = regis.getFilterDefinition(); |
| } |
| |
| filterDef.setFilterName(filterName); |
| filterDef.setFilterClass(filterClass); |
| |
| addFilterDef(filterDef, true, (regis == null)); |
| if (null == regis) { |
| regis = (DynamicFilterRegistrationImpl) |
| filterRegisMap.get(filterName); |
| } |
| |
| return regis; |
| } |
| } |
| |
| /** |
| * Instantiates the given Filter class and performs any required |
| * resource injection into the new Filter instance before returning |
| * it. |
| */ |
| @Override |
| public <T extends Filter> T createFilter(Class<T> clazz) |
| throws ServletException { |
| try { |
| return createFilterInstance(clazz); |
| } catch (Throwable t) { |
| throw new ServletException("Unable to create Filter from " + |
| "class " + clazz.getName(), t); |
| } |
| } |
| |
| /** |
| * Gets the FilterRegistration corresponding to the filter with the |
| * given <tt>filterName</tt>. |
| */ |
| @Override |
| public FilterRegistration getFilterRegistration(String filterName) { |
| return filterRegisMap.get(filterName); |
| } |
| |
| /** |
| * Gets a Map of the FilterRegistration objects corresponding to all |
| * currently registered filters. |
| */ |
| @Override |
| public Map<String, ? extends FilterRegistration> getFilterRegistrations() { |
| return Collections.unmodifiableMap(filterRegisMap); |
| } |
| |
| /** |
| * Gets the session tracking cookie configuration of this |
| * <tt>ServletContext</tt>. |
| */ |
| @Override |
| public synchronized SessionCookieConfig getSessionCookieConfig() { |
| if (sessionCookieConfig == null) { |
| sessionCookieConfig = new SessionCookieConfigImpl(this); |
| } |
| return sessionCookieConfig; |
| } |
| |
| /** |
| * Sets the name that will be assigned to any session tracking |
| * cookies created on behalf of this context |
| */ |
| void setSessionCookieName(String sessionCookieName) { |
| this.sessionCookieName = sessionCookieName; |
| sessionCookieNameInitialized = true; |
| } |
| |
| /** |
| * Gets the name that will be assigned to any session tracking |
| * cookies created on behalf of this context |
| */ |
| @Override |
| public String getSessionCookieName() { |
| return sessionCookieName; |
| } |
| |
| /** |
| * @return the name that will be assigned to any session tracking |
| * parameter created on behalf of this context |
| */ |
| @Override |
| public String getSessionParameterName() { |
| if (sessionCookieNameInitialized) { |
| if (sessionCookieName != null && (!sessionCookieName.isEmpty())) { |
| return sessionCookieName; |
| } |
| } |
| |
| return Globals.SESSION_PARAMETER_NAME; |
| } |
| |
| /** |
| * Sets the session tracking modes that are to become effective for this |
| * <tt>ServletContext</tt>. |
| */ |
| @Override |
| public void setSessionTrackingModes( |
| Set<SessionTrackingMode> sessionTrackingModes) { |
| |
| if (sessionTrackingModes.contains(SessionTrackingMode.SSL)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.UNSUPPORTED_TRACKING_MODE_EXCEPTION), |
| new Object[] {SessionTrackingMode.SSL, getName()}); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"setSessionTrackingModes", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| this.sessionTrackingModes = |
| Collections.unmodifiableSet(sessionTrackingModes); |
| |
| if (sessionTrackingModes.contains(SessionTrackingMode.COOKIE)) { |
| setCookies(true); |
| } else { |
| setCookies(false); |
| } |
| |
| if (sessionTrackingModes.contains(SessionTrackingMode.URL)) { |
| setEnableURLRewriting(true); |
| } else { |
| setEnableURLRewriting(false); |
| } |
| } |
| |
| /** |
| * Gets the session tracking modes that are supported by default for this |
| * <tt>ServletContext</tt>. |
| * |
| * @return set of the session tracking modes supported by default for |
| * this <tt>ServletContext</tt> |
| */ |
| @Override |
| public Set<SessionTrackingMode> getDefaultSessionTrackingModes() { |
| return EnumSet.copyOf(DEFAULT_SESSION_TRACKING_MODES); |
| } |
| |
| /** |
| * Gets the session tracking modes that are in effect for this |
| * <tt>ServletContext</tt>. |
| * |
| * @return set of the session tracking modes in effect for this |
| * <tt>ServletContext</tt> |
| */ |
| @Override |
| public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() { |
| return (sessionTrackingModes != null ? new HashSet<>(sessionTrackingModes) : |
| getDefaultSessionTrackingModes()); |
| } |
| |
| /** |
| * Adds the listener with the given class name to this ServletContext. |
| * |
| * @param className the fully qualified class name of the listener |
| */ |
| @Override |
| public void addListener(String className) { |
| addListener(className, true); |
| } |
| |
| |
| /** |
| * Adds the listener with the given class name to this ServletContext. |
| * |
| * @param className the fully qualified class name of the listener |
| * @param isProgrammatic true if the listener is being added |
| * programmatically, and false if it has been declared in the deployment |
| * descriptor |
| */ |
| private void addListener(String className, boolean isProgrammatic) { |
| EventListener listener = null; |
| try { |
| listener = loadListener(getClassLoader(), className); |
| } catch(Throwable t) { |
| throw new IllegalArgumentException(t); |
| } |
| |
| addListener(listener, isProgrammatic); |
| } |
| |
| /** |
| * Adds the given listener instance to this ServletContext. |
| * |
| * @param t the listener to be added |
| */ |
| @Override |
| public <T extends EventListener> void addListener(T t) { |
| addListener(t, true); |
| } |
| |
| /** |
| * Adds the given listener instance to this ServletContext. |
| * |
| * @param t the listener to be added |
| * @param isProgrammatic true if the listener is being added |
| * programmatically, and false if it has been declared in the deployment |
| * descriptor |
| */ |
| private <T extends EventListener> void addListener(T t, |
| boolean isProgrammatic) { |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addListener", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if ((t instanceof ServletContextListener) && isProgrammatic && |
| !isProgrammaticServletContextListenerRegistrationAllowed) { |
| throw new IllegalArgumentException("Not allowed to register " + |
| "ServletContextListener programmatically"); |
| } |
| |
| boolean added = false; |
| |
| if (t instanceof ServletContextAttributeListener || |
| t instanceof ServletRequestAttributeListener || |
| t instanceof ServletRequestListener || |
| t instanceof HttpSessionAttributeListener || |
| t instanceof HttpSessionIdListener) { |
| eventListeners.add(t); |
| added = true; |
| } |
| |
| if (t instanceof HttpSessionListener) { |
| sessionListeners.add((HttpSessionListener) t); |
| if (!added) { |
| added = true; |
| } |
| } |
| |
| if (t instanceof ServletContextListener) { |
| ServletContextListener proxy = (ServletContextListener) t; |
| if (isProgrammatic) { |
| proxy = new RestrictedServletContextListener( |
| (ServletContextListener) t); |
| } |
| // Always add the JSF listener as the first element, |
| // see GlassFish Issue 2563 for details |
| boolean isFirst = |
| "com.sun.faces.config.ConfigureListener".equals( |
| t.getClass().getName()); |
| if (isFirst) { |
| contextListeners.add(0, proxy); |
| } else { |
| contextListeners.add(proxy); |
| } |
| if (!added) { |
| added = true; |
| } |
| } |
| |
| if (!added) { |
| throw new IllegalArgumentException("Invalid listener type " + |
| t.getClass().getName()); |
| } |
| } |
| |
| /** |
| * Adds a listener of the given class type to this ServletContext. |
| */ |
| @Override |
| public void addListener(Class <? extends EventListener> listenerClass) { |
| EventListener listener = null; |
| try { |
| listener = createListenerInstance(listenerClass); |
| } catch(Throwable t) { |
| throw new IllegalArgumentException(t); |
| } |
| |
| addListener(listener); |
| } |
| |
| /** |
| * Instantiates the given EventListener class and performs any |
| * required resource injection into the new EventListener instance |
| * before returning it. |
| */ |
| @Override |
| public <T extends EventListener> T createListener(Class<T> clazz) |
| throws ServletException { |
| if (!ServletContextListener.class.isAssignableFrom(clazz) && |
| !ServletContextAttributeListener.class.isAssignableFrom(clazz) && |
| !ServletRequestListener.class.isAssignableFrom(clazz) && |
| !ServletRequestAttributeListener.class.isAssignableFrom(clazz) && |
| !HttpSessionAttributeListener.class.isAssignableFrom(clazz) && |
| !HttpSessionIdListener.class.isAssignableFrom(clazz) && |
| !HttpSessionListener.class.isAssignableFrom(clazz)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.UNABLE_ADD_LISTENER_EXCEPTION), |
| new Object[] {clazz.getName()}); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| try { |
| return createListenerInstance(clazz); |
| } catch (Throwable t) { |
| throw new ServletException(t); |
| } |
| } |
| |
| public void setJspConfigDescriptor(JspConfigDescriptor jspConfigDesc) { |
| this.jspConfigDesc = jspConfigDesc; |
| } |
| |
| /** |
| * Gets the <code><jsp-config></code> related configuration |
| * that was aggregated over the <code>web.xml</code> and |
| * <code>web-fragment.xml</code> resources of the web application |
| * represented by this ServletContext. |
| */ |
| @Override |
| public JspConfigDescriptor getJspConfigDescriptor() { |
| return jspConfigDesc; |
| } |
| |
| /** |
| * Gets the class loader of the web application represented by this |
| * ServletContext. |
| */ |
| @Override |
| public ClassLoader getClassLoader() { |
| ClassLoader webappLoader = (getLoader() != null) ? |
| getLoader().getClassLoader() : null; |
| if (webappLoader == null) { |
| return null; |
| } |
| if (mySecurityManager != null) { |
| mySecurityManager.checkGetClassLoaderPermission(webappLoader); |
| } |
| return webappLoader; |
| } |
| |
| @Override |
| public void declareRoles(String... roleNames) { |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"declareRoles", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| for (String roleName : roleNames) { |
| addSecurityRole(roleName); |
| } |
| } |
| |
| public void setEffectiveMajorVersion(int effectiveMajorVersion) { |
| this.effectiveMajorVersion = effectiveMajorVersion; |
| } |
| |
| @Override |
| public int getEffectiveMajorVersion() { |
| return effectiveMajorVersion; |
| } |
| |
| public void setEffectiveMinorVersion(int effectiveMinorVersion) { |
| this.effectiveMinorVersion = effectiveMinorVersion; |
| } |
| |
| @Override |
| public int getEffectiveMinorVersion() { |
| return effectiveMinorVersion; |
| } |
| |
| @Override |
| public String getVirtualServerName() { |
| String virtualServerName = null; |
| Container parent = getParent(); |
| if (parent != null) { |
| virtualServerName = parent.getName(); |
| } |
| return virtualServerName; |
| } |
| |
| /** |
| * Add the classname of an InstanceListener to be added to each |
| * Wrapper appended to this Context. |
| * |
| * @param listener Java class name of an InstanceListener class |
| */ |
| @Override |
| public void addInstanceListener(String listener) { |
| instanceListeners.add(listener); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addInstanceListener", listener); |
| } |
| } |
| |
| public void addInstanceListener(InstanceListener listener) { |
| instanceListenerInstances.add(listener); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addInstanceListener", listener); |
| } |
| } |
| |
| /** |
| * Add the given URL pattern as a jsp-property-group. This maps |
| * resources that match the given pattern so they will be passed |
| * to the JSP container. Though there are other elements in the |
| * property group, we only care about the URL pattern here. The |
| * JSP container will parse the rest. |
| * |
| * @param pattern URL pattern to be mapped |
| */ |
| @Override |
| public void addJspMapping(String pattern) { |
| String servletName = findServletMapping("*.jsp"); |
| if (servletName == null) { |
| servletName = "jsp"; |
| } |
| |
| if( findChild(servletName) != null) { |
| addServletMapping(pattern, servletName, true); |
| } else { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Skipping " + pattern + " , no servlet " |
| + servletName); |
| } |
| } |
| } |
| |
| /** |
| * Add a Locale Encoding Mapping (see Sec 5.4 of Servlet spec 2.4) |
| * |
| * @param locale locale to map an encoding for |
| * @param encoding encoding to be used for a give locale |
| */ |
| @Override |
| public void addLocaleEncodingMappingParameter(String locale, String encoding){ |
| getCharsetMapper().addCharsetMappingFromDeploymentDescriptor(locale, encoding); |
| } |
| |
| /** |
| * Add a local EJB resource reference for this web application. |
| * |
| * @param ejb New EJB resource reference |
| */ |
| @Override |
| public void addLocalEjb(ContextLocalEjb ejb) { |
| namingResources.addLocalEjb(ejb); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addLocalEjb", ejb.getName()); |
| } |
| } |
| |
| /** |
| * Add a message destination for this web application. |
| * |
| * @param md New message destination |
| */ |
| public void addMessageDestination(MessageDestination md) { |
| synchronized (messageDestinations) { |
| messageDestinations.put(md.getName(), md); |
| } |
| if (notifyContainerListeners) { |
| fireContainerEvent("addMessageDestination", md.getName()); |
| } |
| } |
| |
| /** |
| * Add a message destination reference for this web application. |
| * |
| * @param mdr New message destination reference |
| */ |
| public void addMessageDestinationRef(MessageDestinationRef mdr) { |
| namingResources.addMessageDestinationRef(mdr); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addMessageDestinationRef", mdr.getName()); |
| } |
| } |
| |
| /** |
| * Add a new MIME mapping, replacing any existing mapping for |
| * the specified extension. |
| * |
| * @param extension Filename extension being mapped |
| * @param mimeType Corresponding MIME type |
| */ |
| public void addMimeMapping(String extension, String mimeType) { |
| mimeMappings.put(extension.toLowerCase(Locale.ENGLISH), mimeType); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addMimeMapping", extension); |
| } |
| } |
| |
| /** |
| * Add a new context initialization parameter. |
| * |
| * @param name Name of the new parameter |
| * @param value Value of the new parameter |
| * |
| * @exception IllegalArgumentException if the name or value is missing, |
| * or if this context initialization parameter has already been |
| * registered |
| */ |
| public void addParameter(String name, String value) { |
| // Validate the proposed context initialization parameter |
| if ((name == null) || (value == null)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.PARAMETER_REQUIRED_EXCEPTION), name); |
| throw new IllegalArgumentException(msg); |
| } |
| if (parameters.get(name) != null) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.DUPLICATE_PARAMETER_EXCEPTION), name); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| // Add this parameter to our defined set |
| synchronized (parameters) { |
| parameters.put(name, value); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addParameter", name); |
| } |
| } |
| |
| |
| /** |
| * Add a resource reference for this web application. |
| * |
| * @param resource New resource reference |
| */ |
| public void addResource(ContextResource resource) { |
| namingResources.addResource(resource); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addResource", resource.getName()); |
| } |
| } |
| |
| |
| /** |
| * Add a resource environment reference for this web application. |
| * |
| * @param name The resource environment reference name |
| * @param type The resource environment reference type |
| */ |
| public void addResourceEnvRef(String name, String type) { |
| namingResources.addResourceEnvRef(name, type); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addResourceEnvRef", name); |
| } |
| } |
| |
| /** |
| * Add a resource link for this web application. |
| * |
| * @param resourceLink New resource link |
| */ |
| public void addResourceLink(ContextResourceLink resourceLink) { |
| namingResources.addResourceLink(resourceLink); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addResourceLink", resourceLink.getName()); |
| } |
| } |
| |
| |
| /** |
| * Add a security role reference for this web application. |
| * |
| * @param role Security role used in the application |
| * @param link Actual security role to check for |
| */ |
| public void addRoleMapping(String role, String link) { |
| synchronized (roleMappings) { |
| roleMappings.put(role, link); |
| } |
| if (notifyContainerListeners) { |
| fireContainerEvent("addRoleMapping", role); |
| } |
| } |
| |
| /** |
| * Add a new security role for this web application. |
| * |
| * @param role New security role |
| */ |
| public void addSecurityRole(String role) { |
| securityRoles.add(role); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addSecurityRole", role); |
| } |
| } |
| |
| /** |
| * Adds the given servlet mappings to this Context. |
| * |
| * <p>If any of the specified URL patterns are already mapped to a |
| * different Servlet, no updates will be performed. |
| * |
| * @param servletMap the Servlet mappings containing the Servlet name |
| * and URL patterns |
| * |
| * @return the (possibly empty) Set of URL patterns that are already |
| * mapped to a different Servlet |
| * |
| * @exception IllegalArgumentException if the specified servlet name |
| * is not known to this Context |
| */ |
| public Set<String> addServletMapping(ServletMap servletMap) { |
| return addServletMapping(servletMap.getServletName(), |
| servletMap.getURLPatterns()); |
| } |
| |
| /** |
| * Adds the given servlet mappings to this Context. |
| * |
| * <p>If any of the specified URL patterns are already mapped to a |
| * different Servlet, no updates will be performed. |
| * |
| * @param name the Servlet name |
| * @param urlPatterns the URL patterns |
| * |
| * @return the (possibly empty) Set of URL patterns that are already |
| * mapped to a different Servlet |
| * |
| * @exception IllegalArgumentException if the specified servlet name |
| * is not known to this Context |
| */ |
| public Set<String> addServletMapping(String name, |
| String[] urlPatterns) { |
| Set<String> conflicts = null; |
| |
| synchronized (servletMappings) { |
| for (String pattern : urlPatterns) { |
| pattern = adjustURLPattern(RequestUtil.urlDecode(pattern)); |
| if (!validateURLPattern(pattern)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_MAPPING_INVALID_URL_EXCEPTION), pattern); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| // Ignore any conflicts with the container provided |
| // Default- and JspServlet |
| String existing = servletMappings.get(pattern); |
| if (existing != null && |
| !existing.equals(Constants.DEFAULT_SERVLET_NAME) && |
| !existing.equals(Constants.JSP_SERVLET_NAME) && |
| !name.equals(Constants.DEFAULT_SERVLET_NAME) && |
| !name.equals(Constants.JSP_SERVLET_NAME)) { |
| if (conflicts == null) { |
| conflicts = new HashSet<String>(); |
| } |
| conflicts.add(pattern); |
| } |
| } |
| |
| if (conflicts == null) { |
| for (String urlPattern : urlPatterns) { |
| addServletMapping(urlPattern, name, false); |
| } |
| return Collections.emptySet(); |
| } else { |
| return conflicts; |
| } |
| } |
| } |
| |
| /** |
| * Adds the given servlet mapping to this Context, overriding any |
| * existing mapping for the specified pattern. |
| * |
| * @param pattern URL pattern to be mapped |
| * @param name Name of the corresponding servlet to execute |
| * |
| * @exception IllegalArgumentException if the specified servlet name |
| * is not known to this Context |
| */ |
| @Override |
| public void addServletMapping(String pattern, String name) { |
| addServletMapping(pattern, name, false); |
| } |
| |
| /** |
| * Adds the given servlet mapping to this Context, overriding any |
| * existing mapping for the specified pattern. |
| * |
| * @param pattern URL pattern to be mapped |
| * @param name Name of the corresponding servlet to execute |
| * @param jspWildCard true if name identifies the JspServlet |
| * and pattern contains a wildcard; false otherwise |
| * |
| * @exception IllegalArgumentException if the specified servlet name |
| * is not known to this Context |
| */ |
| public void addServletMapping(String pattern, String name, |
| boolean jspWildCard) { |
| // Validate the proposed mapping |
| ServletRegistrationImpl regis = servletRegisMap.get(name); |
| if (null == regis) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_MAPPING_UNKNOWN_NAME_EXCEPTION), name); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| pattern = adjustURLPattern(RequestUtil.urlDecode(pattern)); |
| if (!validateURLPattern(pattern)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_MAPPING_INVALID_URL_EXCEPTION), pattern); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| /* |
| * Add this mapping to our registered set. Make sure that it is |
| * possible to override the mappings of the container provided |
| * Default- and JspServlet, and that these servlets are prevented |
| * from overriding any user-defined mappings (depending on the order |
| * in which the contents of the default-web.xml are merged with those |
| * of the app's deployment descriptor). |
| * This is to prevent the DefaultServlet from hijacking '/', and the |
| * JspServlet from hijacking *.jsp(x). |
| */ |
| synchronized (servletMappings) { |
| String existing = servletMappings.get(pattern); |
| if (existing != null) { |
| if (!existing.equals(Constants.DEFAULT_SERVLET_NAME) && |
| !existing.equals(Constants.JSP_SERVLET_NAME) && |
| !name.equals(Constants.DEFAULT_SERVLET_NAME) && |
| !name.equals(Constants.JSP_SERVLET_NAME)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.DUPLICATE_SERVLET_MAPPING_EXCEPTION), |
| new Object[] {name, pattern, existing}); |
| throw new IllegalArgumentException(msg); |
| } |
| if (existing.equals(Constants.DEFAULT_SERVLET_NAME) || |
| existing.equals(Constants.JSP_SERVLET_NAME)) { |
| // Override the mapping of the container provided |
| // Default- or JspServlet |
| Wrapper wrapper = (Wrapper) findChild(existing); |
| removePatternFromServlet(wrapper, pattern); |
| mapper.removeWrapper(pattern); |
| servletMappings.put(pattern, name); |
| } |
| } else { |
| servletMappings.put(pattern, name); |
| } |
| } |
| |
| Wrapper wrapper = regis.getWrapper(); |
| wrapper.addMapping(pattern); |
| |
| // Update context mapper |
| mapper.addWrapper(pattern, wrapper, jspWildCard, name, true); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addServletMapping", pattern); |
| } |
| } |
| |
| /* |
| * Adds the servlet with the given name and class name to this servlet |
| * context. |
| */ |
| @Override |
| public ServletRegistration.Dynamic addServlet( |
| String servletName, String className) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addServlet", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (servletName == null || servletName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_SERVLET_NAME_EXCEPTION)); |
| } |
| |
| synchronized (children) { |
| if (findChild(servletName) == null) { |
| DynamicServletRegistrationImpl regis = |
| (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| Wrapper wrapper = null; |
| if (regis == null) { |
| wrapper = createWrapper(); |
| wrapper.setServletClassName(className); |
| } else { |
| // Complete preliminary servlet registration |
| wrapper = regis.getWrapper(); |
| regis.setServletClassName(className); |
| } |
| wrapper.setName(servletName); |
| addChild(wrapper, true, (null == regis)); |
| if (null == regis) { |
| regis = (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| } |
| return regis; |
| } else { |
| return null; |
| } |
| } |
| } |
| |
| /* |
| * Registers the given servlet instance with this ServletContext |
| * under the given <tt>servletName</tt>. |
| */ |
| @Override |
| public ServletRegistration.Dynamic addServlet( |
| String servletName, Servlet servlet) { |
| return addServlet(servletName, servlet, null, null); |
| } |
| |
| /* |
| * Adds the servlet with the given name and class type to this servlet |
| * context. |
| */ |
| @Override |
| public ServletRegistration.Dynamic addServlet(String servletName, |
| Class <? extends Servlet> servletClass) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addServlet", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (servletName == null || servletName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_SERVLET_NAME_EXCEPTION)); |
| } |
| |
| // Make sure servlet name is unique for this context |
| synchronized (children) { |
| if (findChild(servletName) == null) { |
| DynamicServletRegistrationImpl regis = |
| (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| Wrapper wrapper = null; |
| if (regis == null) { |
| wrapper = createWrapper(); |
| wrapper.setServletClass(servletClass); |
| } else { |
| // Complete preliminary servlet registration |
| wrapper = regis.getWrapper(); |
| regis.setServletClass(servletClass); |
| } |
| wrapper.setName(servletName); |
| addChild(wrapper, true, (null == regis)); |
| if (null == regis) { |
| regis = (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| } |
| return regis; |
| } else { |
| return null; |
| } |
| } |
| } |
| |
| /** |
| * Adds the given servlet instance with the given name to this servlet |
| * context and initializes it. |
| * |
| * <p>In order to add any URL patterns that will be mapped to the |
| * given servlet, addServletMappings must be used. If this context |
| * has already been started, the URL patterns must be passed to |
| * addServlet instead. |
| * |
| * @param servletName the servlet name |
| * @param instance the servlet instance |
| * @param initParams Map containing the initialization parameters for |
| * the servlet |
| * |
| * @throws ServletException if the servlet fails to be initialized |
| */ |
| @Override |
| public ServletRegistration.Dynamic addServlet(String servletName, |
| Servlet instance, Map<String, String> initParams) { |
| return addServlet(servletName, instance, initParams, null); |
| } |
| |
| /** |
| * Adds the given servlet instance with the given name and URL patterns |
| * to this servlet context, and initializes it. |
| * |
| * @param servletName the servlet name |
| * @param servlet the servlet instance |
| * @param initParams Map containing the initialization parameters for |
| * the servlet |
| * @param urlPatterns the URL patterns that will be mapped to the servlet |
| * |
| * @return the ServletRegistration through which the servlet may be |
| * further configured |
| */ |
| @Override |
| public ServletRegistration.Dynamic addServlet(String servletName, |
| Servlet servlet, Map<String, String> initParams, |
| String... urlPatterns) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addServlet", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (servletName == null || servletName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_SERVLET_NAME_EXCEPTION)); |
| } |
| |
| if (servlet == null) { |
| throw new NullPointerException(rb.getString(LogFacade.NULL_SERVLET_INSTANCE_EXCEPTION)); |
| } |
| |
| if (servlet instanceof SingleThreadModel) { |
| throw new IllegalArgumentException("Servlet implements " + |
| SingleThreadModel.class.getName()); |
| } |
| |
| /* |
| * Make sure the given Servlet instance is unique across all deployed |
| * contexts |
| */ |
| Container host = getParent(); |
| if (host != null) { |
| for (Container child : host.findChildren()) { |
| if (child == this) { |
| // Our own context will be checked further down |
| continue; |
| } |
| if (((StandardContext) child).hasServlet(servlet)) { |
| return null; |
| } |
| } |
| } |
| |
| /* |
| * Make sure the given Servlet name and instance are unique within |
| * this context |
| */ |
| synchronized (children) { |
| for (Map.Entry<String, Container> e : children.entrySet()) { |
| if (servletName.equals(e.getKey()) || |
| servlet == ((StandardWrapper)e.getValue()).getServlet()) { |
| return null; |
| } |
| } |
| |
| DynamicServletRegistrationImpl regis = |
| (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| StandardWrapper wrapper = null; |
| if (regis == null) { |
| wrapper = (StandardWrapper) createWrapper(); |
| } else { |
| // Complete preliminary servlet registration |
| wrapper = regis.getWrapper(); |
| } |
| |
| wrapper.setName(servletName); |
| wrapper.setServlet(servlet); |
| if (initParams != null) { |
| for (Map.Entry<String, String> e : initParams.entrySet()) { |
| wrapper.addInitParameter(e.getKey(), e.getValue()); |
| } |
| } |
| |
| addChild(wrapper, true, (null == regis)); |
| if (null == regis) { |
| regis = (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| } |
| |
| if (urlPatterns != null) { |
| for (String urlPattern : urlPatterns) { |
| addServletMapping(urlPattern, servletName, false); |
| } |
| } |
| |
| return regis; |
| } |
| } |
| |
| /* |
| * Adds the servlet with the given name and jsp file to this servlet |
| * context. |
| */ |
| @Override |
| public ServletRegistration.Dynamic addJspFile( |
| String servletName, String jspFile) { |
| |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"addJspFile", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (servletName == null || servletName.length() == 0) { |
| throw new IllegalArgumentException(rb.getString(LogFacade.NULL_EMPTY_SERVLET_NAME_EXCEPTION)); |
| } |
| |
| synchronized (children) { |
| if (findChild(servletName) == null) { |
| DynamicServletRegistrationImpl regis = |
| (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| Wrapper wrapper = null; |
| if (regis == null) { |
| wrapper = createWrapper(); |
| } else { |
| // Override an existing registration |
| wrapper = regis.getWrapper(); |
| } |
| wrapper.setJspFile(jspFile); |
| wrapper.setName(servletName); |
| addChild(wrapper, true, (null == regis)); |
| if (null == regis) { |
| regis = (DynamicServletRegistrationImpl) |
| servletRegisMap.get(servletName); |
| } |
| return regis; |
| } else { |
| return null; |
| } |
| } |
| } |
| |
| /** |
| * This method is overridden in web-glue to also remove the given |
| * mapping from the deployment backend's WebBundleDescriptor. |
| */ |
| protected void removePatternFromServlet(Wrapper wrapper, String pattern) { |
| wrapper.removeMapping(pattern); |
| } |
| |
| /** |
| * Checks whether this context contains the given Servlet instance |
| */ |
| public boolean hasServlet(Servlet servlet) { |
| for (Map.Entry<String, Container> e : children.entrySet()) { |
| if (servlet == ((StandardWrapper)e.getValue()).getServlet()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Instantiates the given Servlet class and performs any required |
| * resource injection into the new Servlet instance before returning |
| * it. |
| */ |
| @Override |
| public <T extends Servlet> T createServlet(Class<T> clazz) |
| throws ServletException { |
| try { |
| return createServletInstance(clazz); |
| } catch (Throwable t) { |
| throw new ServletException("Unable to create Servlet from " + |
| "class " + clazz.getName(), t); |
| } |
| } |
| |
| /** |
| * Gets the ServletRegistration corresponding to the servlet with the |
| * given <tt>servletName</tt>. |
| */ |
| @Override |
| public ServletRegistration getServletRegistration(String servletName) { |
| return servletRegisMap.get(servletName); |
| } |
| |
| /** |
| * Gets a Map of the ServletRegistration objects corresponding to all |
| * currently registered servlets. |
| */ |
| @Override |
| public Map<String, ? extends ServletRegistration> getServletRegistrations() { |
| return Collections.unmodifiableMap(servletRegisMap); |
| } |
| |
| /** |
| * Add a new watched resource to the set recognized by this Context. |
| * |
| * @param name New watched resource file name |
| */ |
| @Override |
| public void addWatchedResource(String name) { |
| watchedResources.add(name); |
| fireContainerEvent("addWatchedResource", name); |
| } |
| |
| /** |
| * Add a new welcome file to the set recognized by this Context. |
| * |
| * @param name New welcome file name |
| */ |
| @Override |
| public void addWelcomeFile(String name) { |
| |
| // Welcome files from the application deployment descriptor |
| // completely replace those from the default conf/web.xml file |
| if (replaceWelcomeFiles) { |
| welcomeFiles = new String[0]; |
| setReplaceWelcomeFiles(false); |
| } |
| String results[] = new String[welcomeFiles.length + 1]; |
| for (int i = 0; i < welcomeFiles.length; i++) |
| results[i] = welcomeFiles[i]; |
| results[welcomeFiles.length] = name; |
| welcomeFiles = results; |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("addWelcomeFile", name); |
| } |
| } |
| |
| /** |
| * Add the classname of a LifecycleListener to be added to each |
| * Wrapper appended to this Context. |
| * |
| * @param listener Java class name of a LifecycleListener class |
| */ |
| @Override |
| public void addWrapperLifecycle(String listener) { |
| wrapperLifecycles.add(listener); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addWrapperLifecycle", listener); |
| } |
| } |
| |
| /** |
| * Add the classname of a ContainerListener to be added to each |
| * Wrapper appended to this Context. |
| * |
| * @param listener Java class name of a ContainerListener class |
| */ |
| @Override |
| public void addWrapperListener(String listener) { |
| wrapperListeners.add(listener); |
| if (notifyContainerListeners) { |
| fireContainerEvent("addWrapperListener", listener); |
| } |
| } |
| |
| /** |
| * Factory method to create and return a new Wrapper instance, of |
| * the Java implementation class appropriate for this Context |
| * implementation. The constructor of the instantiated Wrapper |
| * will have been called, but no properties will have been set. |
| */ |
| @Override |
| public Wrapper createWrapper() { |
| Wrapper wrapper = new StandardWrapper(); |
| |
| synchronized (instanceListeners) { |
| for (String instanceListener : instanceListeners) { |
| try { |
| Class clazz = Class.forName(instanceListener); |
| wrapper.addInstanceListener((InstanceListener)clazz.newInstance()); |
| } catch(Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.CREATING_INSTANCE_LISTENER_EXCEPTION), |
| instanceListener); |
| log.log(Level.SEVERE, msg, t); |
| return (null); |
| } |
| } |
| } |
| |
| synchronized (instanceListenerInstances) { |
| for(InstanceListener instanceListenerInstance : instanceListenerInstances) { |
| wrapper.addInstanceListener(instanceListenerInstance); |
| } |
| } |
| |
| Iterator<String> i = wrapperLifecycles.iterator(); |
| while (i.hasNext()) { |
| String wrapperLifecycle = i.next(); |
| try { |
| Class clazz = Class.forName(wrapperLifecycle); |
| if(wrapper instanceof Lifecycle) { |
| ((Lifecycle)wrapper).addLifecycleListener( |
| (LifecycleListener)clazz.newInstance()); |
| } |
| } catch(Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.CREATING_LIFECYCLE_LISTENER_EXCEPTION), |
| wrapperLifecycle); |
| log.log(Level.SEVERE, msg, t); |
| return (null); |
| } |
| } |
| |
| i = wrapperListeners.iterator(); |
| while (i.hasNext()) { |
| String wrapperListener = i.next(); |
| try { |
| Class clazz = Class.forName(wrapperListener); |
| wrapper.addContainerListener((ContainerListener) |
| clazz.newInstance()); |
| } catch(Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.CREATING_CONTAINER_LISTENER_EXCEPTION), |
| wrapperListener); |
| log.log(Level.SEVERE, msg, t); |
| return (null); |
| } |
| } |
| |
| return (wrapper); |
| } |
| |
| /** |
| * Return the set of application parameters for this application. |
| */ |
| @Override |
| public List<ApplicationParameter> findApplicationParameters() { |
| return applicationParameters; |
| } |
| |
| /** |
| * Gets the security constraints defined for this web application. |
| */ |
| @Override |
| public List<SecurityConstraint> getConstraints() { |
| return constraints; |
| } |
| |
| /** |
| * Checks whether this web application has any security constraints |
| * defined. |
| */ |
| @Override |
| public boolean hasConstraints() { |
| return !constraints.isEmpty(); |
| } |
| |
| /** |
| * Return the EJB resource reference with the specified name, if any; |
| * otherwise, return <code>null</code>. |
| * |
| * @param name Name of the desired EJB resource reference |
| */ |
| @Override |
| public ContextEjb findEjb(String name) { |
| return namingResources.findEjb(name); |
| } |
| |
| /** |
| * Return the defined EJB resource references for this application. |
| * If there are none, a zero-length array is returned. |
| */ |
| @Override |
| public ContextEjb[] findEjbs() { |
| return namingResources.findEjbs(); |
| } |
| |
| /** |
| * Return the environment entry with the specified name, if any; |
| * otherwise, return <code>null</code>. |
| * |
| * @param name Name of the desired environment entry |
| */ |
| @Override |
| public ContextEnvironment findEnvironment(String name) { |
| return namingResources.findEnvironment(name); |
| } |
| |
| /** |
| * Return the set of defined environment entries for this web |
| * application. If none have been defined, a zero-length array |
| * is returned. |
| */ |
| @Override |
| public ContextEnvironment[] findEnvironments() { |
| return namingResources.findEnvironments(); |
| } |
| |
| /** |
| * Return the error page entry for the specified HTTP error code, |
| * if any; otherwise return <code>null</code>. |
| * |
| * @param errorCode Error code to look up |
| */ |
| @Override |
| public ErrorPage findErrorPage(int errorCode) { |
| if ((errorCode >= 400) && (errorCode < 600)) { |
| return statusPages.get(errorCode); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Return the error page entry for the specified Java exception type, |
| * if any; otherwise return <code>null</code>. |
| * |
| * @param exceptionType Exception type to look up |
| */ |
| @Override |
| public ErrorPage findErrorPage(String exceptionType) { |
| synchronized (exceptionPages) { |
| return exceptionPages.get(exceptionType); |
| } |
| } |
| |
| /** |
| * Gets the default error page of this context. |
| * |
| * <p>A default error page is an error page that was declared without |
| * any exception-type and error-code. |
| * |
| * @return the default error page of this context, or null if this |
| * context does not have any default error page |
| */ |
| @Override |
| public ErrorPage getDefaultErrorPage() { |
| return defaultErrorPage; |
| } |
| |
| /** |
| * Return the filter definition for the specified filter name, if any; |
| * otherwise return <code>null</code>. |
| * |
| * @param filterName Filter name to look up |
| */ |
| @Override |
| public FilterDef findFilterDef(String filterName) { |
| synchronized (filterDefs) { |
| return filterDefs.get(filterName); |
| } |
| } |
| |
| /** |
| * Return the set of defined filters for this Context. |
| */ |
| @Override |
| public FilterDef[] findFilterDefs() { |
| synchronized (filterDefs) { |
| FilterDef results[] = new FilterDef[filterDefs.size()]; |
| return filterDefs.values().toArray(results); |
| } |
| } |
| |
| /** |
| * Return the list of filter mappings for this Context. |
| */ |
| @Override |
| public List<FilterMap> findFilterMaps() { |
| return filterMaps; |
| } |
| |
| /** |
| * Return the list of InstanceListener classes that will be added to |
| * newly created Wrappers automatically. |
| */ |
| @Override |
| public List<String> findInstanceListeners() { |
| return instanceListeners; |
| } |
| |
| /** |
| * Return the local EJB resource reference with the specified name, if any; |
| * otherwise, return <code>null</code>. |
| * |
| * @param name Name of the desired EJB resource reference |
| */ |
| @Override |
| public ContextLocalEjb findLocalEjb(String name) { |
| return namingResources.findLocalEjb(name); |
| } |
| |
| /** |
| * Return the defined local EJB resource references for this application. |
| * If there are none, a zero-length array is returned. |
| */ |
| @Override |
| public ContextLocalEjb[] findLocalEjbs() { |
| return namingResources.findLocalEjbs(); |
| } |
| |
| /** |
| * FIXME: Fooling introspection ... |
| */ |
| public Context findMappingObject() { |
| return (Context) getMappingObject(); |
| } |
| |
| /** |
| * Return the message destination with the specified name, if any; |
| * otherwise, return <code>null</code>. |
| * |
| * @param name Name of the desired message destination |
| */ |
| public MessageDestination findMessageDestination(String name) { |
| synchronized (messageDestinations) { |
| return messageDestinations.get(name); |
| } |
| } |
| |
| /** |
| * Return the set of defined message destinations for this web |
| * application. If none have been defined, a zero-length array |
| * is returned. |
| */ |
| public MessageDestination[] findMessageDestinations() { |
| synchronized (messageDestinations) { |
| return messageDestinations.values().toArray( |
| new MessageDestination[messageDestinations.size()]); |
| } |
| } |
| |
| /** |
| * Return the message destination ref with the specified name, if any; |
| * otherwise, return <code>null</code>. |
| * |
| * @param name Name of the desired message destination ref |
| */ |
| public MessageDestinationRef findMessageDestinationRef(String name) { |
| return namingResources.findMessageDestinationRef(name); |
| } |
| |
| /** |
| * Return the set of defined message destination refs for this web |
| * application. If none have been defined, a zero-length array |
| * is returned. |
| */ |
| public MessageDestinationRef[] findMessageDestinationRefs() { |
| return namingResources.findMessageDestinationRefs(); |
| } |
| |
| /** |
| * Return the MIME type to which the specified extension is mapped, |
| * if any; otherwise return <code>null</code>. |
| * |
| * @param extension Extension to map to a MIME type |
| */ |
| @Override |
| public String findMimeMapping(String extension) { |
| |
| return mimeMappings.get(extension.toLowerCase(Locale.ENGLISH)); |
| } |
| |
| /** |
| * Return the extensions for which MIME mappings are defined. If there |
| * are none, a zero-length array is returned. |
| */ |
| @Override |
| public String[] findMimeMappings() { |
| return mimeMappings.keySet().toArray( |
| new String[mimeMappings.size()]); |
| } |
| |
| /** |
| * Return the value for the specified context initialization |
| * parameter name, if any; otherwise return <code>null</code>. |
| * |
| * @param name Name of the parameter to return |
| */ |
| @Override |
| public String findParameter(String name) { |
| synchronized (parameters) { |
| return parameters.get(name); |
| } |
| } |
| |
| /** |
| * Return the names of all defined context initialization parameters |
| * for this Context. If no parameters are defined, a zero-length |
| * array is returned. |
| */ |
| @Override |
| public String[] findParameters() { |
| synchronized (parameters) { |
| return parameters.keySet().toArray(new String[parameters.size()]); |
| } |
| } |
| |
| /** |
| * Return the resource reference with the specified name, if any; |
| * otherwise return <code>null</code>. |
| * |
| * @param name Name of the desired resource reference |
| */ |
| @Override |
| public ContextResource findResource(String name) { |
| return namingResources.findResource(name); |
| } |
| |
| /** |
| * Return the resource environment reference type for the specified |
| * name, if any; otherwise return <code>null</code>. |
| * |
| * @param name Name of the desired resource environment reference |
| */ |
| @Override |
| public String findResourceEnvRef(String name) { |
| return namingResources.findResourceEnvRef(name); |
| } |
| |
| /** |
| * Return the set of resource environment reference names for this |
| * web application. If none have been specified, a zero-length |
| * array is returned. |
| */ |
| @Override |
| public String[] findResourceEnvRefs() { |
| return namingResources.findResourceEnvRefs(); |
| } |
| |
| /** |
| * Return the resource link with the specified name, if any; |
| * otherwise return <code>null</code>. |
| * |
| * @param name Name of the desired resource link |
| */ |
| @Override |
| public ContextResourceLink findResourceLink(String name) { |
| return namingResources.findResourceLink(name); |
| } |
| |
| /** |
| * Return the defined resource links for this application. If |
| * none have been defined, a zero-length array is returned. |
| */ |
| @Override |
| public ContextResourceLink[] findResourceLinks() { |
| return namingResources.findResourceLinks(); |
| } |
| |
| /** |
| * Return the defined resource references for this application. If |
| * none have been defined, a zero-length array is returned. |
| */ |
| @Override |
| public ContextResource[] findResources() { |
| return namingResources.findResources(); |
| } |
| |
| /** |
| * For the given security role (as used by an application), return the |
| * corresponding role name (as defined by the underlying Realm) if there |
| * is one. Otherwise, return the specified role unchanged. |
| * |
| * @param role Security role to map |
| */ |
| @Override |
| public String findRoleMapping(String role) { |
| |
| String realRole = null; |
| synchronized (roleMappings) { |
| realRole = roleMappings.get(role); |
| } |
| if (realRole != null) |
| return (realRole); |
| else |
| return (role); |
| } |
| |
| /** |
| * Checks if the given security role is defined for this application. |
| * |
| * @param role Security role to check for |
| * |
| * @return true if the specified security role is defined |
| * for this application, false otherwise |
| */ |
| @Override |
| public boolean hasSecurityRole(String role) { |
| return securityRoles.contains(role); |
| } |
| |
| /** |
| * Removes any security roles defined for this application. |
| */ |
| @Override |
| public void removeSecurityRoles() { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<String> i = securityRoles.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeSecurityRole", i.next()); |
| } |
| } |
| securityRoles.clear(); |
| } |
| |
| /** |
| * Return the servlet name mapped by the specified pattern (if any); |
| * otherwise return <code>null</code>. |
| * |
| * @param pattern Pattern for which a mapping is requested |
| */ |
| @Override |
| public String findServletMapping(String pattern) { |
| synchronized (servletMappings) { |
| return servletMappings.get(pattern); |
| } |
| } |
| |
| /** |
| * Return the patterns of all defined servlet mappings for this |
| * Context. If no mappings are defined, a zero-length array is returned. |
| */ |
| @Override |
| public String[] findServletMappings() { |
| synchronized (servletMappings) { |
| String results[] = new String[servletMappings.size()]; |
| return |
| servletMappings.keySet().toArray(results); |
| } |
| } |
| |
| /** |
| * Return the context-relative URI of the error page for the specified |
| * HTTP status code, if any; otherwise return <code>null</code>. |
| * |
| * @param status HTTP status code to look up |
| */ |
| @Override |
| public ErrorPage findStatusPage(int status) { |
| return statusPages.get(status); |
| } |
| |
| /** |
| * Return the set of HTTP status codes for which error pages have |
| * been specified. If none are specified, a zero-length array |
| * is returned. |
| */ |
| @Override |
| public int[] findStatusPages() { |
| synchronized (statusPages) { |
| int results[] = new int[statusPages.size()]; |
| Iterator<Integer> elements = statusPages.keySet().iterator(); |
| int i = 0; |
| while (elements.hasNext()) |
| results[i++] = elements.next(); |
| return results; |
| } |
| } |
| |
| /** |
| * Return <code>true</code> if the specified welcome file is defined |
| * for this Context; otherwise return <code>false</code>. |
| * |
| * @param name Welcome file to verify |
| */ |
| @Override |
| public boolean findWelcomeFile(String name) { |
| synchronized (welcomeFiles) { |
| for(String welcomeFile : welcomeFiles) { |
| if(name.equals(welcomeFile)) { |
| return true; |
| } |
| } |
| } |
| return (false); |
| } |
| |
| /** |
| * Gets the watched resources defined for this web application. |
| */ |
| @Override |
| public List<String> getWatchedResources() { |
| return watchedResources; |
| } |
| |
| /** |
| * Return the set of welcome files defined for this Context. If none are |
| * defined, a zero-length array is returned. |
| */ |
| @Override |
| public String[] findWelcomeFiles() { |
| return (welcomeFiles); |
| } |
| |
| /** |
| * Return the list of LifecycleListener classes that will be added to |
| * newly created Wrappers automatically. |
| */ |
| @Override |
| public List<String> findWrapperLifecycles() { |
| return wrapperLifecycles; |
| } |
| |
| /** |
| * Return the list of ContainerListener classes that will be added to |
| * newly created Wrappers automatically. |
| */ |
| @Override |
| public List<String> findWrapperListeners() { |
| return wrapperListeners; |
| } |
| |
| /** |
| * Gets the Authenticator of this Context. |
| * |
| * @return the Authenticator of this Context |
| */ |
| @Override |
| public Authenticator getAuthenticator() { |
| Pipeline p = getPipeline(); |
| if (p != null) { |
| for (GlassFishValve valve : p.getValves()) { |
| if (valve instanceof Authenticator) { |
| return (Authenticator) valve; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Reload this web application, if reloading is supported. |
| * <p> |
| * <b>IMPLEMENTATION NOTE</b>: This method is designed to deal with |
| * reloads required by changes to classes in the underlying repositories |
| * of our class loader. It does not handle changes to the web application |
| * deployment descriptor. If that has occurred, you should stop this |
| * Context and create (and start) a new Context instance instead. |
| * |
| * @exception IllegalStateException if the <code>reloadable</code> |
| * property is set to <code>false</code>. |
| */ |
| @Override |
| public synchronized void reload() { |
| |
| // Validate our current component state |
| if (!started) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.CONTAINER_NOT_STARTED_EXCEPTION), logName()); |
| throw new IllegalStateException(msg); |
| } |
| // Make sure reloading is enabled |
| // if (!reloadable) |
| // throw new IllegalStateException |
| // (sm.getString("standardContext.notReloadable")); |
| //standardContext.notReloadable=PWC1287: Reloading is disabled on this Context |
| if (log.isLoggable(Level.INFO)) { |
| log.log(Level.INFO, LogFacade.RELOADING_STARTED); |
| } |
| |
| // Stop accepting requests temporarily |
| setPaused(true); |
| |
| try { |
| stop(); |
| } catch (LifecycleException e) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STOPPING_CONTEXT_EXCEPTION), this); |
| log.log(Level.SEVERE, msg, e); |
| } |
| |
| try { |
| start(); |
| } catch (LifecycleException e) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTING_CONTEXT_EXCEPTION), this); |
| log.log(Level.SEVERE, msg, e); |
| } |
| |
| setPaused(false); |
| |
| } |
| |
| /** |
| * Remove the application parameter with the specified name from |
| * the set for this application. |
| * |
| * @param name Name of the application parameter to remove |
| */ |
| @Override |
| public void removeApplicationParameter(String name) { |
| ApplicationParameter match = null; |
| Iterator<ApplicationParameter> i = |
| applicationParameters.iterator(); |
| while (i.hasNext()) { |
| ApplicationParameter applicationParameter = i.next(); |
| // Make sure this parameter is currently present |
| if (name.equals(applicationParameter.getName())) { |
| match = applicationParameter; |
| break; |
| } |
| } |
| if (match != null) { |
| applicationParameters.remove(match); |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeApplicationParameter", name); |
| } |
| } |
| } |
| |
| /** |
| * Removes the given child container. |
| * |
| * @param child the child container to be removed |
| * |
| * @exception IllegalArgumentException if the given child container is |
| * not an implementation of Wrapper |
| */ |
| @Override |
| public void removeChild(Container child) { |
| |
| if (!(child instanceof Wrapper)) |
| throw new IllegalArgumentException(rb.getString(LogFacade.NO_WRAPPER_EXCEPTION)); |
| |
| super.removeChild(child); |
| } |
| |
| /** |
| * Removes any security constraints from this web application. |
| */ |
| @Override |
| public void removeConstraints() { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<SecurityConstraint> i = constraints.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeConstraint", i.next()); |
| } |
| } |
| constraints.clear(); |
| } |
| |
| /** |
| * Remove any EJB resource reference with the specified name. |
| * |
| * @param name Name of the EJB resource reference to remove |
| */ |
| public void removeEjb(String name) { |
| |
| namingResources.removeEjb(name); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeEjb", name); |
| } |
| } |
| |
| /** |
| * Remove any environment entry with the specified name. |
| * |
| * @param name Name of the environment entry to remove |
| */ |
| @Override |
| public void removeEnvironment(String name) { |
| if (namingResources == null) { |
| return; |
| } |
| ContextEnvironment env = namingResources.findEnvironment(name); |
| if (env == null) { |
| throw new IllegalArgumentException |
| ("Invalid environment name '" + name + "'"); |
| } |
| |
| namingResources.removeEnvironment(name); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeEnvironment", name); |
| } |
| } |
| |
| /** |
| * Removes any error page declarations. |
| */ |
| @Override |
| public void removeErrorPages() { |
| synchronized (exceptionPages) { |
| if (notifyContainerListeners) { |
| for (ErrorPage errorPage : exceptionPages.values()) { |
| fireContainerEvent("removeErrorPage", errorPage); |
| } |
| } |
| exceptionPages.clear(); |
| } |
| synchronized (statusPages) { |
| if (notifyContainerListeners) { |
| for (ErrorPage statusPage : statusPages.values()) { |
| fireContainerEvent("removeErrorPage", statusPage); |
| } |
| } |
| statusPages.clear(); |
| } |
| } |
| |
| /** |
| * Remove the specified filter definition from this Context, if it exists; |
| * otherwise, no action is taken. |
| * |
| * @param filterDef Filter definition to be removed |
| */ |
| @Override |
| public void removeFilterDef(FilterDef filterDef) { |
| |
| synchronized (filterDefs) { |
| filterDefs.remove(filterDef.getFilterName()); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeFilterDef", filterDef); |
| } |
| } |
| |
| /** |
| * Removes any filter mappings from this Context. |
| */ |
| @Override |
| public void removeFilterMaps() { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<FilterMap> i = filterMaps.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeFilterMap", i.next()); |
| } |
| } |
| filterMaps.clear(); |
| } |
| |
| /** |
| * Remove a class name from the list of InstanceListener classes that |
| * will be added to newly created Wrappers. |
| * |
| * @param listener Class name of an InstanceListener class to be removed |
| */ |
| @Override |
| public void removeInstanceListener(String listener) { |
| instanceListeners.remove(listener); |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeInstanceListener", listener); |
| } |
| } |
| |
| /** |
| * Remove any local EJB resource reference with the specified name. |
| * |
| * @param name Name of the EJB resource reference to remove |
| */ |
| @Override |
| public void removeLocalEjb(String name) { |
| |
| namingResources.removeLocalEjb(name); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeLocalEjb", name); |
| } |
| } |
| |
| /** |
| * Remove any message destination with the specified name. |
| * |
| * @param name Name of the message destination to remove |
| */ |
| public void removeMessageDestination(String name) { |
| |
| synchronized (messageDestinations) { |
| messageDestinations.remove(name); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeMessageDestination", name); |
| } |
| } |
| |
| /** |
| * Remove any message destination ref with the specified name. |
| * |
| * @param name Name of the message destination ref to remove |
| */ |
| public void removeMessageDestinationRef(String name) { |
| |
| namingResources.removeMessageDestinationRef(name); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeMessageDestinationRef", name); |
| } |
| } |
| |
| /** |
| * Remove the MIME mapping for the specified extension, if it exists; |
| * otherwise, no action is taken. |
| * |
| * @param extension Extension to remove the mapping for |
| */ |
| @Override |
| public void removeMimeMapping(String extension) { |
| |
| mimeMappings.remove(extension.toLowerCase(Locale.ENGLISH)); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeMimeMapping", extension); |
| } |
| } |
| |
| /** |
| * Remove the context initialization parameter with the specified |
| * name, if it exists; otherwise, no action is taken. |
| * |
| * @param name Name of the parameter to remove |
| */ |
| @Override |
| public void removeParameter(String name) { |
| |
| synchronized (parameters) { |
| parameters.remove(name); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeParameter", name); |
| } |
| } |
| |
| /** |
| * Remove any resource reference with the specified name. |
| * |
| * @param resourceName Name of the resource reference to remove |
| */ |
| @Override |
| public void removeResource(String resourceName) { |
| String decoded = URLDecoder.decode(resourceName); |
| if (namingResources == null) { |
| return; |
| } |
| ContextResource resource = namingResources.findResource(decoded); |
| if (resource == null) { |
| throw new IllegalArgumentException |
| ("Invalid resource name '" + decoded + "'"); |
| } |
| |
| namingResources.removeResource(decoded); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeResource", decoded); |
| } |
| } |
| |
| /** |
| * Remove any resource environment reference with the specified name. |
| * |
| * @param name Name of the resource environment reference to remove |
| */ |
| @Override |
| public void removeResourceEnvRef(String name) { |
| |
| namingResources.removeResourceEnvRef(name); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeResourceEnvRef", name); |
| } |
| } |
| |
| /** |
| * Remove any resource link with the specified name. |
| * |
| * @param link Name of the resource link to remove |
| */ |
| @Override |
| public void removeResourceLink(String link) { |
| String decoded = URLDecoder.decode(link); |
| if (namingResources == null) { |
| return; |
| } |
| ContextResourceLink resource = namingResources.findResourceLink(decoded); |
| if (resource == null) { |
| throw new IllegalArgumentException |
| ("Invalid resource name '" + decoded + "'"); |
| } |
| |
| namingResources.removeResourceLink(decoded); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeResourceLink", decoded); |
| } |
| } |
| |
| /** |
| * Remove any security role reference for the specified name |
| * |
| * @param role Security role (as used in the application) to remove |
| */ |
| @Override |
| public void removeRoleMapping(String role) { |
| synchronized (roleMappings) { |
| roleMappings.remove(role); |
| } |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeRoleMapping", role); |
| } |
| } |
| |
| /** |
| * Remove any servlet mapping for the specified pattern, if it exists; |
| * otherwise, no action is taken. |
| * |
| * @param pattern URL pattern of the mapping to remove |
| */ |
| @Override |
| public void removeServletMapping(String pattern) { |
| |
| String name = null; |
| synchronized (servletMappings) { |
| name = servletMappings.remove(pattern); |
| } |
| Wrapper wrapper = (Wrapper) findChild(name); |
| if( wrapper != null ) { |
| wrapper.removeMapping(pattern); |
| } |
| mapper.removeWrapper(pattern); |
| |
| if (notifyContainerListeners) { |
| fireContainerEvent("removeServletMapping", pattern); |
| } |
| } |
| |
| /** |
| * Checks whether this web application has any watched resources |
| * defined. |
| */ |
| @Override |
| public boolean hasWatchedResources() { |
| return !watchedResources.isEmpty(); |
| } |
| |
| /** |
| * Clears any watched resources defined for this web application. |
| */ |
| @Override |
| public void removeWatchedResources() { |
| synchronized (watchedResources) { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<String> i = watchedResources.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeWatchedResource", i.next()); |
| } |
| } |
| watchedResources.clear(); |
| } |
| } |
| |
| @Override |
| public void removeWelcomeFiles() { |
| if (notifyContainerListeners) { |
| for (String welcomeFile : welcomeFiles) { |
| fireContainerEvent("removeWelcomeFile", welcomeFile); |
| } |
| } |
| welcomeFiles = new String[0]; |
| } |
| |
| @Override |
| public void removeWrapperLifecycles() { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<String> i = wrapperLifecycles.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeWrapperLifecycle", i.next()); |
| } |
| } |
| wrapperLifecycles.clear(); |
| } |
| |
| @Override |
| public void removeWrapperListeners() { |
| // Inform interested listeners |
| if (notifyContainerListeners) { |
| Iterator<String> i = wrapperListeners.iterator(); |
| while (i.hasNext()) { |
| fireContainerEvent("removeWrapperListener", i.next()); |
| } |
| } |
| wrapperListeners.clear(); |
| } |
| |
| @Override |
| public void fireRequestInitializedEvent(ServletRequest request) { |
| List<EventListener> listeners = getApplicationEventListeners(); |
| ServletRequestEvent event = null; |
| if (!listeners.isEmpty()) { |
| event = new ServletRequestEvent(getServletContext(), request); |
| // create pre-service event |
| Iterator<EventListener> iter = listeners.iterator(); |
| while (iter.hasNext()) { |
| EventListener eventListener = iter.next(); |
| if (!(eventListener instanceof ServletRequestListener)) { |
| continue; |
| } |
| ServletRequestListener listener = |
| (ServletRequestListener) eventListener; |
| // START SJSAS 6329662 |
| fireContainerEvent(ContainerEvent.BEFORE_REQUEST_INITIALIZED, |
| listener); |
| // END SJSAS 6329662 |
| try { |
| listener.requestInitialized(event); |
| } catch (Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.REQUEST_INIT_EXCEPTION), |
| listener.getClass().getName()); |
| log.log(Level.WARNING, msg, t); |
| request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); |
| // START SJSAS 6329662 |
| } finally { |
| fireContainerEvent(ContainerEvent.AFTER_REQUEST_INITIALIZED, |
| listener); |
| // END SJSAS 6329662 |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void fireRequestDestroyedEvent(ServletRequest request) { |
| List<EventListener> listeners = getApplicationEventListeners(); |
| if (!listeners.isEmpty()) { |
| // create post-service event |
| ServletRequestEvent event = new ServletRequestEvent(getServletContext(), |
| request); |
| int len = listeners.size(); |
| for (int i = 0; i < len; i++) { |
| EventListener eventListener = listeners.get((len - 1) - i); |
| if (!(eventListener instanceof ServletRequestListener)) { |
| continue; |
| } |
| ServletRequestListener listener = |
| (ServletRequestListener) eventListener; |
| // START SJSAS 6329662 |
| fireContainerEvent(ContainerEvent.BEFORE_REQUEST_DESTROYED, |
| listener); |
| // END SJSAS 6329662 |
| try { |
| listener.requestDestroyed(event); |
| } catch (Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.REQUEST_DESTROY_EXCEPTION), |
| listener.getClass().getName()); |
| log.log(Level.WARNING, msg, t); |
| request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); |
| // START SJSAS 6329662 |
| } finally { |
| fireContainerEvent(ContainerEvent.AFTER_REQUEST_DESTROYED, |
| listener); |
| // END SJSAS 6329662 |
| } |
| } |
| } |
| } |
| |
| // --------------------------------------------------------- Public Methods |
| |
| /** |
| * Configure and initialize the set of filters for this Context. |
| * Return <code>true</code> if all filter initialization completed |
| * successfully, or <code>false</code> otherwise. |
| */ |
| public boolean filterStart() { |
| |
| if (log.isLoggable(Level.FINE)) |
| log.log(Level.FINE, "Starting filters"); |
| // Instantiate and record a FilterConfig for each defined filter |
| boolean ok = true; |
| synchronized (filterConfigs) { |
| filterConfigs.clear(); |
| for (String name : filterDefs.keySet()) { |
| String safeName = neutralizeForLog(name); |
| if(log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, " Starting filter '" + safeName + "'"); |
| } |
| try { |
| filterConfigs.put(name, |
| new ApplicationFilterConfig(this, |
| filterDefs.get(name))); |
| } catch(Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTING_FILTER_EXCEPTION), safeName); |
| getServletContext().log(msg, t); |
| ok = false; |
| } |
| } |
| } |
| |
| return (ok); |
| |
| } |
| |
| /** |
| * Finalize and release the set of filters for this Context. |
| * Return <code>true</code> if all filter finalization completed |
| * successfully, or <code>false</code> otherwise. |
| */ |
| public boolean filterStop() { |
| |
| if (log.isLoggable(Level.FINE)) |
| log.log(Level.FINE, "Stopping filters"); |
| |
| // Release all Filter and FilterConfig instances |
| synchronized (filterConfigs) { |
| for (String filterName : filterConfigs.keySet()) { |
| String safeFilterName = neutralizeForLog(filterName); |
| if(log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, " Stopping filter '" + safeFilterName + "'"); |
| } |
| ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)filterConfigs.get(filterName); |
| filterConfig.release(); |
| } |
| filterConfigs.clear(); |
| } |
| return (true); |
| } |
| |
| /** |
| * Find and return the initialized <code>FilterConfig</code> for the |
| * specified filter name, if any; otherwise return <code>null</code>. |
| * |
| * @param name Name of the desired filter |
| */ |
| public FilterConfig findFilterConfig(String name) { |
| return filterConfigs.get(name); |
| } |
| |
| /** |
| * Notifies all ServletContextListeners at their contextInitialized |
| * method. |
| */ |
| protected void contextListenerStart() { |
| ServletContextEvent event = new ServletContextEvent( |
| getServletContext()); |
| for (ServletContextListener listener : contextListeners) { |
| if (listener instanceof RestrictedServletContextListener) { |
| listener = ((RestrictedServletContextListener) listener). |
| getNestedListener(); |
| context.setRestricted(true); |
| } |
| try { |
| fireContainerEvent(ContainerEvent.BEFORE_CONTEXT_INITIALIZED, |
| listener); |
| listener.contextInitialized(event); |
| } finally { |
| context.setRestricted(false); |
| fireContainerEvent(ContainerEvent.AFTER_CONTEXT_INITIALIZED, |
| listener); |
| } |
| } |
| |
| /* |
| * Make sure there are no preliminary servlet or filter |
| * registrations left after all listeners have been notified |
| */ |
| Collection<ServletRegistrationImpl> servletRegistrations = |
| servletRegisMap.values(); |
| for (ServletRegistrationImpl regis : servletRegistrations) { |
| if (null == regis.getClassName() && null == regis.getJspFile()) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_WITHOUT_ANY_CLASS_OR_JSP), regis.getName()); |
| throw new IllegalStateException(msg); |
| } |
| } |
| Collection<FilterRegistrationImpl> filterRegistrations = |
| filterRegisMap.values(); |
| for (FilterRegistrationImpl regis : filterRegistrations) { |
| if (null == regis.getClassName()) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.FILTER_WITHOUT_ANY_CLASS), regis.getName()); |
| throw new IllegalStateException(msg); |
| } |
| } |
| |
| isContextInitializedCalled = true; |
| } |
| |
| |
| /** |
| * Loads and instantiates the listener with the specified classname. |
| * |
| * @param loader the classloader to use |
| * @param listenerClassName the fully qualified classname to instantiate |
| * |
| * @return the instantiated listener |
| * |
| * @throws Exception if the specified classname fails to be loaded or |
| * instantiated |
| */ |
| @SuppressWarnings("unchecked") |
| protected EventListener loadListener(ClassLoader loader, |
| String listenerClassName) |
| throws Exception { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Configuring event listener class '" + |
| neutralizeForLog(listenerClassName) + "'"); |
| } |
| return createListener((Class<EventListener>) |
| loader.loadClass(listenerClassName)); |
| } |
| |
| /** |
| * Notifies all ServletContextListeners at their contextDestroyed |
| * method. |
| * |
| * @return <code>true</code> if the event was processed successfully, |
| * <code>false</code> otherwise. |
| */ |
| private boolean contextListenerStop() { |
| |
| boolean ok = true; |
| |
| if (contextListeners.isEmpty()) { |
| return ok; |
| } |
| |
| ServletContextEvent event = new ServletContextEvent( |
| getServletContext()); |
| int len = contextListeners.size(); |
| for (int i = 0; i < len; i++) { |
| // Invoke in reverse order of declaration |
| ServletContextListener listener = |
| contextListeners.get((len - 1) - i); |
| if (listener instanceof RestrictedServletContextListener) { |
| listener = ((RestrictedServletContextListener) listener). |
| getNestedListener(); |
| context.setRestricted(true); |
| } |
| try { |
| fireContainerEvent(ContainerEvent.BEFORE_CONTEXT_DESTROYED, |
| listener); |
| listener.contextDestroyed(event); |
| fireContainerEvent(ContainerEvent.AFTER_CONTEXT_DESTROYED, |
| listener); |
| } catch (Throwable t) { |
| context.setRestricted(false); |
| fireContainerEvent(ContainerEvent.AFTER_CONTEXT_DESTROYED, |
| listener); |
| String msg = MessageFormat.format(rb.getString(LogFacade.LISTENER_STOP_EXCEPTION), |
| listener.getClass().getName()); |
| getServletContext().log(msg, t); |
| ok = false; |
| } |
| } |
| |
| contextListeners.clear(); |
| |
| return ok; |
| } |
| |
| private void sessionListenerStop() { |
| for (HttpSessionListener listener : sessionListeners) { |
| // ServletContextListeners already had their PreDestroy called |
| if (!(listener instanceof ServletContextListener)) { |
| fireContainerEvent(ContainerEvent.PRE_DESTROY, listener); |
| } |
| } |
| sessionListeners.clear(); |
| } |
| |
| private boolean eventListenerStop() { |
| if (eventListeners.isEmpty()) { |
| return true; |
| } |
| |
| Iterator<EventListener> iter = eventListeners.iterator(); |
| while (iter.hasNext()) { |
| EventListener listener = iter.next(); |
| // ServletContextListeners and HttpSessionListeners |
| // already had their PreDestroy called |
| if (listener instanceof ServletContextListener || |
| listener instanceof HttpSessionListener) { |
| continue; |
| } |
| fireContainerEvent(ContainerEvent.PRE_DESTROY, listener); |
| } |
| |
| eventListeners.clear(); |
| |
| return true; |
| } |
| |
| /** |
| * Merge the context initialization parameters specified in the application |
| * deployment descriptor with the application parameters described in the |
| * server configuration, respecting the <code>override</code> property of |
| * the application parameters appropriately. |
| */ |
| private void mergeParameters() { |
| Map<String,String> mergedParams = new HashMap<>(); |
| |
| for (String name : findParameters()) { |
| mergedParams.put(name, findParameter(name)); |
| } |
| |
| for (ApplicationParameter param : findApplicationParameters()) { |
| if (param.getOverride()) { |
| if (mergedParams.get(param.getName()) == null) |
| mergedParams.put(param.getName(), param.getValue()); |
| } else { |
| mergedParams.put(param.getName(), param.getValue()); |
| } |
| } |
| |
| ServletContext sc = getServletContext(); |
| for (Map.Entry<String,String> entry : mergedParams.entrySet()) { |
| sc.setInitParameter(entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| /** |
| * Allocate resources, including proxy. |
| * Return <code>true</code> if initialization was successfull, |
| * or <code>false</code> otherwise. |
| */ |
| public boolean resourcesStart() { |
| |
| boolean ok = true; |
| |
| Hashtable<String, String> env = new Hashtable<String, String>(); |
| if(getParent() != null) { |
| env.put(ProxyDirContext.HOST, getParent().getName()); |
| } |
| env.put(ProxyDirContext.CONTEXT, getName()); |
| try { |
| ProxyDirContext proxyDirContext = new ProxyDirContext(env, webappResources); |
| if(webappResources instanceof BaseDirContext) { |
| ((BaseDirContext)webappResources).setDocBase(getBasePath(getDocBase())); |
| ((BaseDirContext)webappResources).allocate(); |
| } |
| this.resources = proxyDirContext; |
| } catch(Throwable t) { |
| if(log.isLoggable(Level.FINE)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTING_RESOURCES_EXCEPTION), neutralizeForLog(getName())); |
| log.log(Level.SEVERE, msg, t); |
| } else { |
| log.log(Level.SEVERE, LogFacade.STARTING_RESOURCE_EXCEPTION_MESSAGE, |
| new Object[] {neutralizeForLog(getName()), t.getMessage()}); |
| } |
| ok = false; |
| } |
| |
| return ok; |
| } |
| |
| /** |
| * Starts this context's alternate doc base resources. |
| */ |
| public void alternateResourcesStart() throws LifecycleException { |
| |
| if (alternateDocBases == null || alternateDocBases.isEmpty()) { |
| return; |
| } |
| |
| Hashtable<String, String> env = new Hashtable<String, String>(); |
| if (getParent() != null) { |
| env.put(ProxyDirContext.HOST, getParent().getName()); |
| } |
| env.put(ProxyDirContext.CONTEXT, getName()); |
| for(AlternateDocBase alternateDocBase : alternateDocBases) { |
| String basePath = alternateDocBase.getBasePath(); |
| DirContext alternateWebappResources = ContextsAdapterUtility.unwrap( |
| alternateDocBase.getWebappResources()); |
| try { |
| ProxyDirContext proxyDirContext = new ProxyDirContext(env, alternateWebappResources); |
| if(alternateWebappResources instanceof BaseDirContext) { |
| ((BaseDirContext)alternateWebappResources).setDocBase(basePath); |
| ((BaseDirContext)alternateWebappResources).allocate(); |
| } |
| alternateDocBase.setResources(ContextsAdapterUtility.wrap(proxyDirContext)); |
| } catch(Throwable t) { |
| if(log.isLoggable(Level.FINE)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTING_RESOURCES_EXCEPTION), getName()); |
| throw new LifecycleException(msg, t); |
| } else { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTING_RESOURCE_EXCEPTION_MESSAGE), |
| new Object[] {getName(), t.getMessage()}); |
| throw new LifecycleException(msg); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Deallocate resources and destroy proxy. |
| */ |
| public boolean resourcesStop() { |
| |
| boolean ok = true; |
| |
| try { |
| if (resources != null) { |
| if (resources instanceof Lifecycle) { |
| ((Lifecycle) resources).stop(); |
| } |
| if (webappResources instanceof BaseDirContext) { |
| ((BaseDirContext) webappResources).release(); |
| } |
| } |
| } catch (Throwable t) { |
| log.log(Level.SEVERE, LogFacade.STOPPING_RESOURCES_EXCEPTION, t); |
| ok = false; |
| } |
| |
| this.resources = null; |
| |
| return (ok); |
| |
| } |
| |
| /** |
| * Stops this context's alternate doc base resources. |
| */ |
| public boolean alternateResourcesStop() { |
| |
| boolean ok = true; |
| |
| if (alternateDocBases == null || alternateDocBases.isEmpty()) { |
| return ok; |
| } |
| for(AlternateDocBase alternateDocBase : alternateDocBases) { |
| final DirContext alternateResources = ContextsAdapterUtility.unwrap( |
| alternateDocBase.getResources()); |
| if(alternateResources instanceof Lifecycle) { |
| try { |
| ((Lifecycle)alternateResources).stop(); |
| } catch(Throwable t) { |
| log.log(Level.SEVERE, LogFacade.STOPPING_RESOURCES_EXCEPTION, t); |
| ok = false; |
| } |
| } |
| final DirContext alternateWebappResources = ContextsAdapterUtility.unwrap( |
| alternateDocBase.getWebappResources()); |
| if(alternateWebappResources instanceof BaseDirContext) { |
| try { |
| ((BaseDirContext)alternateWebappResources).release(); |
| } catch(Throwable t) { |
| log.log(Level.SEVERE, LogFacade.STOPPING_RESOURCES_EXCEPTION, t); |
| ok = false; |
| } |
| } |
| } |
| |
| this.alternateDocBases = null; |
| |
| return (ok); |
| } |
| |
| /** |
| * Load and initialize all servlets marked "load on startup" in the |
| * web application deployment descriptor. |
| * |
| * @param children Array of wrappers for all currently defined |
| * servlets (including those not declared load on startup) |
| */ |
| /* SJSAS 6377790 |
| public void loadOnStartup(Container children[]){ |
| */ |
| // START SJSAS 6377790 |
| public void loadOnStartup(Container children[]) throws LifecycleException { |
| // END SJSAS 6377790 |
| // Collect "load on startup" servlets that need to be initialized |
| Map<Integer, List<Wrapper>> map = |
| new TreeMap<Integer, List<Wrapper>>(); |
| for (Container aChildren : children) { |
| Wrapper wrapper = (Wrapper)aChildren; |
| int loadOnStartup = wrapper.getLoadOnStartup(); |
| if(loadOnStartup < 0) { |
| continue; |
| } |
| Integer key = loadOnStartup; |
| List<Wrapper> list = map.get(key); |
| if(list == null) { |
| list = new ArrayList<Wrapper>(); |
| map.put(key, list); |
| } |
| list.add(wrapper); |
| } |
| |
| // Load the collected "load on startup" servlets |
| for (List<Wrapper> list : map.values()) { |
| for(Wrapper wrapper : list) { |
| try { |
| wrapper.load(); |
| } catch(ServletException e) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_LOAD_EXCEPTION), neutralizeForLog(getName())); |
| getServletContext().log(msg, StandardWrapper.getRootCause(e)); |
| // NOTE: load errors (including a servlet that throws |
| // UnavailableException from the init() method) are NOT |
| // fatal to application startup |
| // START SJSAS 6377790 |
| throw new LifecycleException( |
| StandardWrapper.getRootCause(e)); |
| // END SJSAS 6377790 |
| } |
| } |
| } |
| } |
| |
| /** |
| * Starts the session manager of this Context. |
| */ |
| protected void managerStart() throws LifecycleException { |
| if ((manager != null) && (manager instanceof Lifecycle)) { |
| ((Lifecycle) getManager()).start(); |
| } |
| } |
| |
| |
| /** |
| * Stops the session manager of this Context. |
| */ |
| protected void managerStop() throws LifecycleException { |
| if ((manager != null) && (manager instanceof Lifecycle)) { |
| ((Lifecycle) manager).stop(); |
| } |
| } |
| |
| /** |
| * Start this Context component. |
| * |
| * @exception LifecycleException if a startup error occurs |
| */ |
| @Override |
| public synchronized void start() throws LifecycleException { |
| |
| if (started) { |
| if (log.isLoggable(Level.INFO)) { |
| log.log(Level.INFO, LogFacade.CONTAINER_ALREADY_STARTED_EXCEPTION, neutralizeForLog(logName())); |
| } |
| return; |
| } |
| |
| long startupTimeStart = System.currentTimeMillis(); |
| |
| if(!initialized) { |
| try { |
| init(); |
| } catch( Exception ex ) { |
| throw new LifecycleException("Error initializaing ", ex); |
| } |
| } |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Starting " + |
| ("".equals(getName()) ? "ROOT" : neutralizeForLog(getName()))); |
| } |
| |
| // Set JMX object name for proper pipeline registration |
| preRegisterJMX(); |
| |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); |
| |
| setAvailable(false); |
| setConfigured(false); |
| |
| // Add missing components as necessary |
| if (webappResources == null) { // (1) Required by Loader |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Configuring default Resources"); |
| } |
| try { |
| if ((docBase != null) && (docBase.endsWith(".war")) && |
| (!(new File(docBase).isDirectory()))) |
| setResources(new WARDirContext()); |
| else |
| setResources(new WebDirContext()); |
| } catch (IllegalArgumentException e) { |
| throw new LifecycleException(rb.getString(LogFacade.INIT_RESOURCES_EXCEPTION), e); |
| } |
| } |
| |
| resourcesStart(); |
| |
| // Add alternate resources |
| if (alternateDocBases != null && !alternateDocBases.isEmpty()) { |
| for(AlternateDocBase alternateDocBase : alternateDocBases) { |
| String docBase = alternateDocBase.getDocBase(); |
| if(log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Configuring alternate resources"); |
| } |
| try { |
| if(docBase != null && docBase.endsWith(".war") && |
| (!(new File(docBase).isDirectory()))) { |
| setAlternateResources(alternateDocBase, |
| new WARDirContext()); |
| } else { |
| setAlternateResources(alternateDocBase, |
| new FileDirContext()); |
| } |
| } catch(IllegalArgumentException e) { |
| throw new LifecycleException(rb.getString(LogFacade.INIT_RESOURCES_EXCEPTION), e); |
| } |
| } |
| |
| alternateResourcesStart(); |
| } |
| |
| if (getLoader() == null) { |
| createLoader(); |
| } |
| |
| // Initialize character set mapper |
| getCharsetMapper(); |
| |
| // Post work directory |
| postWorkDirectory(); |
| |
| // Validate required extensions |
| try { |
| ExtensionValidator.validateApplication(getResources(), this); |
| } catch (IOException ioe) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.DEPENDENCY_CHECK_EXCEPTION), this); |
| throw new LifecycleException(msg, ioe); |
| } |
| |
| // Reading the "catalina.useNaming" environment variable |
| String useNamingProperty = System.getProperty("catalina.useNaming"); |
| if ((useNamingProperty != null) && |
| ("false".equals(useNamingProperty))) { |
| useNaming = false; |
| } |
| |
| if (isUseNaming()) { |
| if (namingContextListener == null) { |
| namingContextListener = new NamingContextListener(); |
| namingContextListener.setDebug(getDebug()); |
| namingContextListener.setName(getNamingContextName()); |
| addLifecycleListener(namingContextListener); |
| } |
| } |
| |
| // Binding thread |
| // START OF SJSAS 8.1 6174179 |
| //ClassLoader oldCCL = bindThread(); |
| ClassLoader oldCCL = null; |
| // END OF SJSAS 8.1 6174179 |
| |
| try { |
| started = true; |
| |
| // Start our subordinate components, if any |
| if ((loader != null) && (loader instanceof Lifecycle)) |
| ((Lifecycle) loader).start(); |
| if ((logger != null) && (logger instanceof Lifecycle)) |
| ((Lifecycle) logger).start(); |
| |
| // Unbinding thread |
| // START OF SJSAS 8.1 6174179 |
| //unbindThread(oldCCL); |
| // END OF SJSAS 8.1 6174179 |
| |
| // Binding thread |
| oldCCL = bindThread(); |
| |
| if ((realm != null) && (realm instanceof Lifecycle)) |
| ((Lifecycle) realm).start(); |
| if ((resources != null) && (resources instanceof Lifecycle)) |
| ((Lifecycle) resources).start(); |
| |
| // Start our child containers, if any |
| for (Container child : findChildren()) { |
| if(child instanceof Lifecycle) { |
| ((Lifecycle)child).start(); |
| } |
| } |
| |
| // Start the Valves in our pipeline (including the basic), |
| // if any |
| if (pipeline instanceof Lifecycle) |
| ((Lifecycle) pipeline).start(); |
| |
| // START SJSAS 8.1 5049111 |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(START_EVENT, null); |
| // END SJSAS 8.1 5049111 |
| } catch (Throwable t) { |
| throw new LifecycleException(t); |
| } finally { |
| // Unbinding thread |
| unbindThread(oldCCL); |
| } |
| |
| if (!getConfigured()) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.STARTUP_CONTEXT_FAILED_EXCEPTION), getName()); |
| throw new LifecycleException(msg); |
| } |
| |
| // Store some required info as ServletContext attributes |
| postResources(); |
| if (orderedLibs != null && !orderedLibs.isEmpty()) { |
| getServletContext().setAttribute(ServletContext.ORDERED_LIBS, |
| orderedLibs); |
| context.setAttributeReadOnly(ServletContext.ORDERED_LIBS); |
| } |
| |
| // Initialize associated mapper |
| mapper.setContext(getPath(), welcomeFiles, ContextsAdapterUtility.wrap(resources)); |
| |
| // Binding thread |
| oldCCL = bindThread(); |
| |
| try { |
| // Set up the context init params |
| mergeParameters(); |
| |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); |
| |
| // Support for pluggability : this has to be done before |
| // listener events are fired |
| callServletContainerInitializers(); |
| |
| // Configure and call application event listeners |
| contextListenerStart(); |
| |
| // Start manager |
| if ((manager != null) && (manager instanceof Lifecycle)) { |
| ((Lifecycle) getManager()).start(); |
| } |
| |
| // Start ContainerBackgroundProcessor thread |
| super.threadStart(); |
| |
| // Configure and call application filters |
| filterStart(); |
| |
| // Load and initialize all "load on startup" servlets |
| loadOnStartup(findChildren()); |
| } catch (Throwable t) { |
| log.log(Level.SEVERE, LogFacade.STARTUP_CONTEXT_FAILED_EXCEPTION, getName()); |
| try { |
| stop(); |
| } catch (Throwable tt) { |
| log.log(Level.SEVERE, LogFacade.CLEANUP_FAILED_EXCEPTION, tt); |
| } |
| throw new LifecycleException(t); |
| } finally { |
| // Unbinding thread |
| unbindThread(oldCCL); |
| } |
| |
| // Set available status depending upon startup success |
| if (log.isLoggable(Level.FINEST)) { |
| log.log(Level.FINEST, "Startup successfully completed"); |
| } |
| |
| setAvailable(true); |
| |
| // JMX registration |
| registerJMX(); |
| |
| startTimeMillis = System.currentTimeMillis(); |
| startupTime = startTimeMillis - startupTimeStart; |
| |
| // Send j2ee.state.running notification |
| if (getObjectName() != null) { |
| Notification notification = |
| new Notification("j2ee.state.running", this, sequenceNumber++); |
| sendNotification(notification); |
| } |
| |
| // Close all JARs right away to avoid always opening a peak number |
| // of files on startup |
| if (getLoader() instanceof WebappLoader) { |
| ((WebappLoader) getLoader()).closeJARs(true); |
| } |
| } |
| |
| protected Types getTypes() { |
| return null; |
| } |
| |
| protected void callServletContainerInitializers() |
| throws LifecycleException { |
| |
| // Get the list of ServletContainerInitializers and the classes |
| // they are interested in |
| Map<Class<?>, List<Class<? extends ServletContainerInitializer>>> interestList = |
| ServletContainerInitializerUtil.getInterestList( |
| servletContainerInitializers); |
| Map<Class<? extends ServletContainerInitializer>, Set<Class<?>>> initializerList = |
| ServletContainerInitializerUtil.getInitializerList( |
| servletContainerInitializers, interestList, |
| getTypes(), |
| getClassLoader()); |
| if (initializerList == null) { |
| return; |
| } |
| |
| // Allow programmatic registration of ServletContextListeners, but |
| // only within the scope of ServletContainerInitializer#onStartup |
| isProgrammaticServletContextListenerRegistrationAllowed = true; |
| |
| // We have the list of initializers and the classes that satisfy |
| // the condition. Time to call the initializers |
| ServletContext ctxt = this.getServletContext(); |
| try { |
| for (Map.Entry<Class<? extends ServletContainerInitializer>, Set<Class<?>>> e : |
| initializerList.entrySet()) { |
| Class<? extends ServletContainerInitializer> initializer = e.getKey(); |
| // See IT 11333 |
| if (isUseMyFaces() && |
| Globals.FACES_INITIALIZER.equals(initializer.getName())) { |
| continue; |
| } |
| try { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Calling ServletContainerInitializer [" + initializer |
| + "] onStartup with classes " + e.getValue()); |
| } |
| ServletContainerInitializer iniInstance = |
| initializer.newInstance(); |
| fireContainerEvent(ContainerEvent.BEFORE_CONTEXT_INITIALIZER_ON_STARTUP, |
| iniInstance); |
| iniInstance.onStartup( |
| initializerList.get(initializer), ctxt); |
| fireContainerEvent(ContainerEvent.AFTER_CONTEXT_INITIALIZER_ON_STARTUP, |
| iniInstance); |
| } catch (Throwable t) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.INVOKING_SERVLET_CONTAINER_INIT_EXCEPTION), |
| initializer.getCanonicalName()); |
| log.log(Level.SEVERE, msg, t); |
| throw new LifecycleException(t); |
| } |
| } |
| } finally { |
| isProgrammaticServletContextListenerRegistrationAllowed = false; |
| } |
| } |
| |
| public void setServletContainerInitializerInterestList( |
| Iterable<ServletContainerInitializer> initializers) |
| { |
| servletContainerInitializers = initializers; |
| } |
| |
| /** |
| * Creates a classloader for this context. |
| */ |
| public void createLoader() { |
| ClassLoader parent = null; |
| if (getPrivileged()) { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Configuring privileged default Loader"); |
| } |
| parent = this.getClass().getClassLoader(); |
| } else { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Configuring non-privileged default Loader"); |
| } |
| parent = getParentClassLoader(); |
| } |
| WebappLoader webappLoader = new WebappLoader(parent); |
| webappLoader.setDelegate(getDelegate()); |
| webappLoader.setUseMyFaces(useMyFaces); |
| setLoader(webappLoader); |
| } |
| |
| /** |
| * Stop this Context component. |
| * |
| * @exception LifecycleException if a shutdown error occurs |
| */ |
| @Override |
| public synchronized void stop() throws LifecycleException { |
| stop(false); |
| } |
| |
| /** |
| * Stop this Context component. |
| * |
| * @param isShutdown true if this Context is being stopped as part |
| * of a domain shutdown (as opposed to an undeployment), and false otherwise |
| * @exception LifecycleException if a shutdown error occurs |
| */ |
| public synchronized void stop(boolean isShutdown) |
| throws LifecycleException { |
| |
| // Validate and update our current component state |
| if (!started) { |
| if(log.isLoggable(Level.INFO)) { |
| log.log(Level.INFO, LogFacade.CONTAINER_NOT_STARTED_EXCEPTION, logName()); |
| } |
| return; |
| } |
| |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); |
| |
| // Send j2ee.state.stopping notification |
| if (this.getObjectName() != null) { |
| Notification notification = |
| new Notification("j2ee.state.stopping", this, sequenceNumber++); |
| sendNotification(notification); |
| } |
| |
| // Mark this application as unavailable while we shut down |
| setAvailable(false); |
| |
| // Binding thread |
| ClassLoader oldCCL = bindThread(); |
| |
| try { |
| // Stop our child containers, if any |
| for (Container child : findChildren()) { |
| if(child instanceof Lifecycle) { |
| ((Lifecycle)child).stop(); |
| } |
| } |
| |
| // Stop our filters |
| filterStop(); |
| |
| // Stop ContainerBackgroundProcessor thread |
| super.threadStop(); |
| |
| if ((manager != null) && (manager instanceof Lifecycle)) { |
| if(manager instanceof StandardManager) { |
| ((StandardManager)manager).stop(isShutdown); |
| } else { |
| ((Lifecycle)manager).stop(); |
| } |
| } |
| |
| /* |
| * Stop all ServletContextListeners. It is important that they |
| * are passed a ServletContext to their contextDestroyed() method |
| * that still has all its attributes set. In other words, it is |
| * important that we invoke these listeners before calling |
| * context.clearAttributes() |
| */ |
| contextListenerStop(); |
| |
| sessionListenerStop(); |
| |
| // Clear all application-originated servlet context attributes |
| if (context != null) { |
| context.clearAttributes(); |
| } |
| |
| /* |
| * Stop all event listeners, including those of type |
| * ServletContextAttributeListener. For the latter, it is |
| * important that we invoke them after calling |
| * context.clearAttributes, so that they receive the corresponding |
| * attribute removal events |
| */ |
| eventListenerStop(); |
| |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(STOP_EVENT, null); |
| started = false; |
| |
| // Stop the Valves in our pipeline (including the basic), if any |
| if (pipeline instanceof Lifecycle) { |
| ((Lifecycle) pipeline).stop(); |
| } |
| |
| // Finalize our character set mapper |
| setCharsetMapper(null); |
| |
| // Stop resources |
| resourcesStop(); |
| alternateResourcesStop(); |
| |
| if ((realm != null) && (realm instanceof Lifecycle)) { |
| ((Lifecycle) realm).stop(); |
| } |
| if ((logger != null) && (logger instanceof Lifecycle)) { |
| ((Lifecycle) logger).stop(); |
| } |
| /* SJSAS 6347606 |
| if ((loader != null) && (loader instanceof Lifecycle)) { |
| ((Lifecycle) loader).stop(); |
| } |
| */ |
| } catch(Throwable t) { |
| // started was "true" when it first enters the try block. |
| // Note that it is set to false after STOP_EVENT is fired. |
| // One need to fire STOP_EVENT to clean up naming information |
| // if START_EVENT is processed successfully. |
| if (started) { |
| lifecycle.fireLifecycleEvent(STOP_EVENT, null); |
| } |
| |
| if (t instanceof RuntimeException) { |
| throw (RuntimeException)t; |
| } else if (t instanceof LifecycleException) { |
| throw (LifecycleException)t; |
| } else { |
| throw new LifecycleException(t); |
| } |
| } finally { |
| |
| // Unbinding thread |
| unbindThread(oldCCL); |
| |
| // START SJSAS 6347606 |
| /* |
| * Delay the stopping of the webapp classloader until this point, |
| * because unbindThread() calls the security-checked |
| * Thread.setContextClassLoader(), which may ask the current thread |
| * context classloader (i.e., the webapp classloader) to load |
| * Principal classes specified in the security policy file |
| */ |
| if ((loader != null) && (loader instanceof Lifecycle)) { |
| ((Lifecycle) loader).stop(); |
| } |
| // END SJSAS 6347606 |
| } |
| |
| // Send j2ee.state.stopped notification |
| if (this.getObjectName() != null) { |
| Notification notification = |
| new Notification("j2ee.state.stopped", this ,sequenceNumber++); |
| sendNotification(notification); |
| } |
| |
| // Reset application context |
| context = null; |
| |
| // This object will no longer be visible or used. |
| try { |
| resetContext(); |
| } catch( Exception ex ) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.RESETTING_CONTEXT_EXCEPTION), this); |
| log.log(Level.SEVERE, msg, ex); |
| } |
| |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); |
| |
| if (log.isLoggable(Level.FINE)) |
| log.log(Level.FINE, "Stopping complete"); |
| |
| if(oname != null) { |
| // Send j2ee.object.deleted notification |
| Notification notification = |
| new Notification("j2ee.object.deleted", this, sequenceNumber++); |
| sendNotification(notification); |
| } |
| |
| } |
| |
| /** |
| * Destroys this context by cleaning it up completely. |
| * |
| * The problem is that undoing all the config in start() and restoring |
| * a 'fresh' state is impossible. After stop()/destroy()/init()/start() |
| * we should have the same state as if a fresh start was done - i.e |
| * read modified web.xml, etc. This can only be done by completely |
| * removing the context object and remapping a new one, or by cleaning |
| * up everything. |
| * |
| * XXX Should this be done in stop() ? |
| */ |
| @Override |
| public void destroy() throws Exception { |
| super.destroy(); |
| |
| // START SJASAS 6359401 |
| // super.destroy() will stop session manager and cause it to unload |
| // all its active sessions into a file. Delete this file, because this |
| // context is being destroyed and must not leave any traces. |
| if (getManager() instanceof ManagerBase) { |
| ((ManagerBase)getManager()).release(); |
| } |
| // END SJSAS 6359401 |
| |
| instanceListeners.clear(); |
| instanceListenerInstances.clear(); |
| } |
| |
| private void resetContext() throws Exception, MBeanRegistrationException { |
| // Restore the original state ( pre reading web.xml in start ) |
| // If you extend this - override this method and make sure to clean up |
| children=new HashMap<String, Container>(); |
| startupTime = 0; |
| startTimeMillis = 0; |
| tldScanTime = 0; |
| |
| // Bugzilla 32867 |
| distributable = false; |
| |
| eventListeners.clear(); |
| contextListeners.clear(); |
| sessionListeners.clear(); |
| |
| requestCharacterEncoding = null; |
| responseCharacterEncoding = DEFAULT_RESPONSE_CHARACTER_ENCODING; |
| |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "resetContext " + oname); |
| } |
| } |
| |
| /** |
| * Return a String representation of this component. |
| */ |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| if (getParent() != null) { |
| sb.append(getParent().toString()); |
| sb.append("."); |
| } |
| sb.append("StandardContext["); |
| sb.append(getName()); |
| sb.append("]"); |
| return (sb.toString()); |
| |
| } |
| |
| /** |
| * Execute a periodic task, such as reloading, etc. This method will be |
| * invoked inside the classloading context of this container. Unexpected |
| * throwables will be caught and logged. |
| */ |
| @Override |
| public void backgroundProcess() { |
| |
| if (!started) |
| return; |
| |
| count = (count + 1) % managerChecksFrequency; |
| |
| if ((getManager() != null) && (count == 0)) { |
| if (getManager() instanceof StandardManager) { |
| ((StandardManager) getManager()).processExpires(); |
| } else if (getManager() instanceof PersistentManagerBase) { |
| PersistentManagerBase pManager = |
| (PersistentManagerBase) getManager(); |
| pManager.backgroundProcess(); |
| } |
| } |
| |
| // START S1AS8PE 4965017 |
| if (isReload()) { |
| if (getLoader() != null) { |
| if (reloadable && (getLoader().modified())) { |
| try { |
| Thread.currentThread().setContextClassLoader |
| (standardContextClassLoader); |
| reload(); |
| } finally { |
| if (getLoader() != null) { |
| Thread.currentThread().setContextClassLoader |
| (getClassLoader()); |
| } |
| } |
| } |
| if (getLoader() instanceof WebappLoader) { |
| ((WebappLoader) getLoader()).closeJARs(false); |
| } |
| } |
| } |
| // END S1AS8PE 4965017 |
| } |
| |
| |
| // ------------------------------------------------------ Protected Methods |
| |
| /** |
| * Adjust the URL pattern to begin with a leading slash, if appropriate |
| * (i.e. we are running a servlet 2.2 application). Otherwise, return |
| * the specified URL pattern unchanged. |
| * |
| * @param urlPattern The URL pattern to be adjusted (if needed) |
| * and returned |
| */ |
| protected String adjustURLPattern(String urlPattern) { |
| |
| if (urlPattern == null) |
| return (urlPattern); |
| if (urlPattern.startsWith("/") || urlPattern.startsWith("*.")) |
| return (urlPattern); |
| if (!isServlet22()) |
| return (urlPattern); |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, LogFacade.URL_PATTERN_WARNING, urlPattern); |
| } |
| return ("/" + urlPattern); |
| |
| } |
| |
| /** |
| * Are we processing a version 2.2 deployment descriptor? |
| */ |
| protected boolean isServlet22() { |
| return publicId != null && publicId.equals( |
| org.apache.catalina.startup.Constants.WebDtdPublicId_22); |
| } |
| |
| /** |
| * Return a File object representing the base directory for the |
| * entire servlet container (i.e. the Engine container if present). |
| */ |
| protected File engineBase() { |
| String base=System.getProperty("catalina.base"); |
| if( base == null ) { |
| StandardEngine eng=(StandardEngine)this.getParent().getParent(); |
| base=eng.getBaseDir(); |
| } |
| return (new File(base)); |
| } |
| |
| // -------------------------------------------------------- Private Methods |
| |
| |
| /** |
| * Bind current thread, both for CL purposes and for JNDI ENC support |
| * during : startup, shutdown and realoading of the context. |
| * |
| * @return the previous context class loader |
| */ |
| private ClassLoader bindThread() { |
| ClassLoader oldContextClassLoader = |
| Thread.currentThread().getContextClassLoader(); |
| Thread.currentThread().setContextClassLoader(getClassLoader()); |
| if (isUseNaming()) { |
| try { |
| ContextBindings.bindThread(this, this); |
| } catch (Throwable e) { |
| log.log(Level.WARNING, LogFacade.BIND_THREAD_EXCEPTION, e); |
| } |
| } |
| |
| return oldContextClassLoader; |
| |
| } |
| |
| /** |
| * Unbind thread. |
| */ |
| private void unbindThread(ClassLoader oldContextClassLoader) { |
| Thread.currentThread().setContextClassLoader(oldContextClassLoader); |
| if (isUseNaming()) { |
| ContextBindings.unbindThread(this, this); |
| } |
| } |
| |
| /** |
| * Get base path. |
| */ |
| private String getBasePath(String docBase) { |
| String basePath = null; |
| Container container = this; |
| while (container != null) { |
| if (container instanceof Host) |
| break; |
| container = container.getParent(); |
| } |
| File file = new File(docBase); |
| if (!file.isAbsolute()) { |
| if (container == null) { |
| basePath = (new File(engineBase(), docBase)).getPath(); |
| } else { |
| // Use the "appBase" property of this container |
| String appBase = ((Host) container).getAppBase(); |
| file = new File(appBase); |
| if (!file.isAbsolute()) |
| file = new File(engineBase(), appBase); |
| basePath = (new File(file, docBase)).getPath(); |
| } |
| } else { |
| basePath = file.getPath(); |
| } |
| return basePath; |
| } |
| |
| /** |
| * Get app base. |
| * |
| private String getAppBase() { |
| String appBase = null; |
| Container container = this; |
| while (container != null) { |
| if (container instanceof Host) |
| break; |
| container = container.getParent(); |
| } |
| if (container != null) { |
| appBase = ((Host) container).getAppBase(); |
| } |
| return appBase; |
| } |
| |
| /** |
| * Get config base. |
| * |
| private File getConfigBase() { |
| File configBase = |
| new File(System.getProperty("catalina.base"), "conf"); |
| if (!configBase.exists()) { |
| return null; |
| } |
| Container container = this; |
| Container host = null; |
| Container engine = null; |
| while (container != null) { |
| if (container instanceof Host) |
| host = container; |
| if (container instanceof Engine) |
| engine = container; |
| container = container.getParent(); |
| } |
| if (engine != null) { |
| configBase = new File(configBase, engine.getName()); |
| } |
| if (host != null) { |
| configBase = new File(configBase, host.getName()); |
| } |
| configBase.mkdirs(); |
| return configBase; |
| } |
| */ |
| |
| /** |
| * Given a context path, get the config file name. |
| */ |
| protected String getDefaultConfigFile() { |
| String basename = null; |
| String path = getPath(); |
| if ("".equals(path)) { |
| basename = "ROOT"; |
| } else { |
| basename = path.substring(1).replace('/', '_'); |
| } |
| return (basename + ".xml"); |
| } |
| |
| /** |
| * Copy a file. |
| * |
| private boolean copy(File src, File dest) { |
| FileInputStream is = null; |
| FileOutputStream os = null; |
| try { |
| is = new FileInputStream(src); |
| os = new FileOutputStream(dest); |
| byte[] buf = new byte[4096]; |
| while (true) { |
| int len = is.read(buf); |
| if (len < 0) |
| break; |
| os.write(buf, 0, len); |
| } |
| is.close(); |
| os.close(); |
| } catch (IOException e) { |
| return false; |
| } finally { |
| try { |
| if (is != null) { |
| is.close(); |
| } |
| } catch (Exception e) { |
| // Ignore |
| } |
| try { |
| if (os != null) { |
| os.close(); |
| } |
| } catch (Exception e) { |
| // Ignore |
| } |
| } |
| return true; |
| } |
| */ |
| |
| |
| /** |
| * Get naming context full name. |
| */ |
| public String getNamingContextName() { |
| if (namingContextName == null) { |
| Container parent = getParent(); |
| if (parent == null) { |
| namingContextName = getName(); |
| } else { |
| Stack<String> stk = new Stack<String>(); |
| StringBuilder buff = new StringBuilder(); |
| while (parent != null) { |
| stk.push(parent.getName()); |
| parent = parent.getParent(); |
| } |
| while (!stk.empty()) { |
| buff.append("/").append(stk.pop()); |
| } |
| buff.append(getName()); |
| namingContextName = buff.toString(); |
| } |
| // START RIMOD 4868393 |
| // append an id to make the name unique to the instance. |
| namingContextName += instanceIDCounter.getAndIncrement(); |
| // END RIMOD 4868393 |
| } |
| return namingContextName; |
| } |
| |
| /** |
| * @return the request processing paused flag for this Context |
| */ |
| public boolean getPaused() { |
| return paused; |
| } |
| |
| /** |
| * Stores the resources of this application as ServletContext |
| * attributes. |
| */ |
| private void postResources() { |
| getServletContext().setAttribute( |
| Globals.RESOURCES_ATTR, getResources()); |
| context.setAttributeReadOnly(Globals.RESOURCES_ATTR); |
| getServletContext().setAttribute( |
| Globals.ALTERNATE_RESOURCES_ATTR, getAlternateDocBases()); |
| context.setAttributeReadOnly(Globals.ALTERNATE_RESOURCES_ATTR); |
| } |
| |
| public String getHostname() { |
| Container parentHost = getParent(); |
| if (parentHost != null) { |
| hostName = parentHost.getName(); |
| } |
| if ((hostName == null) || (hostName.length() < 1)) |
| hostName = "_"; |
| return hostName; |
| } |
| |
| /** |
| * Set the appropriate context attribute for our work directory. |
| */ |
| private void postWorkDirectory() { |
| |
| // Acquire (or calculate) the work directory path |
| String workDir = getWorkDir(); |
| if (workDir == null || workDir.length() == 0) { |
| |
| // Retrieve our parent (normally a host) name |
| String hostName = null; |
| String engineName = null; |
| String hostWorkDir = null; |
| Container parentHost = getParent(); |
| if (parentHost != null) { |
| hostName = parentHost.getName(); |
| if (parentHost instanceof StandardHost) { |
| hostWorkDir = ((StandardHost)parentHost).getWorkDir(); |
| } |
| Container parentEngine = parentHost.getParent(); |
| if (parentEngine != null) { |
| engineName = parentEngine.getName(); |
| } |
| } |
| if ((hostName == null) || (hostName.length() < 1)) |
| hostName = "_"; |
| if ((engineName == null) || (engineName.length() < 1)) |
| engineName = "_"; |
| |
| String temp = getPath(); |
| if (temp.startsWith("/")) |
| temp = temp.substring(1); |
| temp = temp.replace('/', '_'); |
| temp = temp.replace('\\', '_'); |
| if (temp.length() < 1) |
| temp = "_"; |
| if (hostWorkDir != null ) { |
| workDir = hostWorkDir + File.separator + temp; |
| } else { |
| workDir = "work" + File.separator + engineName + |
| File.separator + hostName + File.separator + temp; |
| } |
| setWorkDir(workDir); |
| } |
| |
| // Create this directory if necessary |
| File dir = new File(workDir); |
| if (!dir.isAbsolute()) { |
| File catalinaHome = engineBase(); |
| String catalinaHomePath = null; |
| try { |
| catalinaHomePath = catalinaHome.getCanonicalPath(); |
| dir = new File(catalinaHomePath, workDir); |
| } catch (IOException e) { |
| } |
| } |
| if (!dir.mkdirs() && !dir.isDirectory()) { |
| log.log(Level.SEVERE, LogFacade.CREATE_WORK_DIR_EXCEPTION, dir.getAbsolutePath()); |
| } |
| |
| // Set the appropriate servlet context attribute |
| getServletContext().setAttribute(ServletContext.TEMPDIR, dir); |
| context.setAttributeReadOnly(ServletContext.TEMPDIR); |
| |
| } |
| |
| /** |
| * Set the request processing paused flag for this Context. |
| * |
| * @param paused The new request processing paused flag |
| */ |
| private void setPaused(boolean paused) { |
| this.paused = paused; |
| } |
| |
| /** |
| * Validate the syntax of a proposed <code><url-pattern></code> |
| * for conformance with specification requirements. |
| * |
| * @param urlPattern URL pattern to be validated |
| */ |
| protected boolean validateURLPattern(String urlPattern) { |
| if (urlPattern == null) { |
| return false; |
| } |
| if (urlPattern.isEmpty()) { |
| return true; |
| } |
| if (urlPattern.indexOf('\n') >= 0 || urlPattern.indexOf('\r') >= 0) { |
| log.log(Level.WARNING, LogFacade.URL_PATTERN_CANNOT_BE_MATCHED_EXCEPTION, urlPattern); |
| return false; |
| } |
| if (urlPattern.startsWith("*.")) { |
| if (urlPattern.indexOf('/') < 0) { |
| checkUnusualURLPattern(urlPattern); |
| return true; |
| } else |
| return false; |
| } |
| if ( (urlPattern.startsWith("/")) && |
| (!urlPattern.contains("*."))) { |
| checkUnusualURLPattern(urlPattern); |
| return true; |
| } else |
| return false; |
| |
| } |
| |
| |
| /** |
| * Check for unusual but valid <code><url-pattern></code>s. |
| * See Bugzilla 34805, 43079 & 43080 |
| */ |
| private void checkUnusualURLPattern(String urlPattern) { |
| if (log.isLoggable(Level.INFO)) { |
| if(urlPattern.endsWith("*") && (urlPattern.length() < 2 || |
| urlPattern.charAt(urlPattern.length()-2) != '/')) { |
| String msg = "Suspicious url pattern: \"" + urlPattern + "\"" + |
| " in context [" + getName() + "] - see" + |
| " section SRV.11.2 of the Servlet specification"; |
| log.log(Level.INFO, msg); |
| } |
| } |
| } |
| |
| |
| // -------------------- JMX methods -------------------- |
| |
| /** |
| * Return the MBean Names of the set of defined environment entries for |
| * this web application |
| */ |
| public String[] getEnvironments() { |
| ContextEnvironment[] envs = getNamingResources().findEnvironments(); |
| List<String> results = new ArrayList<String>(); |
| for(ContextEnvironment env : envs) { |
| try { |
| ObjectName oname = createObjectName(env); |
| results.add(oname.toString()); |
| } catch(MalformedObjectNameException e) { |
| IllegalArgumentException iae = new IllegalArgumentException |
| ("Cannot create object name for environment " + env); |
| iae.initCause(e); |
| throw iae; |
| } |
| } |
| return results.toArray(new String[results.size()]); |
| |
| } |
| |
| |
| /** |
| * Return the MBean Names of all the defined resource references for this |
| * application. |
| */ |
| public String[] getResourceNames() { |
| |
| ContextResource[] resources = getNamingResources().findResources(); |
| List<String> results = new ArrayList<String>(); |
| for(ContextResource resource : resources) { |
| try { |
| ObjectName oname = createObjectName(resource); |
| results.add(oname.toString()); |
| } catch(MalformedObjectNameException e) { |
| IllegalArgumentException iae = new IllegalArgumentException |
| ("Cannot create object name for resource " + resource); |
| iae.initCause(e); |
| throw iae; |
| } |
| } |
| return results.toArray(new String[results.size()]); |
| |
| } |
| |
| /** |
| * Return the MBean Names of all the defined resource links for this |
| * application |
| */ |
| public String[] getResourceLinks() { |
| |
| ContextResourceLink[] links = getNamingResources().findResourceLinks(); |
| List<String> results = new ArrayList<String>(); |
| for(ContextResourceLink link : links) { |
| try { |
| ObjectName oname = createObjectName(link); |
| results.add(oname.toString()); |
| } catch(MalformedObjectNameException e) { |
| IllegalArgumentException iae = new IllegalArgumentException |
| ("Cannot create object name for resource " + link); |
| iae.initCause(e); |
| throw iae; |
| } |
| } |
| return results.toArray(new String[results.size()]); |
| |
| } |
| |
| // ------------------------------------------------------------- Operations |
| |
| |
| /** |
| * Add an environment entry for this web application. |
| * |
| * @param envName New environment entry name |
| */ |
| public String addEnvironment(String envName, String type) |
| throws MalformedObjectNameException { |
| |
| NamingResources nresources = getNamingResources(); |
| if (nresources == null) { |
| return null; |
| } |
| ContextEnvironment env = nresources.findEnvironment(envName); |
| if (env != null) { |
| throw new IllegalArgumentException |
| ("Invalid environment name - already exists '" + envName + "'"); |
| } |
| env = new ContextEnvironment(); |
| env.setName(envName); |
| env.setType(type); |
| nresources.addEnvironment(env); |
| |
| // Return the corresponding MBean name |
| return createObjectName(env).toString(); |
| |
| } |
| |
| |
| /** |
| * Add a resource reference for this web application. |
| * |
| * @param resourceName New resource reference name |
| */ |
| public String addResource(String resourceName, String type) |
| throws MalformedObjectNameException { |
| |
| NamingResources nresources = getNamingResources(); |
| if (nresources == null) { |
| return null; |
| } |
| ContextResource resource = nresources.findResource(resourceName); |
| if (resource != null) { |
| throw new IllegalArgumentException |
| ("Invalid resource name - already exists'" + resourceName + "'"); |
| } |
| resource = new ContextResource(); |
| resource.setName(resourceName); |
| resource.setType(type); |
| nresources.addResource(resource); |
| |
| // Return the corresponding MBean name |
| return createObjectName(resource).toString(); |
| } |
| |
| /** |
| * Add a resource link for this web application. |
| * |
| * @param resourceLinkName New resource link name |
| */ |
| public String addResourceLink(String resourceLinkName, String global, |
| String name, String type) throws MalformedObjectNameException { |
| |
| NamingResources nresources = getNamingResources(); |
| if (nresources == null) { |
| return null; |
| } |
| ContextResourceLink resourceLink = |
| nresources.findResourceLink(resourceLinkName); |
| if (resourceLink != null) { |
| throw new IllegalArgumentException |
| ("Invalid resource link name - already exists'" + |
| resourceLinkName + "'"); |
| } |
| resourceLink = new ContextResourceLink(); |
| resourceLink.setGlobal(global); |
| resourceLink.setName(resourceLinkName); |
| resourceLink.setType(type); |
| nresources.addResourceLink(resourceLink); |
| |
| // Return the corresponding MBean name |
| return createObjectName(resourceLink).toString(); |
| } |
| |
| @Override |
| public ObjectName createObjectName(String hostDomain, ObjectName parentName) |
| throws MalformedObjectNameException |
| { |
| String onameStr; |
| StandardHost hst=(StandardHost)getParent(); |
| |
| String hostName=getParent().getName(); |
| String name= "//" + ((hostName==null)? "DEFAULT" : hostName) + |
| (("".equals(encodedPath)) ? "/" : encodedPath); |
| |
| String suffix=",J2EEApplication=" + |
| getJ2EEApplication() + ",J2EEServer=" + |
| getJ2EEServer(); |
| |
| onameStr="j2eeType=WebModule,name=" + name + suffix; |
| if( log.isLoggable(Level.FINE)) |
| log.log(Level.FINE, "Registering " + onameStr + " for " + oname); |
| |
| // default case - no domain explictely set. |
| if( getDomain() == null ) domain=hst.getDomain(); |
| return new ObjectName(getDomain() + ":" + onameStr); |
| } |
| |
| |
| |
| private void preRegisterJMX() { |
| try { |
| StandardHost host = (StandardHost) getParent(); |
| if ((oname == null) |
| || (oname.getKeyProperty("j2eeType") == null)) { |
| oname = createObjectName(host.getDomain(), host.getJmxName()); |
| controller = oname; |
| } |
| } catch(Exception ex) { |
| if (log.isLoggable(Level.INFO)) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_UPDATING_CTX_INFO), |
| new Object[] {this, oname, ex.toString()}); |
| log.log(Level.INFO, msg, ex); |
| } |
| } |
| } |
| |
| private void registerJMX() { |
| try { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Checking for " + oname); |
| } |
| controller = oname; |
| // Send j2ee.object.created notification |
| if (this.getObjectName() != null) { |
| Notification notification = new Notification( |
| "j2ee.object.created", this, sequenceNumber++); |
| sendNotification(notification); |
| } |
| for (Container child : findChildren()) { |
| ((StandardWrapper)child).registerJMX( this ); |
| } |
| } catch (Exception ex) { |
| |
| String msg = MessageFormat.format(rb.getString(LogFacade.ERROR_REGISTERING_WRAPPER_INFO), |
| new Object[] {this, oname, ex.toString()}); |
| log.log(Level.INFO, msg, ex); |
| } |
| } |
| |
| |
| public void sendNotification(Notification notification) { |
| |
| if (broadcaster == null) { |
| broadcaster = ((StandardEngine)getParent().getParent()).getService().getBroadcaster(); |
| } |
| if (broadcaster != null) { |
| broadcaster.sendNotification(notification); |
| } |
| return; |
| } |
| |
| |
| @Override |
| public void init() throws Exception { |
| |
| if( this.getParent() == null ) { |
| |
| ContextConfig config = new ContextConfig(); |
| this.addLifecycleListener(config); |
| } |
| |
| // It's possible that addChild may have started us |
| if( initialized ) { |
| return; |
| } |
| |
| super.init(); |
| |
| // START GlassFish 2439 |
| // Notify our interested LifecycleListeners |
| lifecycle.fireLifecycleEvent(INIT_EVENT, null); |
| // END GlassFish 2439 |
| |
| // Send j2ee.state.starting notification |
| if (this.getObjectName() != null) { |
| Notification notification = new Notification("j2ee.state.starting", this, sequenceNumber++); |
| sendNotification(notification); |
| } |
| |
| } |
| |
| @Override |
| public ObjectName getParentName() throws MalformedObjectNameException { |
| // "Life" update |
| String path=oname.getKeyProperty("name"); |
| if( path == null ) { |
| log.log(Level.SEVERE, LogFacade.MISSING_ATTRIBUTE, getName()); |
| return null; |
| } |
| if( ! path.startsWith( "//")) { |
| log.log(Level.SEVERE, LogFacade.MALFORMED_NAME, getName()); |
| } |
| path=path.substring(2); |
| int delim=path.indexOf( "/" ); |
| hostName="localhost"; // Should be default... |
| if( delim > 0 ) { |
| hostName=path.substring(0, delim); |
| path = path.substring(delim); |
| if ("/".equals(path)) { |
| this.setName(""); |
| } else { |
| this.setName(path); |
| } |
| } else { |
| if (log.isLoggable(Level.FINE)) { |
| log.log(Level.FINE, "Setting path " + path); |
| } |
| this.setName( path ); |
| } |
| // XXX The service and domain should be the same. |
| String parentDomain=getEngineName(); |
| if( parentDomain == null ) parentDomain=domain; |
| return new ObjectName( parentDomain + ":" + |
| "type=Host,host=" + hostName); |
| } |
| |
| public void create() throws Exception{ |
| init(); |
| } |
| |
| |
| |
| /** |
| * Create an <code>ObjectName</code> for <code>ContextEnvironment</code> object. |
| * |
| * @param environment The ContextEnvironment to be named |
| * |
| * @exception MalformedObjectNameException if a name cannot be created |
| */ |
| public ObjectName createObjectName(ContextEnvironment environment) |
| throws MalformedObjectNameException { |
| |
| ObjectName name = null; |
| Object container = |
| environment.getNamingResources().getContainer(); |
| if (container instanceof Server) { |
| name = new ObjectName(domain + ":type=Environment" + |
| ",resourcetype=Global,name=" + environment.getName()); |
| } else if (container instanceof Context) { |
| String path = ((Context)container).getPath(); |
| if (path.length() < 1) |
| path = "/"; |
| Host host = (Host) ((Context)container).getParent(); |
| name = new ObjectName(domain + ":type=Environment" + |
| ",resourcetype=Context,path=" + path + |
| ",host=" + host.getName() + |
| ",name=" + environment.getName()); |
| } |
| |
| return (name); |
| |
| } |
| |
| /** |
| * Create an <code>ObjectName</code> for <code>ContextResource</code> object. |
| * |
| * @param resource The ContextResource to be named |
| * |
| * @exception MalformedObjectNameException if a name cannot be created |
| */ |
| public ObjectName createObjectName(ContextResource resource) |
| throws MalformedObjectNameException { |
| |
| ObjectName name = null; |
| String encodedResourceName = urlEncoder.encode(resource.getName()); |
| Object container = |
| resource.getNamingResources().getContainer(); |
| if (container instanceof Server) { |
| name = new ObjectName(domain + ":type=Resource" + |
| ",resourcetype=Global,class=" + resource.getType() + |
| ",name=" + encodedResourceName); |
| } else if (container instanceof Context) { |
| String path = ((Context)container).getPath(); |
| if (path.length() < 1) |
| path = "/"; |
| Host host = (Host) ((Context)container).getParent(); |
| name = new ObjectName(domain + ":type=Resource" + |
| ",resourcetype=Context,path=" + path + |
| ",host=" + host.getName() + |
| ",class=" + resource.getType() + |
| ",name=" + encodedResourceName); |
| } |
| |
| return (name); |
| |
| } |
| |
| |
| /** |
| * Create an <code>ObjectName</code> for <code>ContextResourceLink</code> object. |
| * |
| * @param resourceLink The ContextResourceLink to be named |
| * |
| * @exception MalformedObjectNameException if a name cannot be created |
| */ |
| public ObjectName createObjectName(ContextResourceLink resourceLink) |
| throws MalformedObjectNameException { |
| |
| ObjectName name = null; |
| String encodedResourceLinkName = urlEncoder.encode(resourceLink.getName()); |
| Object container = |
| resourceLink.getNamingResources().getContainer(); |
| if (container instanceof Server) { |
| name = new ObjectName(domain + ":type=ResourceLink" + |
| ",resourcetype=Global" + |
| ",name=" + encodedResourceLinkName); |
| } else if (container instanceof Context) { |
| String path = ((Context)container).getPath(); |
| if (path.length() < 1) |
| path = "/"; |
| Host host = (Host) ((Context)container).getParent(); |
| name = new ObjectName(domain + ":type=ResourceLink" + |
| ",resourcetype=Context,path=" + path + |
| ",host=" + host.getName() + |
| ",name=" + encodedResourceLinkName); |
| } |
| |
| return (name); |
| |
| } |
| |
| // ------------------------------------------------- ServletContext Methods |
| |
| /** |
| * Return the value of the specified context attribute, if any; |
| * otherwise return <code>null</code>. |
| */ |
| @Override |
| public Object getAttribute(String name) { |
| return context.getAttribute(name); |
| } |
| |
| /** |
| * Return an enumeration of the names of the context attributes |
| * associated with this context. |
| */@Override |
| public Enumeration<String> getAttributeNames() { |
| return context.getAttributeNames(); |
| } |
| |
| /** |
| * Returns the context path of the web application. |
| */ |
| public String getContextPath() { |
| return getPath(); |
| } |
| |
| /** |
| * Return a <code>ServletContext</code> object that corresponds to a |
| * specified URI on the server. |
| */ |
| public ServletContext getContext(String uri) { |
| |
| // Validate the format of the specified argument |
| if ((uri == null) || (!uri.startsWith("/"))) { |
| return (null); |
| } |
| |
| Context child = null; |
| try { |
| Host host = (Host) getParent(); |
| String mapuri = uri; |
| while (true) { |
| child = (Context) host.findChild(mapuri); |
| if (child != null) |
| break; |
| int slash = mapuri.lastIndexOf('/'); |
| if (slash < 0) |
| break; |
| mapuri = mapuri.substring(0, slash); |
| } |
| } catch (Throwable t) { |
| return (null); |
| } |
| |
| if (child == null) { |
| return (null); |
| } |
| |
| if (getCrossContext()) { |
| // If crossContext is enabled, can always return the context |
| return child.getServletContext(); |
| } else if (child == this) { |
| // Can still return the current context |
| return getServletContext(); |
| } else { |
| // Nothing to return |
| return (null); |
| } |
| } |
| |
| /** |
| * Return the value of the specified initialization parameter, or |
| * <code>null</code> if this parameter does not exist. |
| */ |
| public String getInitParameter(final String name) { |
| return context.getInitParameter(name); |
| } |
| |
| /** |
| * Return the names of the context's initialization parameters, or an |
| * empty enumeration if the context has no initialization parameters. |
| */ |
| public Enumeration<String> getInitParameterNames() { |
| return context.getInitParameterNames(); |
| } |
| |
| /** |
| * @return true if the context initialization parameter with the given |
| * name and value was set successfully on this ServletContext, and false |
| * if it was not set because this ServletContext already contains a |
| * context initialization parameter with a matching name |
| */ |
| public boolean setInitParameter(String name, String value) { |
| if (isContextInitializedCalled) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.SERVLET_CONTEXT_ALREADY_INIT_EXCEPTION), |
| new Object[] {"setInitParameter", getName()}); |
| throw new IllegalStateException(msg); |
| } |
| return context.setInitParameter(name, value); |
| } |
| |
| /** |
| * Return the major version of the Java Servlet API that we implement. |
| */ |
| public int getMajorVersion() { |
| return context.getMajorVersion(); |
| } |
| |
| /** |
| * Return the minor version of the Java Servlet API that we implement. |
| */ |
| public int getMinorVersion() { |
| return context.getMinorVersion(); |
| } |
| |
| /** |
| * Return the MIME type of the specified file, or <code>null</code> if |
| * the MIME type cannot be determined. |
| */ |
| public String getMimeType(String file) { |
| |
| if (file == null) |
| return (null); |
| int period = file.lastIndexOf("."); |
| if (period < 0) |
| return (null); |
| String extension = file.substring(period + 1); |
| if (extension.length() < 1) |
| return (null); |
| return (findMimeMapping(extension)); |
| |
| } |
| |
| /** |
| * Return a <code>RequestDispatcher</code> object that acts as a |
| * wrapper for the named servlet. |
| */ |
| public RequestDispatcher getNamedDispatcher(String name) { |
| |
| // Validate the name argument |
| if (name == null) |
| return (null); |
| |
| // Create and return a corresponding request dispatcher |
| Wrapper wrapper = (Wrapper) findChild(name); |
| if (wrapper == null) |
| return (null); |
| |
| return new ApplicationDispatcher(wrapper, null, null, null, null, null, name); |
| |
| } |
| |
| /** |
| * Return the display name of this web application. |
| */ |
| public String getServletContextName() { |
| return getDisplayName(); |
| } |
| |
| /** |
| * Remove the context attribute with the specified name, if any. |
| */ |
| public void removeAttribute(String name) { |
| context.removeAttribute(name); |
| } |
| |
| /** |
| * Bind the specified value with the specified context attribute name, |
| * replacing any existing value for that name. |
| */ |
| public void setAttribute(String name, Object value) { |
| context.setAttribute(name, value); |
| } |
| |
| /** |
| * Return the name and version of the servlet container. |
| */ |
| public String getServerInfo() { |
| return context.getServerInfo(); |
| } |
| |
| /** |
| * Return the real path corresponding to the given virtual path, or |
| * <code>null</code> if the container was unable to perform the |
| * translation |
| */ |
| public String getRealPath(String path) { |
| if (!(showArchivedRealPathEnabled || directoryDeployed)) { |
| return null; |
| } |
| |
| if (!isFilesystemBased()) |
| return null; |
| |
| if (path == null) { |
| return null; |
| } |
| |
| File file = null; |
| if (alternateDocBases == null |
| || alternateDocBases.size() == 0) { |
| file = new File(getBasePath(getDocBase()), path); |
| } else { |
| AlternateDocBase match = AlternateDocBase.findMatch( |
| path, alternateDocBases); |
| if (match != null) { |
| file = new File(match.getBasePath(), path); |
| } else { |
| // None of the url patterns for alternate doc bases matched |
| file = new File(getBasePath(getDocBase()), path); |
| } |
| } |
| |
| if (!file.exists()) { |
| try { |
| // Try looking up resource in |
| // WEB-INF/lib/[*.jar]/META-INF/resources |
| File f = getExtractedMetaInfResourcePath(path); |
| if (f != null && f.exists()) { |
| file = f; |
| } |
| } catch (Exception e) { |
| // ignore |
| } |
| } |
| |
| if (!file.exists()) { |
| return null; |
| } else { |
| return file.getAbsolutePath(); |
| } |
| } |
| |
| /** |
| * Writes the specified message to a servlet log file. |
| */ |
| public void log(String message) { |
| message= neutralizeForLog(message); |
| org.apache.catalina.Logger logger = getLogger(); |
| if (logger != null) { |
| /* PWC 6403328 |
| logger.log(context.logName() + message, Logger.INFORMATION); |
| */ |
| //START PWC 6403328 |
| logger.log(logName() + " ServletContext.log():" + message, org.apache.catalina.Logger.INFORMATION); |
| //END PWC 6403328 |
| } |
| } |
| |
| /** |
| * Writes the specified exception and message to a servlet log file. |
| */ |
| public void log(Exception exception, String message) { |
| message= neutralizeForLog(message); |
| org.apache.catalina.Logger logger = getLogger(); |
| if (logger != null) |
| logger.log(exception, logName() + message); |
| } |
| |
| /** |
| * Writes the specified message and exception to a servlet log file. |
| */ |
| public void log(String message, Throwable throwable) { |
| message= neutralizeForLog(message); |
| org.apache.catalina.Logger logger = getLogger(); |
| if (logger != null) |
| logger.log(logName() + message, throwable); |
| } |
| |
| public Servlet getServlet(String name) { |
| return context.getServlet(name); |
| } |
| |
| public Enumeration<String> getServletNames() { |
| return context.getServletNames(); |
| } |
| |
| public Enumeration<Servlet> getServlets() { |
| return context.getServlets(); |
| } |
| |
| /** |
| * Return the requested resource as an <code>InputStream</code>. The |
| * path must be specified according to the rules described under |
| * <code>getResource</code>. If no such resource can be identified, |
| * return <code>null</code>. |
| */ |
| public InputStream getResourceAsStream(String path) { |
| |
| if (path == null || !path.startsWith("/")) |
| return (null); |
| |
| path = RequestUtil.normalize(path); |
| if (path == null) |
| return (null); |
| |
| DirContext resources = null; |
| |
| if (alternateDocBases == null |
| || alternateDocBases.size() == 0) { |
| resources = getResources(); |
| } else { |
| AlternateDocBase match = AlternateDocBase.findMatch( |
| path, alternateDocBases); |
| if (match != null) { |
| resources = ContextsAdapterUtility.unwrap(match.getResources()); |
| } else { |
| // None of the url patterns for alternate doc bases matched |
| resources = getResources(); |
| } |
| } |
| |
| if (resources != null) { |
| try { |
| Object resource = resources.lookup(path); |
| if (resource instanceof Resource) |
| return (((Resource) resource).streamContent()); |
| } catch (Exception e) { |
| // do nothing |
| } |
| } |
| return (null); |
| } |
| |
| /** |
| * Return the URL to the resource that is mapped to a specified path. |
| * The path must begin with a "/" and is interpreted as relative to the |
| * current context root. |
| */ |
| public java.net.URL getResource(String path) |
| throws MalformedURLException { |
| |
| if (path == null || !path.startsWith("/")) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.INCORRECT_PATH), path); |
| throw new MalformedURLException(msg); |
| } |
| |
| path = RequestUtil.normalize(path); |
| if (path == null) |
| return (null); |
| |
| String libPath = "/WEB-INF/lib/"; |
| if ((path.startsWith(libPath)) && (path.endsWith(".jar"))) { |
| File jarFile = null; |
| if (isFilesystemBased()) { |
| jarFile = new File(getBasePath(docBase), path); |
| } else { |
| jarFile = new File(getWorkPath(), path); |
| } |
| if (jarFile.exists()) { |
| return jarFile.toURL(); |
| } else { |
| return null; |
| } |
| |
| } else { |
| |
| DirContext resources = null; |
| if (alternateDocBases == null |
| || alternateDocBases.size() == 0) { |
| resources = context.getResources(); |
| } else { |
| AlternateDocBase match = AlternateDocBase.findMatch( |
| path, alternateDocBases); |
| if (match != null) { |
| resources = ContextsAdapterUtility.unwrap(match.getResources()); |
| } else { |
| // None of the url patterns for alternate doc bases matched |
| resources = getResources(); |
| } |
| } |
| |
| if (resources != null) { |
| String fullPath = getName() + path; |
| String hostName = getParent().getName(); |
| try { |
| resources.lookup(path); |
| return new java.net.URL |
| /* SJSAS 6318494 |
| ("jndi", null, 0, getJNDIUri(hostName, fullPath), |
| */ |
| // START SJAS 6318494 |
| ("jndi", "", 0, getJNDIUri(hostName, fullPath), |
| // END SJSAS 6318494 |
| new DirContextURLStreamHandler(resources)); |
| } catch (Exception e) { |
| // do nothing |
| } |
| } |
| } |
| |
| return (null); |
| } |
| |
| /** |
| * Return a Set containing the resource paths of resources member of the |
| * specified collection. Each path will be a String starting with |
| * a "/" character. The returned set is immutable. |
| */ |
| public Set<String> getResourcePaths(String path) { |
| // Validate the path argument |
| if (path == null) { |
| return null; |
| } |
| if (!path.startsWith("/")) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.INCORRECT_PATH), path); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| path = RequestUtil.normalize(path); |
| if (path == null) |
| return (null); |
| |
| DirContext resources = null; |
| |
| if (alternateDocBases == null |
| || alternateDocBases.size() == 0) { |
| resources = getResources(); |
| } else { |
| AlternateDocBase match = AlternateDocBase.findMatch( |
| path, alternateDocBases); |
| if (match != null) { |
| resources = ContextsAdapterUtility.unwrap(match.getResources()); |
| } else { |
| // None of the url patterns for alternate doc bases matched |
| resources = getResources(); |
| } |
| } |
| |
| if (resources != null) { |
| return (getResourcePathsInternal(resources, path)); |
| } |
| |
| return (null); |
| } |
| |
| /** |
| * Internal implementation of getResourcesPath() logic. |
| * |
| * @param resources Directory context to search |
| * @param path Collection path |
| */ |
| private Set<String> getResourcePathsInternal(DirContext resources, |
| String path) { |
| HashSet<String> set = new HashSet<String>(); |
| try { |
| listCollectionPaths(set, resources, path); |
| } catch (NamingException e) { |
| // Ignore, need to check for resource paths underneath |
| // WEB-INF/lib/[*.jar]/META-INF/resources, see next |
| } |
| try { |
| // Trigger expansion of bundled JAR files |
| File file = getExtractedMetaInfResourcePath(path); |
| if (file != null) { |
| File[] children = file.listFiles(); |
| StringBuilder sb = null; |
| for (File child : children) { |
| sb = new StringBuilder(path); |
| if (!path.endsWith("/")) { |
| sb.append("/"); |
| } |
| sb.append(child.getName()); |
| if (child.isDirectory()) { |
| sb.append("/"); |
| } |
| set.add(sb.toString()); |
| } |
| } |
| } catch (Exception e) { |
| // ignore |
| } |
| return Collections.unmodifiableSet(set); |
| } |
| |
| /** |
| * Return a <code>RequestDispatcher</code> instance that acts as a |
| * wrapper for the resource at the given path. The path must begin |
| * with a "/" and is interpreted as relative to the current context root. |
| */ |
| public RequestDispatcher getRequestDispatcher(String path) { |
| |
| // Validate the path argument |
| if (path == null) { |
| return null; |
| } |
| |
| if (!path.startsWith("/") && !path.isEmpty()) { |
| String msg = MessageFormat.format(rb.getString(LogFacade.INCORRECT_OR_NOT_EMPTY_PATH), path); |
| throw new IllegalArgumentException(msg); |
| } |
| |
| // Get query string |
| String queryString = null; |
| int pos = path.indexOf('?'); |
| if (pos >= 0) { |
| queryString = path.substring(pos + 1); |
| path = path.substring(0, pos); |
| } |
| |
| path = RequestUtil.normalize(path); |
| if (path == null) |
| return (null); |
| |
| pos = path.length(); |
| |
| // Use the thread local URI and mapping data |
| DispatchData dd = dispatchData.get(); |
| if (dd == null) { |
| dd = new DispatchData(); |
| dispatchData.set(dd); |
| } |
| |
| MessageBytes uriMB = dd.uriMB; |
| uriMB.recycle(); |
| |
| // Retrieve the thread local mapping data |
| MappingData mappingData = dd.mappingData; |
| |
| // Map the URI |
| CharChunk uriCC = uriMB.getCharChunk(); |
| try { |
| uriCC.append(getPath(), 0, getPath().length()); |
| /* |
| * Ignore any trailing path params (separated by ';') for mapping |
| * purposes |
| */ |
| int semicolon = path.indexOf(';'); |
| if (pos >= 0 && semicolon > pos) { |
| semicolon = -1; |
| } |
| uriCC.append(path, 0, semicolon > 0 ? semicolon : pos); |
| getMapper().map(uriMB, mappingData); |
| if (mappingData.wrapper == null) { |
| return (null); |
| } |
| /* |
| * Append any trailing path params (separated by ';') that were |
| * ignored for mapping purposes, so that they're reflected in the |
| * RequestDispatcher's requestURI |
| */ |
| if (semicolon > 0) { |
| uriCC.append(path, semicolon, pos - semicolon); |
| } |
| } catch (Exception e) { |
| // Should never happen |
| log.log(Level.WARNING, LogFacade.MAPPING_ERROR_EXCEPTION, e); |
| return (null); |
| } |
| |
| Wrapper wrapper = (Wrapper) mappingData.wrapper; |
| String wrapperPath = mappingData.wrapperPath.toString(); |
| String pathInfo = mappingData.pathInfo.toString(); |
| HttpServletMapping mappingForDispatch = new MappingImpl(mappingData); |
| |
| mappingData.recycle(); |
| |
| // Construct a RequestDispatcher to process this request |
| return new ApplicationDispatcher |
| (wrapper, mappingForDispatch, uriCC.toString(), wrapperPath, pathInfo, |
| queryString, null); |
| } |
| |
| |
| // ------------------------------------------------------------- Attributes |
| |
| |
| /** |
| * Return the naming resources associated with this web application. |
| */ |
| public DirContext getStaticResources() { |
| return getResources(); |
| } |
| |
| /** |
| * Return the naming resources associated with this web application. |
| * FIXME: Fooling introspection ... |
| */ |
| public DirContext findStaticResources() { |
| return getResources(); |
| } |
| |
| /** |
| * Return the naming resources associated with this web application. |
| */ |
| public String[] getWelcomeFiles() { |
| return findWelcomeFiles(); |
| } |
| |
| /** |
| * Set the validation feature of the XML parser used when |
| * parsing xml instances. |
| * @param webXmlValidation true to enable xml instance validation |
| */ |
| public void setXmlValidation(boolean webXmlValidation){ |
| this.webXmlValidation = webXmlValidation; |
| } |
| |
| /** |
| * Get the server.xml <context> attribute's xmlValidation. |
| * @return true if validation is enabled. |
| * |
| */ |
| public boolean getXmlValidation(){ |
| return webXmlValidation; |
| } |
| |
| /** |
| * Get the server.xml <context> attribute's xmlNamespaceAware. |
| * @return true if namespace awarenes is enabled. |
| */ |
| public boolean getXmlNamespaceAware(){ |
| return webXmlNamespaceAware; |
| } |
| |
| /** |
| * Set the namespace aware feature of the XML parser used when |
| * parsing xml instances. |
| * @param webXmlNamespaceAware true to enable namespace awareness |
| */ |
| public void setXmlNamespaceAware(boolean webXmlNamespaceAware){ |
| this.webXmlNamespaceAware= webXmlNamespaceAware; |
| } |
| |
| /** |
| * Set the validation feature of the XML parser used when |
| * parsing tlds files. |
| * @param tldValidation true to enable xml instance validation |
| */ |
| public void setTldValidation(boolean tldValidation){ |
| this.tldValidation = tldValidation; |
| } |
| |
| /** |
| * Get the server.xml <context> attribute's webXmlValidation. |
| * @return true if validation is enabled. |
| * |
| */ |
| public boolean getTldValidation(){ |
| return tldValidation; |
| } |
| |
| /** |
| * Get the server.xml <host> attribute's xmlNamespaceAware. |
| * @return true if namespace awarenes is enabled. |
| */ |
| public boolean getTldNamespaceAware(){ |
| return tldNamespaceAware; |
| } |
| |
| /** |
| * Set the namespace aware feature of the XML parser used when |
| * parsing xml instances. |
| * @param tldNamespaceAware true to enable namespace awareness |
| */ |
| public void setTldNamespaceAware(boolean tldNamespaceAware){ |
| this.tldNamespaceAware= tldNamespaceAware; |
| } |
| |
| /** |
| * Sets the list of ordered libs, which will be used as the value of the |
| * ServletContext attribute with name jakarta.servlet.context.orderedLibs |
| */ |
| public void setOrderedLibs(List<String> orderedLibs) { |
| this.orderedLibs = orderedLibs; |
| } |
| |
| public void startRecursive() throws LifecycleException { |
| // nothing to start recursively, the servlets will be started by |
| // load-on-startup |
| start(); |
| } |
| |
| public int getState() { |
| if( started ) { |
| return 1; // RUNNING |
| } |
| if( initialized ) { |
| return 0; // starting ? |
| } |
| if( ! available ) { |
| return 4; //FAILED |
| } |
| // 2 - STOPPING |
| return 3; // STOPPED |
| } |
| |
| boolean isContextInitializedCalled() { |
| return isContextInitializedCalled; |
| } |
| |
| /** |
| * Creates an ObjectInputStream that provides special deserialization |
| * logic for classes that are normally not serializable (such as |
| * javax.naming.Context). |
| */ |
| public ObjectInputStream createObjectInputStream(InputStream is) |
| throws IOException { |
| |
| ObjectInputStream ois = null; |
| |
| Loader loader = getLoader(); |
| if (loader != null) { |
| ClassLoader classLoader = loader.getClassLoader(); |
| if (classLoader != null) { |
| try { |
| ois = new CustomObjectInputStream(is, classLoader); |
| } catch (IOException ioe) { |
| log.log(Level.SEVERE, LogFacade.CANNOT_CREATE_OBJECT_INPUT_STREAM, ioe); |
| } |
| } |
| } |
| |
| if (ois == null) { |
| ois = new ObjectInputStream(is); |
| } |
| |
| return ois; |
| } |
| |
| /** |
| * Creates an ObjectOutputStream that provides special serialization |
| * logic for classes that are normally not serializable (such as |
| * javax.naming.Context). |
| */ |
| public ObjectOutputStream createObjectOutputStream(OutputStream os) |
| throws IOException { |
| return new ObjectOutputStream(os); |
| } |
| |
| /** |
| * Gets the time this context was started. |
| * |
| * @return Time (in milliseconds since January 1, 1970, 00:00:00) when this |
| * context was started |
| */ |
| public long getStartTimeMillis() { |
| return startTimeMillis; |
| } |
| |
| public boolean isEventProvider() { |
| return false; |
| } |
| |
| public boolean isStatisticsProvider() { |
| return false; |
| } |
| |
| /* |
| * HTTP session related monitoring events |
| */ |
| public void sessionCreatedEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionDestroyedEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionRejectedEvent(int maxSessions) { |
| // Deliberate noop |
| } |
| |
| public void sessionExpiredEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionPersistedStartEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionPersistedEndEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionActivatedStartEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionActivatedEndEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionPassivatedStartEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public void sessionPassivatedEndEvent(HttpSession session) { |
| // Deliberate noop |
| } |
| |
| public static class RestrictedServletContextListener |
| implements ServletContextListener { |
| |
| /* |
| * The ServletContextListener to which to delegate |
| */ |
| private ServletContextListener delegate; |
| |
| /** |
| * Constructor |
| */ |
| public RestrictedServletContextListener( |
| ServletContextListener delegate) { |
| this.delegate = delegate; |
| } |
| |
| public void contextInitialized(ServletContextEvent sce) { |
| delegate.contextInitialized(sce); |
| } |
| |
| public void contextDestroyed(ServletContextEvent sce) { |
| delegate.contextDestroyed(sce); |
| } |
| |
| public ServletContextListener getNestedListener() { |
| return delegate; |
| } |
| } |
| |
| /** |
| * Instantiates the given Servlet class. |
| * |
| * @return the new Servlet instance |
| */ |
| protected <T extends Servlet> T createServletInstance(Class<T> clazz) |
| throws Exception{ |
| return clazz.newInstance(); |
| } |
| |
| /** |
| * Instantiates the given Filter class. |
| * |
| * @return the new Filter instance |
| */ |
| protected <T extends Filter> T createFilterInstance(Class<T> clazz) |
| throws Exception{ |
| return clazz.newInstance(); |
| } |
| |
| /** |
| * Instantiates the given EventListener class. |
| * |
| * @return the new EventListener instance |
| */ |
| public <T extends EventListener> T createListenerInstance( |
| Class<T> clazz) throws Exception{ |
| return clazz.newInstance(); |
| } |
| |
| /** |
| * Instantiates the given HttpUpgradeHandler class. |
| * |
| * @param clazz |
| * @param <T> |
| * @return a new T instance |
| * @throws Exception |
| */ |
| public <T extends HttpUpgradeHandler> T createHttpUpgradeHandlerInstance(Class<T> clazz) |
| throws Exception { |
| return clazz.newInstance(); |
| } |
| |
| /** |
| * Custom security manager responsible for enforcing permission |
| * check on ServletContext#getClassLoader if necessary. |
| */ |
| private static class MySecurityManager extends SecurityManager { |
| |
| /* |
| * @return true if the specified class loader <code>cl</code> |
| * can be found in the class loader delegation chain of the |
| * <code>start</code> class loader, false otherwise |
| */ |
| boolean isAncestor(ClassLoader start, ClassLoader cl) { |
| ClassLoader acl = start; |
| do { |
| acl = acl.getParent(); |
| if (cl == acl) { |
| return true; |
| } |
| } while (acl != null); |
| return false; |
| } |
| |
| /* |
| * Checks whether access to the webapp class loader associated |
| * with this Context should be granted to the caller of |
| * ServletContext#getClassLoader. |
| * |
| * If no security manager exists, this method returns immediately. |
| * |
| * Otherwise, it calls the security manager's checkPermission |
| * method with the getClassLoader permission if the class loader |
| * of the caller of ServletContext#getClassLoader is not the same as, |
| * or an ancestor of the webapp class loader associated with this |
| * Context. |
| */ |
| void checkGetClassLoaderPermission(ClassLoader webappLoader) { |
| SecurityManager sm = System.getSecurityManager(); |
| if (sm == null) { |
| return; |
| } |
| |
| // Get the current execution stack as an array of classes |
| Class[] classContext = getClassContext(); |
| |
| /* |
| * Determine the caller of ServletContext#getClassLoader: |
| * |
| * classContext[0]: |
| * org.apache.catalina.core.StandardContext$MySecurityManager |
| * classContext[1]: |
| * org.apache.catalina.core.StandardContext |
| * classContext[2]: |
| * org.apache.catalina.core.StandardContext |
| * classContext[3]: |
| * org.apache.catalina.core.ApplicationContext |
| * classContext[4]: |
| * org.apache.catalina.core.ApplicationContextFacade |
| * classContext[5]: |
| * Caller whose classloader to check |
| * |
| * NOTE: INDEX MUST BE ADJUSTED WHENEVER EXECUTION STACK |
| * CHANGES, E.G., DUE TO CODE BEING REORGANIZED |
| */ |
| ClassLoader ccl = classContext[5].getClassLoader(); |
| if (ccl != null && ccl != webappLoader && |
| !isAncestor(webappLoader, ccl)) { |
| sm.checkPermission(GET_CLASSLOADER_PERMISSION); |
| } |
| } |
| } |
| |
| private static class PrivilegedCreateSecurityManager |
| implements PrivilegedAction<MySecurityManager> { |
| |
| public MySecurityManager run() { |
| return new MySecurityManager(); |
| } |
| } |
| |
| /** |
| * List resource paths (recursively), and store all of them in the given |
| * Set. |
| */ |
| private static void listCollectionPaths |
| (Set<String> set, DirContext resources, String path) |
| throws NamingException { |
| |
| Enumeration<Binding> childPaths = resources.listBindings(path); |
| while (childPaths.hasMoreElements()) { |
| Binding binding = childPaths.nextElement(); |
| String name = binding.getName(); |
| StringBuilder childPath = new StringBuilder(path); |
| if (!"/".equals(path) && !path.endsWith("/")) |
| childPath.append("/"); |
| childPath.append(name); |
| Object object = binding.getObject(); |
| if (object instanceof DirContext && |
| childPath.charAt(childPath.length() -1) != '/') { |
| childPath.append("/"); |
| } |
| set.add(childPath.toString()); |
| } |
| } |
| |
| /** |
| * Get full path, based on the host name and the context path. |
| */ |
| private static String getJNDIUri(String hostName, String path) { |
| if (!path.startsWith("/")) |
| return "/" + hostName + "/" + path; |
| else |
| return "/" + hostName + path; |
| } |
| |
| /** |
| * Internal class used as thread-local storage when doing path |
| * mapping during dispatch. |
| */ |
| private static final class DispatchData { |
| public MessageBytes uriMB; |
| public MappingData mappingData; |
| |
| public DispatchData() { |
| uriMB = MessageBytes.newInstance(); |
| CharChunk uriCC = uriMB.getCharChunk(); |
| uriCC.setLimit(-1); |
| mappingData = new MappingData(); |
| } |
| } |
| |
| /** |
| * Get resource from META-INF/resources/ in jars. |
| */ |
| private File getExtractedMetaInfResourcePath(String path) { |
| path = Globals.META_INF_RESOURCES + path; |
| |
| ClassLoader cl = getLoader().getClassLoader(); |
| if (cl instanceof WebappClassLoader) { |
| return ((WebappClassLoader)cl).getExtractedResourcePath(path); |
| } |
| return null; |
| } |
| } |