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-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2016 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.
*/
// Portions Copyright [2019-2021] Payara Foundation and/or affiliates
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.web.valve.GlassFishValve;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import jakarta.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 = LogFacade.getLogger();
private static final ResourceBundle rb = log.getResourceBundle();
// --------------------------------------------------- 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
*/
@Override
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(LogFacade.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
switch (event.getType()) {
case Lifecycle.START_EVENT:
start();
break;
case Lifecycle.STOP_EVENT:
stop();
// START GlassFish 2439
break;
case Lifecycle.INIT_EVENT:
init();
// END GlassFish 2439
break;
default:
break;
}
}
// -------------------------------------------------------- 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(LogFacade.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, LogFacade.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, LogFacade.NO_WEB_XML_INFO);
}
}
} catch (SAXParseException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.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(LogFacade.PARSE_ERROR_IN_APP_WEB_XML), e);
} finally {
try {
stream.close();
} catch (IOException e) {
log.log(Level.SEVERE, LogFacade.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 (GlassFishValve valve : valves) {
if (valve 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(LogFacade.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(LogFacade.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(LogFacade.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(LogFacade.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, LogFacade.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, LogFacade.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(LogFacade.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(LogFacade.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(LogFacade.PARSE_ERROR_IN_DEFAULT_WEB_XML), e);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
log.log(Level.SEVERE, LogFacade.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 {0} {1}", new Object[]{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 [{0}] configuration file {1} {2}", new Object[]{context.getName(), 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(LogFacade.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, LogFacade.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 [{0}] configuration file {1} {2}",
new Object[]{context.getName(), baseDir, resourceName});
} catch (SAXParseException e) {
String msg = MessageFormat.format(rb.getString(LogFacade.PARSE_ERROR_IN_DEFAULT_WEB_XML_EXCEPTION),
new Object[] {e.getLineNumber(), e.getColumnNumber()});
log.log(Level.SEVERE, LogFacade.PARSE_ERROR_IN_DEFAULT_WEB_XML, e);
log.log(Level.SEVERE, msg);
ok = false;
} catch (Exception e) {
log.log(Level.SEVERE, LogFacade.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, LogFacade.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, LogFacade.CONTEXT_CONFIG_INIT_FINE);
context.setConfigured(false);
ok = true;
contextConfig();
try {
fixDocBase();
} catch (IOException e) {
log.log(Level.SEVERE, LogFacade.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, LogFacade.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 (GlassFishValve valve : valves) {
log.log(Level.FINEST, " " + valve.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, LogFacade.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, LogFacade.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 (Container wrapper1 : wrappers) {
Wrapper wrapper = (Wrapper) wrapper1;
String runAs = wrapper.getRunAs();
if ((runAs != null) && !context.hasSecurityRole(runAs)) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, LogFacade.SECURITY_ROLE_NAME_USED_IN_RUNAS_WITHOUT_DEFINITION,
new Object[] {runAs, context.getName()});
}
context.addSecurityRole(runAs);
}
String names[] = wrapper.findSecurityReferences();
for (String name : names) {
String link = wrapper.findSecurityReference(name);
if ((link != null) && !context.hasSecurityRole(link)) {
if (log.isLoggable(Level.INFO)) {
log.log(Level.INFO, LogFacade.SECURITY_ROLE_NAME_USED_IN_LINK_WITHOUT_DEFINITION,
new Object[] {link, context.getName()});
}
context.addSecurityRole(link);
}
}
}
}
// START GlassFish 2439
protected class ContextErrorHandler
implements ErrorHandler {
@Override
public void error(SAXParseException exception) {
parseException = exception;
}
@Override
public void fatalError(SAXParseException exception) {
parseException = exception;
}
@Override
public void warning(SAXParseException exception) {
parseException = exception;
}
}
// END GlassFish 2439
} //end of public class