org.apache.catalina.startup.ContextConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-embedded-all Show documentation
Show all versions of payara-embedded-all Show documentation
Payara-Embedded-All Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* 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.startup;
import org.apache.catalina.*;
import org.apache.catalina.authenticator.*;
import org.apache.catalina.core.*;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.catalina.deploy.SecurityConstraint;
import org.apache.catalina.session.StandardManager;
import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.RuleSet;
import org.glassfish.logging.annotation.LogMessageInfo;
import org.glassfish.web.valve.GlassFishValve;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import javax.servlet.ServletContext;
import java.io.*;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.*;
import java.util.logging.Logger;
/**
* Startup event listener for a Context that configures the properties
* of that Context, and the associated defined servlets.
*
* @author Craig R. McClanahan
* @author Jean-Francois Arcand
* @version $Revision: 1.14 $ $Date: 2007/02/20 20:16:56 $
*/
// START OF SJAS 8.0 BUG 5046959
// public final class ContextConfig
// NOTE: All the methods were originally private and changed to public.
public class ContextConfig
// END OF SJAS 8.0 BUG 5046959
implements LifecycleListener {
private static final Logger log = StandardServer.log;
private static final ResourceBundle rb = log.getResourceBundle();
@LogMessageInfo(
message = "Lifecycle event data object {0} is not a Context",
level = "WARNING"
)
public static final String EVENT_DATA_IS_NOT_CONTEXT_EXCEPTION = "AS-WEB-CORE-00408";
@LogMessageInfo(
message = "alt-dd file {0} not found",
level = "WARNING"
)
public static final String ALT_DD_FILE_NOT_FOUND_EXCEPTION = "AS-WEB-CORE-00409";
@LogMessageInfo(
message = "Missing application web.xml, using defaults only {0}",
level = "FINE"
)
public static final String MISSING_APP_WEB_XML_FINE = "AS-WEB-CORE-00410";
@LogMessageInfo(
message = "Parse error in application web.xml at line {0} and column {1}",
level = "WARNING"
)
public static final String PARSE_ERROR_IN_APP_WEB_XML_EXCEPTION = "AS-WEB-CORE-00411";
@LogMessageInfo(
message = "Parse error in application web.xml",
level = "WARNING"
)
public static final String PARSE_ERROR_IN_APP_WEB_XML = "AS-WEB-CORE-00412";
@LogMessageInfo(
message = "Error closing application web.xml",
level = "SEVERE",
cause = "Could not close this input stream and releases any system resources " +
"associated with the stream.",
action = "Verify if any I/O errors occur"
)
public static final String ERROR_CLOSING_APP_WEB_XML_EXCEPTION = "AS-WEB-CORE-00413";
@LogMessageInfo(
message = "No Realm has been configured to authenticate against",
level = "WARNING"
)
public static final String NO_REALM_BEEN_CONFIGURED_EXCEPTION = "AS-WEB-CORE-00414";
@LogMessageInfo(
message = "Cannot configure an authenticator for method {0}",
level = "WARNING"
)
public static final String CANNOT_CONFIG_AUTHENTICATOR_EXCEPTION = "AS-WEB-CORE-00415";
@LogMessageInfo(
message = "Cannot instantiate an authenticator of class {0}",
level = "WARNING"
)
public static final String CANNOT_INSTANTIATE_AUTHENTICATOR_EXCEPTION = "AS-WEB-CORE-00416";
@LogMessageInfo(
message = "Configured an authenticator for method {0}",
level = "FINE"
)
public static final String CONFIGURED_AUTHENTICATOR_FINE = "AS-WEB-CORE-00417";
@LogMessageInfo(
message = "No default web.xml",
level = "INFO"
)
public static final String NO_DEFAULT_WEB_XML_INFO = "AS-WEB-CORE-00418";
@LogMessageInfo(
message = "Missing default web.xml, using application web.xml only {0} {1}",
level = "WARNING"
)
public static final String MISSING_DEFAULT_WEB_XML_EXCEPTION = "AS-WEB-CORE-00419";
@LogMessageInfo(
message = "Parse error in default web.xml at line {0} and column {1}",
level = "SEVERE",
cause = "Could not parse the content of the specified input source using this Digester",
action = "Verify the input parameter, if any I/O errors occur"
)
public static final String PARSE_ERROR_IN_DEFAULT_WEB_XML_EXCEPTION = "AS-WEB-CORE-00420";
@LogMessageInfo(
message = "Parse error in default web.xml",
level = "SEVERE",
cause = "Could not parse the content of the specified input source using this Digester",
action = "Verify the input parameter, if any I/O errors occur"
)
public static final String PARSE_ERROR_IN_DEFAULT_WEB_XML = "AS-WEB-CORE-00421";
@LogMessageInfo(
message = "Error closing default web.xml",
level = "SEVERE",
cause = "Could not close this input stream and releases any system resources " +
"associated with the stream.",
action = "Verify if any I/O errors occur"
)
public static final String ERROR_CLOSING_DEFAULT_WEB_XML_EXCEPTION = "AS-WEB-CORE-00422";
@LogMessageInfo(
message = "ContextConfig: Initializing",
level = "FINE"
)
public static final String CONTEXT_CONFIG_INIT_FINE = "AS-WEB-CORE-00423";
@LogMessageInfo(
message = "Exception fixing docBase",
level = "SEVERE",
cause = "Could not adjust docBase",
action = "Verify if any I/O errors occur"
)
public static final String FIXING_DOC_BASE_EXCEPTION = "AS-WEB-CORE-00424";
@LogMessageInfo(
message = "ContextConfig: Processing START",
level = "FINEST"
)
public static final String PROCESSING_START_FINEST = "AS-WEB-CORE-00425";
@LogMessageInfo(
message = "ContextConfig: Processing STOP",
level = "FINEST"
)
public static final String PROCESSING_STOP_FINEST = "AS-WEB-CORE-00426";
@LogMessageInfo(
message = "Security role name {0} used in an without being defined in a in context [{1}]",
level = "INFO"
)
public static final String SECURITY_ROLE_NAME_USED_IN_AUTH_WITHOUT_DEFINITION = "AS-WEB-CORE-00427";
@LogMessageInfo(
message = "Security role name {0} used in a without being defined in a in context [{1}]",
level = "INFO"
)
public static final String SECURITY_ROLE_NAME_USED_IN_RUNAS_WITHOUT_DEFINITION = "AS-WEB-CORE-00428";
@LogMessageInfo(
message = "Security role name {0} used in a without being defined in a in context [{1}]",
level = "INFO"
)
public static final String SECURITY_ROLE_NAME_USED_IN_LINK_WITHOUT_DEFINITION = "AS-WEB-CORE-00429";
@LogMessageInfo(
message = "No web.xml, using defaults {0}",
level = "INFO"
)
public static final String NO_WEB_XML_INFO = "AS-WEB-CORE-00430";
// --------------------------------------------------- Instance Variables
/*
* Custom mappings of login methods to authenticators
*/
//START SJSAS 6202703
//private Map customAuthenticators;
protected Map customAuthenticators;
//END SJSAS 6202703
/**
* The set of Authenticators that we know how to configure. The key is
* the name of the implemented authentication method, and the value is
* the fully qualified Java class name of the corresponding Valve.
*/
//START SJSAS 6202703
//private static Properties authenticators = null;
protected static final Properties authenticators = new Properties();
//END SJSAS 6202703
private ClassLoader classLoader;
/**
* The Context we are associated with.
*/
protected Context context = null;
/**
* The debugging detail level for this component.
*/
private int debug = 0;
// START GlassFish 2439
/**
* The default web application's context file location.
*/
protected String defaultContextXml = null;
// END GlassFish 2439
/**
* The default web application's deployment descriptor location.
*/
// BEGIN OF SJSAS 8.1 6172288
// private String defaultWebXml = null;
protected String defaultWebXml = null;
/**
* Track any fatal errors during startup configuration processing.
*/
// private boolean ok = false;
protected boolean ok = false;
// END OF SJSAS 8.1 6172288
// START GlassFish 2439
/**
* Any parse error which occurred while parsing XML descriptors.
*/
protected SAXParseException parseException = null;
// END GlassFish 2439
// START GlassFish 2439
/**
* The Digester
we will use to process web application
* context files.
*/
protected static final Digester contextDigester =
createContextDigester();
// END GlassFish 2439
/**
* The Digester
we will use to process web application
* deployment descriptor files.
*/
// BEGIN OF SJSAS 8.1 6172288
// private static Digester webDigester = null;
protected static final Digester webDigester =
createWebDigester();
// END OF SJSAS 8.1 6172288
/**
* The Rule
used to parse the web.xml
*/
// BEGIN OF SJSAS 8.1 6172288
// private static WebRuleSet webRuleSet = new WebRuleSet();
protected static final WebRuleSet webRuleSet = new WebRuleSet();
// END OF SJSAS 8.1 6172288
/**
* Attribute value used to turn on/off XML validation
*/
private static boolean xmlValidation = false;
/**
* Attribute value used to turn on/off XML namespace awarenes.
*/
private static boolean xmlNamespaceAware = false;
/**
* Static initializer
*/
static {
authenticators.setProperty(
"BASIC", BasicAuthenticator.class.getName());
authenticators.setProperty(
"CLIENT-CERT", SSLAuthenticator.class.getName());
authenticators.setProperty(
"FORM", FormAuthenticator.class.getName());
authenticators.setProperty(
"NONE", NonLoginAuthenticator.class.getName());
authenticators.setProperty(
"DIGEST", DigestAuthenticator.class.getName());
}
// ----------------------------------------------------------- Properties
public void setClassLoader(ClassLoader cl) {
this.classLoader = cl;
}
/**
* Return the debugging detail level for this component.
*/
public int getDebug() {
return (this.debug);
}
/**
* Set the debugging detail level for this component.
*
* @param debug The new debugging detail level
*/
public void setDebug(int debug) {
this.debug = debug;
}
// START GlassFish 2439
/**
* Return the location of the default deployment descriptor
*/
public String getDefaultWebXml() {
if( defaultWebXml == null ) defaultWebXml=Constants.DefaultWebXml;
return (this.defaultWebXml);
}
/**
* Set the location of the default deployment descriptor
*
* @param path Absolute/relative path to the default web.xml
*/
public void setDefaultWebXml(String path) {
this.defaultWebXml = path;
}
// END GlassFish 2439
/**
* Return the location of the default context file
*/
public String getDefaultContextXml() {
if( defaultContextXml == null ) {
defaultContextXml=Constants.DEFAULT_CONTEXT_XML;
}
return (this.defaultContextXml);
}
/**
* Set the location of the default context file
*
* @param path Absolute/relative path to the default context.xml
*/
public void setDefaultContextXml(String path) {
this.defaultContextXml = path;
}
/**
* Sets custom mappings of login methods to authenticators.
*
* @param customAuthenticators Custom mappings of login methods to
* authenticators
*/
public void setCustomAuthenticators(Map customAuthenticators) {
this.customAuthenticators = customAuthenticators;
}
// --------------------------------------------------------- Public Methods
/**
* Process the START event for an associated Context.
*
* @param event The lifecycle event that has occurred
*/
public void lifecycleEvent(LifecycleEvent event)
throws LifecycleException {
// Identify the context we are associated with
try {
context = (Context) event.getLifecycle();
} catch (ClassCastException e) {
String msg = MessageFormat.format(rb.getString(EVENT_DATA_IS_NOT_CONTEXT_EXCEPTION),
event.getLifecycle());
throw new LifecycleException(msg, e);
}
// Called from ContainerBase.addChild() -> StandardContext.start()
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT)) {
start();
} else if (event.getType().equals(Lifecycle.STOP_EVENT)) {
stop();
// START GlassFish 2439
} else if (event.getType().equals(Lifecycle.INIT_EVENT)) {
init();
// END GlassFish 2439
}
}
// -------------------------------------------------------- Private Methods
/**
* Process the application configuration file, if it exists.
*/
protected void applicationConfig() throws LifecycleException {
String altDDName = null;
// Open the application web.xml file, if it exists
InputStream stream = null;
ServletContext servletContext = context.getServletContext();
if (servletContext != null) {
altDDName = (String)servletContext.getAttribute(
Globals.ALT_DD_ATTR);
if (altDDName != null) {
try {
stream = new FileInputStream(altDDName);
} catch (FileNotFoundException e) {
String msg = MessageFormat.format(rb.getString(ALT_DD_FILE_NOT_FOUND_EXCEPTION),
altDDName);
throw new LifecycleException(msg);
}
}
else {
stream = servletContext.getResourceAsStream
(Constants.ApplicationWebXml);
}
}
if (stream == null) {
/* PWC 6296257
log.info(sm.getString("contextConfig.applicationMissing") + " " + context);
//contextConfig.applicationMissing=PWC3013: Missing application web.xml, using defaults only
*/
// START PWC 6296257
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, MISSING_APP_WEB_XML_FINE, context);
}
// END PWC 6296257
return;
}
long t1=System.currentTimeMillis();
URL url=null;
// Process the application web.xml file
synchronized (webDigester) {
try {
if (altDDName != null) {
url = new File(altDDName).toURL();
} else {
url = servletContext.getResource(
Constants.ApplicationWebXml);
}
if( url!=null ) {
InputSource is = new InputSource(url.toExternalForm());
is.setByteStream(stream);
webDigester.clear();
webDigester.setDebug(getDebug());
if (context instanceof StandardContext) {
((StandardContext) context).setReplaceWelcomeFiles(true);
}
webDigester.setUseContextClassLoader(false);
webDigester.push(context);
webDigester.parse(is);
} else {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, NO_WEB_XML_INFO);
}
}
} catch (SAXParseException e) {
String msg = MessageFormat.format(rb.getString(PARSE_ERROR_IN_APP_WEB_XML_EXCEPTION),
new Object[] {e.getLineNumber(), e.getColumnNumber()});
throw new LifecycleException(msg, e);
} catch (Exception e) {
throw new LifecycleException(rb.getString(PARSE_ERROR_IN_APP_WEB_XML), e);
} finally {
try {
stream.close();
} catch (IOException e) {
log.log(Level.SEVERE, ERROR_CLOSING_APP_WEB_XML_EXCEPTION,
e);
}
webDigester.push(null);
}
}
webRuleSet.recycle();
long t2=System.currentTimeMillis();
if (context instanceof StandardContext) {
((StandardContext) context).setStartupTime(t2-t1);
}
}
/**
* Set up a manager.
*/
protected synchronized void managerConfig() {
if (context.getManager() == null) {
context.setManager(new StandardManager());
}
}
/**
* Set up an Authenticator automatically if required, and one has not
* already been configured.
*/
protected synchronized void authenticatorConfig()
throws LifecycleException {
// Does this Context require an Authenticator?
/* START IASRI 4856062
// This constraints check is relocated to happen after
// setRealmName(). This allows apps which have no constraints
// and no authenticator to still have a realm name set in
// their RealmAdapater. This is only relevant in the case where
// the core ACLs are doing all access control AND the servlet
// wishes to call isUserInRole AND the application does have
// security-role-mapping elements in sun-web.xml. This is probably
// not an interesting scenario. But might as well allow it to
// work, maybe it is of some use.
SecurityConstraint constraints[] = context.findConstraints();
if ((constraints == null) || (constraints.length == 0))
return;
*/
LoginConfig loginConfig = context.getLoginConfig();
if (loginConfig == null) {
loginConfig = new LoginConfig("NONE", null, null, null);
context.setLoginConfig(loginConfig);
}
// Has an authenticator been configured already?
if (context instanceof Authenticator)
return;
if (context instanceof ContainerBase) {
Pipeline pipeline = ((ContainerBase) context).getPipeline();
if (pipeline != null) {
GlassFishValve basic = pipeline.getBasic();
if ((basic != null) && (basic instanceof Authenticator))
return;
GlassFishValve valves[] = pipeline.getValves();
for (int i = 0; i < valves.length; i++) {
if (valves[i] instanceof Authenticator)
return;
}
}
} else {
return; // Cannot install a Valve even if it would be needed
}
// Has a Realm been configured for us to authenticate against?
/* START IASRI 4856062
if (context.getRealm() == null) {
*/
// BEGIN IASRI 4856062
Realm rlm = context.getRealm();
if (rlm == null) {
// END IASRI 4856062
throw new LifecycleException(rb.getString(NO_REALM_BEEN_CONFIGURED_EXCEPTION));
}
// BEGIN IASRI 4856062
// If a realm is available set its name in the Realm(Adapter)
rlm.setRealmName(loginConfig.getRealmName(),
loginConfig.getAuthMethod());
if (!context.hasConstraints()) {
return;
}
// END IASRI 4856062
/*
* First check to see if there is a custom mapping for the login
* method. If so, use it. Otherwise, check if there is a mapping in
* org/apache/catalina/startup/Authenticators.properties.
*/
GlassFishValve authenticator = null;
if (customAuthenticators != null) {
/* PWC 6392537
authenticator = (Valve)
customAuthenticators.get(loginConfig.getAuthMethod());
*/
// START PWC 6392537
String loginMethod = loginConfig.getAuthMethod();
if (loginMethod != null
&& customAuthenticators.containsKey(loginMethod)) {
authenticator = getGlassFishValveAuthenticator(loginMethod);
if (authenticator == null) {
String msg = MessageFormat.format(rb.getString(CANNOT_CONFIG_AUTHENTICATOR_EXCEPTION),
loginMethod);
throw new LifecycleException(msg);
}
}
// END PWC 6392537
}
if (authenticator == null) {
// Identify the class name of the Valve we should configure
String authenticatorName = null;
// BEGIN RIMOD 4808402
// If login-config is given but auth-method is null, use NONE
// so that NonLoginAuthenticator is picked
String authMethod = loginConfig.getAuthMethod();
if (authMethod == null) {
authMethod = "NONE";
}
authenticatorName = authenticators.getProperty(authMethod);
// END RIMOD 4808402
/* RIMOD 4808402
authenticatorName =
authenticators.getProperty(loginConfig.getAuthMethod());
*/
if (authenticatorName == null) {
String msg = MessageFormat.format(rb.getString(CANNOT_CONFIG_AUTHENTICATOR_EXCEPTION),
loginConfig.getAuthMethod());
throw new LifecycleException(msg);
}
// Instantiate and install an Authenticator of the requested class
try {
Class authenticatorClass = Class.forName(authenticatorName);
authenticator = (GlassFishValve) authenticatorClass.newInstance();
} catch (Throwable t) {
String msg = MessageFormat.format(rb.getString(CANNOT_INSTANTIATE_AUTHENTICATOR_EXCEPTION),
authenticatorName);
throw new LifecycleException(msg, t);
}
}
if (authenticator != null && context instanceof ContainerBase) {
Pipeline pipeline = ((ContainerBase) context).getPipeline();
if (pipeline != null) {
((ContainerBase) context).addValve(authenticator);
if (log.isLoggable(Level.FINE)) {
log.log(Level.FINE, CONFIGURED_AUTHENTICATOR_FINE, loginConfig.getAuthMethod());
}
}
}
}
@SuppressWarnings("unchecked")
private GlassFishValve getGlassFishValveAuthenticator(String loginMethod) {
return (GlassFishValve) customAuthenticators.get(loginMethod);
}
/**
* Create and return a Digester configured to process the
* web application deployment descriptor (web.xml).
*/
// BEGIN OF SJSAS 8.1 6172288
// private static Digester createWebDigester() {
public static Digester createWebDigester() {
// END OF SJSAS 8.1 6172288
return createWebXmlDigester(xmlNamespaceAware, xmlValidation);
}
/*
* Create and return a Digester configured to process the
* web application deployment descriptor (web.xml).
*/
public static Digester createWebXmlDigester(boolean namespaceAware,
boolean validation) {
DigesterFactory df = org.glassfish.internal.api.Globals.get(
DigesterFactory.class);
Digester digester = df.newDigester(xmlValidation,
xmlNamespaceAware, webRuleSet);
digester.getParser();
return digester;
}
// START GlassFish 2439
/**
* Create and return a Digester configured to process the
* context configuration descriptor for an application.
*/
protected static Digester createContextDigester() {
Digester digester = new Digester();
digester.setValidating(false);
RuleSet contextRuleSet = new ContextRuleSet("", false);
digester.addRuleSet(contextRuleSet);
RuleSet namingRuleSet = new NamingRuleSet("Context/");
digester.addRuleSet(namingRuleSet);
digester.getParser();
return digester;
}
// END GlassFish 2439
protected String getBaseDir() {
Container engineC=context.getParent().getParent();
if( engineC instanceof StandardEngine ) {
return ((StandardEngine)engineC).getBaseDir();
}
return System.getProperty("catalina.base");
}
/**
* Process the default configuration file, if it exists.
* The default config must be read with the container loader - so
* container servlets can be loaded
*/
protected void defaultConfig() throws LifecycleException {
long t1 = System.currentTimeMillis();
// Open the default web.xml file, if it exists
if (defaultWebXml == null && context instanceof StandardContext) {
defaultWebXml=((StandardContext)context).getDefaultWebXml();
}
// set the default if we don't have any overrides
if (defaultWebXml == null) getDefaultWebXml();
File file = new File(this.defaultWebXml);
if (!file.isAbsolute()) {
file = new File(getBaseDir(), this.defaultWebXml);
}
InputStream stream = null;
InputSource source = null;
try {
if ( ! file.exists() ) {
// Use getResource and getResourceAsStream
stream = getClass().getClassLoader()
.getResourceAsStream(defaultWebXml);
if( stream != null ) {
source = new InputSource
(getClass().getClassLoader()
.getResource(defaultWebXml).toString());
}
if (stream == null) {
// maybe embedded
stream = getClass().getClassLoader()
.getResourceAsStream("web-embed.xml");
if( stream != null ) {
source = new InputSource
(getClass().getClassLoader()
.getResource("web-embed.xml").toString());
}
}
if( stream== null ) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, NO_DEFAULT_WEB_XML_INFO);
}
// no default web.xml
return;
}
} else {
source =
new InputSource("file://" + file.getAbsolutePath());
stream = new FileInputStream(file);
}
} catch (Exception e) {
String msg = MessageFormat.format(rb.getString(MISSING_DEFAULT_WEB_XML_EXCEPTION),
new Object[] {defaultWebXml, file});
throw new LifecycleException(msg, e);
}
// Process the default web.xml file
synchronized (webDigester) {
try {
source.setByteStream(stream);
webDigester.setDebug(getDebug());
// JFA
if (context instanceof StandardContext)
((StandardContext) context).setReplaceWelcomeFiles(true);
webDigester.clear();
webDigester.setClassLoader(this.getClass().getClassLoader());
webDigester.setUseContextClassLoader(false);
webDigester.push(context);
webDigester.parse(source);
} catch (SAXParseException e) {
String msg = MessageFormat.format(rb.getString(PARSE_ERROR_IN_DEFAULT_WEB_XML_EXCEPTION),
new Object[] {e.getLineNumber(), e.getColumnNumber()});
throw new LifecycleException(msg, e);
} catch (Exception e) {
throw new LifecycleException(rb.getString(PARSE_ERROR_IN_DEFAULT_WEB_XML), e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
log.log(Level.SEVERE, ERROR_CLOSING_DEFAULT_WEB_XML_EXCEPTION, e);
}
}
}
webRuleSet.recycle();
long t2=System.currentTimeMillis();
if( (t2-t1) > 200 && log.isLoggable(Level.FINE) )
log.log(Level.FINE, "Processed default web.xml " + file + " " + ( t2-t1));
}
// START GlassFish 2439
/**
* Process the default configuration file, if it exists.
*/
protected void contextConfig() {
if( defaultContextXml==null ) getDefaultContextXml();
if (!context.getOverride()) {
processContextConfig(new File(getBaseDir()), defaultContextXml);
}
if (context.getConfigFile() != null)
processContextConfig(new File(context.getConfigFile()), null);
}
/**
* Process a context.xml.
*/
protected void processContextConfig(File baseDir, String resourceName) {
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, "Processing context [" + context.getName() +
"] configuration file " + baseDir + " " + resourceName);
InputSource source = null;
InputStream stream = null;
File file = baseDir;
if (resourceName != null) {
file = new File(baseDir, resourceName);
}
try {
if ( !file.exists() ) {
if (resourceName != null) {
// Use getResource and getResourceAsStream
stream = getClass().getClassLoader()
.getResourceAsStream(resourceName);
if( stream != null ) {
source = new InputSource
(getClass().getClassLoader()
.getResource(resourceName).toString());
}
}
} else {
source =
new InputSource("file://" + file.getAbsolutePath());
stream = new FileInputStream(file);
// Add as watched resource so that cascade reload occurs if a default
// config file is modified/added/removed
context.addWatchedResource(file.getAbsolutePath());
}
} catch (Exception e) {
String msg = MessageFormat.format(rb.getString(MISSING_DEFAULT_WEB_XML_EXCEPTION),
new Object[] {resourceName, file});
log.log(Level.SEVERE, msg, e);
}
if (source == null) {
if (stream != null) {
try {
stream.close();
} catch(IOException e) {
log.log(Level.SEVERE, ERROR_CLOSING_DEFAULT_WEB_XML_EXCEPTION, e);
}
}
return;
}
synchronized (contextDigester) {
try {
source.setByteStream(stream);
contextDigester.setClassLoader(classLoader);
contextDigester.setUseContextClassLoader(false);
contextDigester.push(context.getParent());
contextDigester.push(context);
contextDigester.setErrorHandler(new ContextErrorHandler());
contextDigester.parse(source);
if (parseException != null) {
ok = false;
}
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, "Successfully processed context [" +
context.getName() + "] configuration file " +
baseDir + " " + resourceName);
} catch (SAXParseException e) {
String msg = MessageFormat.format(rb.getString(PARSE_ERROR_IN_DEFAULT_WEB_XML_EXCEPTION),
new Object[] {e.getLineNumber(), e.getColumnNumber()});
log.log(Level.SEVERE, PARSE_ERROR_IN_DEFAULT_WEB_XML, e);
log.log(Level.SEVERE, msg);
ok = false;
} catch (Exception e) {
log.log(Level.SEVERE, PARSE_ERROR_IN_DEFAULT_WEB_XML, e);
ok = false;
} finally {
//contextDigester.reset();
parseException = null;
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
log.log(Level.SEVERE, ERROR_CLOSING_DEFAULT_WEB_XML_EXCEPTION, e);
}
}
}
}
// END GlassFish 2439
/**
* Adjust docBase.
*/
protected void fixDocBase()
throws IOException {
Host host = (Host) context.getParent();
String appBase = host.getAppBase();
boolean unpackWARs = true;
if (host instanceof StandardHost) {
unpackWARs = ((StandardHost) host).isUnpackWARs()
&& ((StandardContext) context).getUnpackWAR();
}
File canonicalAppBase = null;
if (appBase != null) {
canonicalAppBase = new File(appBase);
if (canonicalAppBase.isAbsolute()) {
canonicalAppBase = canonicalAppBase.getCanonicalFile();
} else {
canonicalAppBase =
new File(System.getProperty("catalina.base"), appBase)
.getCanonicalFile();
}
}
String docBase = context.getDocBase();
if (docBase == null) {
// Trying to guess the docBase according to the path
String path = context.getPath();
if (path == null) {
return;
}
if (path.equals("")) {
docBase = "ROOT";
} else {
if (path.startsWith("/")) {
docBase = path.substring(1).replace('/', '#');
} else {
docBase = path.replace('/', '#');
}
}
}
File file = new File(docBase);
if (!file.isAbsolute() && canonicalAppBase != null) {
docBase = (new File(canonicalAppBase, docBase)).getPath();
} else {
docBase = file.getCanonicalPath();
}
file = new File(docBase);
String origDocBase = docBase;
String pathName = context.getPath();
if (pathName.equals("")) {
pathName = "ROOT";
} else {
// Context path must start with '/'
pathName = pathName.substring(1).replace('/','#');
}
if (docBase.toLowerCase(Locale.ENGLISH).endsWith(".war") && !file.isDirectory() && unpackWARs) {
URL war = new URL("jar:" + (new File(docBase)).toURI().toURL() + "!/");
docBase = ExpandWar.expand(host, war, pathName);
file = new File(docBase);
docBase = file.getCanonicalPath();
if (context instanceof StandardContext) {
((StandardContext) context).setOriginalDocBase(origDocBase);
}
} else if (docBase.toLowerCase(Locale.ENGLISH).endsWith(".war") &&
!file.isDirectory() && !unpackWARs) {
URL war =
new URL("jar:" + (new File (docBase)).toURI().toURL() + "!/");
ExpandWar.validate(host, war, pathName);
} else {
File docDir = new File(docBase);
if (!docDir.exists()) {
File warFile = new File(docBase + ".war");
if (warFile.exists()) {
URL war =
new URL("jar:" + warFile.toURI().toURL() + "!/");
if (unpackWARs) {
docBase = ExpandWar.expand(host, war, pathName);
file = new File(docBase);
docBase = file.getCanonicalPath();
} else {
docBase = warFile.getCanonicalPath();
ExpandWar.validate(host, war, pathName);
}
}
if (context instanceof StandardContext) {
((StandardContext) context).setOriginalDocBase(origDocBase);
}
}
}
if (canonicalAppBase != null &&
docBase.startsWith(canonicalAppBase.getPath())) {
docBase = docBase.substring(canonicalAppBase.getPath().length());
docBase = docBase.replace(File.separatorChar, '/');
if (docBase.startsWith("/")) {
docBase = docBase.substring(1);
}
} else {
docBase = docBase.replace(File.separatorChar, '/');
}
context.setDocBase(docBase);
}
/**
* Log a message on the Logger associated with our Context (if any)
*
* @param message Message to be logged
*
private void log(String message) {
org.apache.catalina.Logger logger = null;
if (context != null)
logger = context.getLogger();
if (logger != null)
logger.log("ContextConfig[" + context.getName() + "]: " + message);
else
log.info( message );
}
/**
* Log a message on the Logger associated with our Context (if any)
*
* @param message Message to be logged
* @param throwable Associated exception
*
private void log(String message, Throwable throwable) {
org.apache.catalina.Logger logger = null;
if (context != null)
logger = context.getLogger();
if (logger != null)
logger.log("ContextConfig[" + context.getName() + "] "
+ message, throwable);
else {
log.log(Level.SEVERE, message, throwable );
}
}
*/
// START GlassFish 2439
/**
* Process a "init" event for this Context.
*/
protected void init() {
// Called from StandardContext.init()
if (log.isLoggable(Level.FINE))
log.log(Level.FINE, CONTEXT_CONFIG_INIT_FINE);
context.setConfigured(false);
ok = true;
contextConfig();
try {
fixDocBase();
} catch (IOException e) {
log.log(Level.SEVERE, FIXING_DOC_BASE_EXCEPTION, e);
}
}
// END GlassFish 2439
/**
* Process a "start" event for this Context - in background
*/
protected synchronized void start() throws LifecycleException {
if (log.isLoggable(Level.FINEST)) {
log.log(Level.FINEST, PROCESSING_START_FINEST);
}
context.setConfigured(false);
// Set properties based on DefaultContext
Container container = context.getParent();
if( !context.getOverride() ) {
if( container instanceof Host ) {
// Reset the value only if the attribute wasn't
// set on the context.
xmlValidation = context.getXmlValidation();
if (!xmlValidation) {
xmlValidation = ((Host)container).getXmlValidation();
}
xmlNamespaceAware = context.getXmlNamespaceAware();
if (!xmlNamespaceAware){
xmlNamespaceAware
= ((Host)container).getXmlNamespaceAware();
}
}
}
// Process the default and application web.xml files
defaultConfig();
applicationConfig();
validateSecurityRoles();
// Configure an authenticator if we need one
authenticatorConfig();
// Configure a manager
managerConfig();
// Dump the contents of this pipeline if requested
if ((log.isLoggable(Level.FINEST)) &&
(context instanceof ContainerBase)) {
log.log(Level.FINEST, "Pipline Configuration:");
Pipeline pipeline = ((ContainerBase) context).getPipeline();
GlassFishValve valves[] = null;
if (pipeline != null)
valves = pipeline.getValves();
if (valves != null) {
for (int i = 0; i < valves.length; i++) {
log.log(Level.FINEST, " " + valves[i].getInfo());
}
}
log.log(Level.FINEST, "======================");
}
// Make our application available because no problems
// were encountered
context.setConfigured(true);
}
/**
* Process a "stop" event for this Context.
*/
protected synchronized void stop() {
if (log.isLoggable(Level.FINEST))
log.log(Level.FINEST, PROCESSING_STOP_FINEST);
int i;
// Removing children
Container[] children = context.findChildren();
for (i = 0; i < children.length; i++) {
context.removeChild(children[i]);
}
// Removing application parameters
/* ApplicationParameter[] applicationParameters =
context.findApplicationParameters();
for (i = 0; i < applicationParameters.length; i++) {
context.removeApplicationParameter
(applicationParameters[i].getName());
}
*/
// Removing security constraints
context.removeConstraints();
// Removing Ejbs
/*
ContextEjb[] contextEjbs = context.findEjbs();
for (i = 0; i < contextEjbs.length; i++) {
context.removeEjb(contextEjbs[i].getName());
}
*/
// Removing environments
/*
ContextEnvironment[] contextEnvironments = context.findEnvironments();
for (i = 0; i < contextEnvironments.length; i++) {
context.removeEnvironment(contextEnvironments[i].getName());
}
*/
// Removing errors pages
context.removeErrorPages();
// Removing filter defs
FilterDef[] filterDefs = context.findFilterDefs();
for (i = 0; i < filterDefs.length; i++) {
context.removeFilterDef(filterDefs[i]);
}
// Removing filter maps
context.removeFilterMaps();
// Removing local ejbs
/*
ContextLocalEjb[] contextLocalEjbs = context.findLocalEjbs();
for (i = 0; i < contextLocalEjbs.length; i++) {
context.removeLocalEjb(contextLocalEjbs[i].getName());
}
*/
// Removing Mime mappings
String[] mimeMappings = context.findMimeMappings();
for (i = 0; i < mimeMappings.length; i++) {
context.removeMimeMapping(mimeMappings[i]);
}
// Removing parameters
String[] parameters = context.findParameters();
for (i = 0; i < parameters.length; i++) {
context.removeParameter(parameters[i]);
}
// Removing resource env refs
/*
String[] resourceEnvRefs = context.findResourceEnvRefs();
for (i = 0; i < resourceEnvRefs.length; i++) {
context.removeResourceEnvRef(resourceEnvRefs[i]);
}
*/
// Removing resource links
/*
ContextResourceLink[] contextResourceLinks =
context.findResourceLinks();
for (i = 0; i < contextResourceLinks.length; i++) {
context.removeResourceLink(contextResourceLinks[i].getName());
}
*/
// Removing resources
/*
ContextResource[] contextResources = context.findResources();
for (i = 0; i < contextResources.length; i++) {
context.removeResource(contextResources[i].getName());
}
*/
// Removing sercurity role
context.removeSecurityRoles();
// Removing servlet mappings
String[] servletMappings = context.findServletMappings();
for (i = 0; i < servletMappings.length; i++) {
context.removeServletMapping(servletMappings[i]);
}
// FIXME : Removing status pages
// Removing welcome files
context.removeWelcomeFiles();
// Removing wrapper lifecycles
context.removeWrapperLifecycles();
// Removing wrapper listeners
context.removeWrapperListeners();
ok = true;
}
/**
* Validate the usage of security role names in the web application
* deployment descriptor. If any problems are found, issue warning
* messages (for backwards compatibility) and add the missing roles.
* (To make these problems fatal instead, simply set the ok
* instance variable to false
as well).
*/
protected void validateSecurityRoles() {
// Check role names used in elements
Iterator iter =
context.getConstraints().iterator();
while (iter.hasNext()) {
for (String role : iter.next().findAuthRoles()) {
if (!"*".equals(role) &&
!context.hasSecurityRole(role)) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, SECURITY_ROLE_NAME_USED_IN_AUTH_WITHOUT_DEFINITION,
new Object[] {role, context.getName()});
}
context.addSecurityRole(role);
}
}
}
// Check role names used in elements
Container wrappers[] = context.findChildren();
for (int i = 0; i < wrappers.length; i++) {
Wrapper wrapper = (Wrapper) wrappers[i];
String runAs = wrapper.getRunAs();
if ((runAs != null) && !context.hasSecurityRole(runAs)) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, SECURITY_ROLE_NAME_USED_IN_RUNAS_WITHOUT_DEFINITION,
new Object[] {runAs, context.getName()});
}
context.addSecurityRole(runAs);
}
String names[] = wrapper.findSecurityReferences();
for (int j = 0; j < names.length; j++) {
String link = wrapper.findSecurityReference(names[j]);
if ((link != null) && !context.hasSecurityRole(link)) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, SECURITY_ROLE_NAME_USED_IN_LINK_WITHOUT_DEFINITION,
new Object[] {link, context.getName()});
}
context.addSecurityRole(link);
}
}
}
}
// START GlassFish 2439
protected class ContextErrorHandler
implements ErrorHandler {
public void error(SAXParseException exception) {
parseException = exception;
}
public void fatalError(SAXParseException exception) {
parseException = exception;
}
public void warning(SAXParseException exception) {
parseException = exception;
}
}
// END GlassFish 2439
} //end of public class