From 590f2a2034cd201581c48cea6d993f14d931cf3e Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 19 Sep 2009 20:13:22 +0000 Subject: [PATCH] First part of the Servlet3 web-fragment support. This patch inserts a stage into the web.xml processing. web.xml files are now parsed and loaded into an instance of WebXml and then that WebXml instance is used to configure the context. This will allow the subsequent addition of parsing and merging web-fragment.xml files. The hooks are in place to add this functionality but it has not yet been written. With the patch applied, the Servlet 2.5 TCK and JSP 2.1 TCK pass with the exception of the Servlet version number checks. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@816951 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/deploy/JspPropertyGroup.java | 84 ++++ java/org/apache/catalina/deploy/ServletDef.java | 209 +++++++++ .../org/apache/catalina/startup/ContextConfig.java | 518 +++++++++++---------- .../catalina/startup/LocalStrings.properties | 23 +- .../catalina/startup/LocalStrings_es.properties | 15 +- .../catalina/startup/LocalStrings_fr.properties | 13 - .../catalina/startup/LocalStrings_ja.properties | 13 - java/org/apache/catalina/startup/WebRuleSet.java | 130 +++--- java/org/apache/catalina/startup/WebXml.java | 503 +++++++++++++++++++- java/org/apache/catalina/startup/WebXmlCommon.java | 360 -------------- .../apache/catalina/startup/WebXmlFragment.java | 49 -- 11 files changed, 1145 insertions(+), 772 deletions(-) create mode 100644 java/org/apache/catalina/deploy/JspPropertyGroup.java create mode 100644 java/org/apache/catalina/deploy/ServletDef.java delete mode 100644 java/org/apache/catalina/startup/WebXmlCommon.java delete mode 100644 java/org/apache/catalina/startup/WebXmlFragment.java diff --git a/java/org/apache/catalina/deploy/JspPropertyGroup.java b/java/org/apache/catalina/deploy/JspPropertyGroup.java new file mode 100644 index 000000000..a208488dd --- /dev/null +++ b/java/org/apache/catalina/deploy/JspPropertyGroup.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +package org.apache.catalina.deploy; + +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Representation of a jsp-property-group element in web.xml. + */ +public class JspPropertyGroup { + private Boolean deferredSyntax = null; + public void setDeferredSyntax(String deferredSyntax) { + this.deferredSyntax = Boolean.valueOf(deferredSyntax); + } + public Boolean getDeferredSyntax() { return deferredSyntax; } + + private Boolean elIgnored = null; + public void setElIgnored(String elIgnored) { + this.elIgnored = Boolean.valueOf(elIgnored); + } + public Boolean getElIgnored() { return elIgnored; } + + private Set includeCodas = new LinkedHashSet(); + public void addIncludeCoda(String includeCoda) { + includeCodas.add(includeCoda); + } + public Set getIncludeCodas() { return includeCodas; } + + private Set includePreludes = new LinkedHashSet(); + public void addIncludePrelude(String includePrelude) { + includePreludes.add(includePrelude); + } + public Set getIncludePreludes() { return includePreludes; } + + private Boolean isXml = null; + public void setIsXml(String isXml) { + this.isXml = Boolean.valueOf(isXml); + } + public Boolean getIsXml() { return isXml; } + + private String pageEncoding = null; + public void setPageEncoding(String pageEncoding) { + this.pageEncoding = pageEncoding; + } + public String getPageEncoding() { return this.pageEncoding; } + + private Boolean scriptingInvalid = null; + public void setScriptingInvalid(String scriptingInvalid) { + this.scriptingInvalid = Boolean.valueOf(scriptingInvalid); + } + public Boolean getScriptingInvalid() { return scriptingInvalid; } + + private Boolean trimWhitespace = null; + public void setTrimWhitespace(String trimWhitespace) { + this.trimWhitespace = Boolean.valueOf(trimWhitespace); + } + public Boolean getTrimWhitespace() { return trimWhitespace; } + + private String urlPattern = null; + public void setUrlPattern(String urlPattern) { + this.urlPattern = urlPattern; + } + public String getUrlPattern() { return this.urlPattern; } + +} diff --git a/java/org/apache/catalina/deploy/ServletDef.java b/java/org/apache/catalina/deploy/ServletDef.java new file mode 100644 index 000000000..4a42b1178 --- /dev/null +++ b/java/org/apache/catalina/deploy/ServletDef.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.catalina.deploy; + + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.io.Serializable; + + +/** + * Representation of a servlet definition for a web application, as represented + * in a <servlet> element in the deployment descriptor. + */ + +public class ServletDef implements Serializable { + + + // ------------------------------------------------------------- Properties + + + /** + * The description of this servlet. + */ + private String description = null; + + public String getDescription() { + return (this.description); + } + + public void setDescription(String description) { + this.description = description; + } + + + /** + * The display name of this servlet. + */ + private String displayName = null; + + public String getDisplayName() { + return (this.displayName); + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + + /** + * The small icon associated with this servlet. + */ + private String smallIcon = null; + + public String getSmallIcon() { + return (this.smallIcon); + } + + public void setSmallIcon(String smallIcon) { + this.smallIcon = smallIcon; + } + + /** + * The large icon associated with this servlet. + */ + private String largeIcon = null; + + public String getLargeIcon() { + return (this.largeIcon); + } + + public void setLargeIcon(String largeIcon) { + this.largeIcon = largeIcon; + } + + + /** + * The name of this servlet, which must be unique among the servlets + * defined for a particular web application. + */ + private String servletName = null; + + public String getServletName() { + return (this.servletName); + } + + public void setServletName(String servletName) { + this.servletName = servletName; + } + + + /** + * The fully qualified name of the Java class that implements this servlet. + */ + private String servletClass = null; + + public String getServletClass() { + return (this.servletClass); + } + + public void setServletClass(String servletClass) { + this.servletClass = servletClass; + } + + + /** + * The name of the JSP file to which this servlet definition applies + */ + private String jspFile = null; + + public String getJspFile() { + return (this.jspFile); + } + + public void setJspFile(String jspFile) { + this.jspFile = jspFile; + } + + + /** + * The set of initialization parameters for this servlet, keyed by + * parameter name. + */ + private Map parameters = new HashMap(); + + public Map getParameterMap() { + + return (this.parameters); + + } + + /** + * Add an initialization parameter to the set of parameters associated + * with this servlet. + * + * @param name The initialisation parameter name + * @param value The initialisation parameter value + */ + public void addInitParameter(String name, String value) { + + parameters.put(name, value); + + } + + /** + * The load-on-startup order for this servlet + */ + private Integer loadOnStartup = null; + + public Integer getLoadOnStartup() { + return (this.loadOnStartup); + } + + public void setLoadOnStartup(String loadOnStartup) { + this.loadOnStartup = Integer.valueOf(loadOnStartup); + } + + + /** + * The run-as configuration for this servlet + */ + private String runAs = null; + + public String getRunAs() { + return (this.runAs); + } + + public void setRunAs(String runAs) { + this.runAs = runAs; + } + + + /** + * The set of security role references for this servlet + */ + private Set securityRoleRefs = + new HashSet(); + + public Set getSecurityRoleRefs() { + return (this.securityRoleRefs); + } + + /** + * Add a security-role-ref to the set of security-role-refs associated + * with this servlet. + */ + public void addSecurityRoleRef(SecurityRoleRef securityRoleRef) { + securityRoleRefs.add(securityRoleRef); + } + +} diff --git a/java/org/apache/catalina/startup/ContextConfig.java b/java/org/apache/catalina/startup/ContextConfig.java index cfff3e466..3f0346455 100644 --- a/java/org/apache/catalina/startup/ContextConfig.java +++ b/java/org/apache/catalina/startup/ContextConfig.java @@ -24,7 +24,9 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -294,100 +296,6 @@ public class ContextConfig /** - * Process the application configuration file, if it exists. - */ - protected void applicationWebConfig() { - - 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) { - log.error(sm.getString("contextConfig.altDDNotFound", - altDDName)); - } - } - else { - stream = servletContext.getResourceAsStream - (Constants.ApplicationWebXml); - } - } - if (stream == null) { - if (log.isDebugEnabled()) { - log.debug(sm.getString("contextConfig.applicationMissing") + " " + context); - } - return; - } - - long t1=System.currentTimeMillis(); - - URL url=null; - // Process the application web.xml file - synchronized (webDigester) { - try { - if (altDDName != null) { - url = new File(altDDName).toURI().toURL(); - } else { - url = servletContext.getResource( - Constants.ApplicationWebXml); - } - if( url!=null ) { - InputSource is = new InputSource(url.toExternalForm()); - is.setByteStream(stream); - if (context instanceof StandardContext) { - ((StandardContext) context).setReplaceWelcomeFiles(true); - } - webDigester.push(context); - ContextErrorHandler errorHandler = new ContextErrorHandler(); - webDigester.setErrorHandler(errorHandler); - - if(log.isDebugEnabled()) { - log.debug("Parsing application web.xml file at " + url.toExternalForm()); - } - - webDigester.parse(is); - - if (errorHandler.getParseException() != null) { - ok = false; - } - } else { - log.info("No web.xml, using defaults " + context ); - } - } catch (SAXParseException e) { - log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e); - log.error(sm.getString("contextConfig.applicationPosition", - "" + e.getLineNumber(), - "" + e.getColumnNumber())); - ok = false; - } catch (Exception e) { - log.error(sm.getString("contextConfig.applicationParse", url.toExternalForm()), e); - ok = false; - } finally { - webDigester.reset(); - try { - stream.close(); - } catch (IOException e) { - log.error(sm.getString("contextConfig.applicationClose"), e); - } - } - } - webRuleSet.recycle(); - - long t2=System.currentTimeMillis(); - if (context instanceof StandardContext) { - ((StandardContext) context).setStartupTime(t2-t1); - } - } - - - /** * Set up an Authenticator automatically if required, and one has not * already been configured. */ @@ -560,157 +468,7 @@ public class ContextConfig 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 defaultWebConfig() { - 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 ) { - log.info("No default web.xml"); - } - } else { - source = - new InputSource("file://" + file.getAbsolutePath()); - stream = new FileInputStream(file); - context.addWatchedResource(file.getAbsolutePath()); - } - } catch (Exception e) { - log.error(sm.getString("contextConfig.defaultMissing") - + " " + defaultWebXml + " " + file , e); - } - - if (stream != null) { - processDefaultWebConfig(webDigester, stream, source); - webRuleSet.recycle(); - } - - long t2=System.currentTimeMillis(); - if( (t2-t1) > 200 ) - log.debug("Processed default web.xml " + file + " " + ( t2-t1)); - - stream = null; - source = null; - - String resourceName = getHostConfigPath(Constants.HostWebXml); - file = new File(getConfigBase(), resourceName); - - try { - if ( ! file.exists() ) { - // 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); - } - } catch (Exception e) { - log.error(sm.getString("contextConfig.defaultMissing") - + " " + resourceName + " " + file , e); - } - - if (stream != null) { - processDefaultWebConfig(webDigester, stream, source); - webRuleSet.recycle(); - } - - } - - - /** - * Process a default web.xml. - */ - protected void processDefaultWebConfig(Digester digester, InputStream stream, - InputSource source) { - - if (log.isDebugEnabled()) - log.debug("Processing context [" + context.getName() - + "] web configuration resource " + source.getSystemId()); - - // Process the default web.xml file - synchronized (digester) { - try { - source.setByteStream(stream); - - if (context instanceof StandardContext) - ((StandardContext) context).setReplaceWelcomeFiles(true); - digester.setClassLoader(this.getClass().getClassLoader()); - digester.setUseContextClassLoader(false); - digester.push(context); - ContextErrorHandler errorHandler = new ContextErrorHandler(); - digester.setErrorHandler(errorHandler); - digester.parse(source); - if (errorHandler.getParseException() != null) { - ok = false; - } - } catch (SAXParseException e) { - log.error(sm.getString("contextConfig.defaultParse"), e); - log.error(sm.getString("contextConfig.defaultPosition", - "" + e.getLineNumber(), - "" + e.getColumnNumber())); - ok = false; - } catch (Exception e) { - log.error(sm.getString("contextConfig.defaultParse"), e); - ok = false; - } finally { - digester.reset(); - try { - if (stream != null) { - stream.close(); - } - } catch (IOException e) { - log.error(sm.getString("contextConfig.defaultClose"), e); - } - } - } - } - - + /** * Process the default configuration file, if it exists. */ @@ -1060,8 +818,8 @@ public class ContextConfig } webDigester = createWebXmlDigester(useXmlNamespaceAware, useXmlValidation); - defaultWebConfig(); - applicationWebConfig(); + webConfig(); + if (!context.getIgnoreAnnotations()) { applicationAnnotationsConfig(); } @@ -1360,6 +1118,272 @@ public class ContextConfig } + /** + * Scan the web.xml files that apply to the web application and merge them + * using the rules defined in the spec. For the global web.xml files, + * where there is duplicate configuration, the most specific level wins. ie + * an application's web.xml takes precedence over the host level or global + * web.xml file. + */ + protected void webConfig() { + WebXml webXml = new WebXml(); + // Parse global web.xml if present + InputSource globalWebXml = getGlobalWebXmlSource(); + if (globalWebXml == null) { + // This is unusual enough to log + log.info(sm.getString("contextConfig.defaultMissing")); + } else { + parseWebXml(globalWebXml, webXml); + } + + // Parse host level web.xml if present + // Additive apart from welcome pages + webXml.setReplaceWelcomeFiles(true); + InputSource hostWebXml = getHostWebXmlSource(); + parseWebXml(hostWebXml, webXml); + + // Parse context level web.xml + webXml.setReplaceWelcomeFiles(true); + InputSource contextWebXml = getContextWebXmlSource(); + parseWebXml(contextWebXml, webXml); + + if (!webXml.isMetadataComplete()) { + // Have to process JARs for fragments + Map fragments = processJarsForWebFragments(); + + // Merge the fragments into the main web.xml + mergeWebFragments(webXml, fragments); + + // Apply merged web.xml to Context + webXml.configureContext(context); + + // Process JARs for annotations + processAnnotationsInJars(fragments); + + // Process /WEB-INF/classes for annotations + // TODO SERVLET3 + } else { + // Apply merged web.xml to Context + webXml.configureContext(context); + } + } + + + /** + * Identify the default web.xml to be used and obtain an input source for + * it. + */ + protected InputSource getGlobalWebXmlSource() { + // Is a default web.xml specified for the Context? + if (defaultWebXml == null && context instanceof StandardContext) { + defaultWebXml = ((StandardContext) context).getDefaultWebXml(); + } + // Set the default if we don't have any overrides + if (defaultWebXml == null) getDefaultWebXml(); + + return getWebXmlSource(defaultWebXml, getBaseDir()); + } + + /** + * Identify the host web.xml to be used and obtain an input source for + * it. + */ + protected InputSource getHostWebXmlSource() { + String resourceName = getHostConfigPath(Constants.HostWebXml); + + String basePath = null; + try { + basePath = getConfigBase().getCanonicalPath(); + } catch (IOException e) { + log.error(sm.getString("contectConfig.baseError"), e); + return null; + } + + return getWebXmlSource(resourceName, basePath); + } + + /** + * Identify the application web.xml to be used and obtain an input source + * for it. + */ + protected InputSource getContextWebXmlSource() { + InputStream stream = null; + InputSource source = null; + URL url = null; + + String altDDName = null; + + // Open the application web.xml file, if it exists + ServletContext servletContext = context.getServletContext(); + if (servletContext != null) { + altDDName = (String)servletContext.getAttribute( + Globals.ALT_DD_ATTR); + if (altDDName != null) { + try { + stream = new FileInputStream(altDDName); + url = new File(altDDName).toURI().toURL(); + } catch (FileNotFoundException e) { + log.error(sm.getString("contextConfig.altDDNotFound", + altDDName)); + } catch (MalformedURLException e) { + log.error(sm.getString("contextConfig.applicationUrl")); + } + } + else { + stream = servletContext.getResourceAsStream + (Constants.ApplicationWebXml); + try { + url = servletContext.getResource( + Constants.ApplicationWebXml); + } catch (MalformedURLException e) { + log.error(sm.getString("contextConfig.applicationUrl")); + } + } + } + if (stream == null || url == null) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("contextConfig.applicationMissing") + " " + context); + } + } else { + source = new InputSource(url.toExternalForm()); + source.setByteStream(stream); + } + + return source; + } + + /** + * + * @param filename Name of the file (possibly with one or more leading path + * segemnts) to read + * @param path Location that filename is relative to + * @return + */ + protected InputSource getWebXmlSource(String filename, String path) { + File file = new File(filename); + if (!file.isAbsolute()) { + file = new File(path, filename); + } + + InputStream stream = null; + InputSource source = null; + + try { + if (!file.exists()) { + // Use getResource and getResourceAsStream + stream = + getClass().getClassLoader().getResourceAsStream(filename); + if(stream != null) { + source = + new InputSource(getClass().getClassLoader().getResource( + filename).toString()); + } + } else { + source = new InputSource("file://" + file.getAbsolutePath()); + stream = new FileInputStream(file); + context.addWatchedResource(file.getAbsolutePath()); + } + + if (stream != null && source != null) { + source.setByteStream(stream); + } + } catch (Exception e) { + log.error(sm.getString( + "contextConfig.defaultError", filename, file), e); + } + + return source; + } + + + protected void parseWebXml(InputSource source, WebXml dest) { + + if (source == null) return; + + ContextErrorHandler handler = new ContextErrorHandler(); + + // Web digesters and rulesets are shared between contexts but are not + // thread safe. Whilst there should only be one thread at a time + // processing a config, play safe and sync. + synchronized(webDigester) { + + webDigester.push(dest); + webDigester.setErrorHandler(handler); + + if(log.isDebugEnabled()) { + log.debug(sm.getString("contextConfig.applicationStart", + source.getSystemId())); + } + + try { + webDigester.parse(source); + + if (handler.getParseException() != null) { + ok = false; + } + } catch (SAXParseException e) { + log.error(sm.getString("contextConfig.applicationParse", + source.getSystemId()), e); + log.error(sm.getString("contextConfig.applicationPosition", + "" + e.getLineNumber(), + "" + e.getColumnNumber())); + ok = false; + } catch (Exception e) { + log.error(sm.getString("contextConfig.applicationParse", + source.getSystemId()), e); + ok = false; + } finally { + webDigester.reset(); + webRuleSet.recycle(); + } + } + } + + + /** + * Scan /META-INF/lib for JARs and for each one found add it and any + * /META-INF/web-fragment.xml to the resulting Map. web-fragment.xml files + * will be parsed before being added to the map. Every JAR will be added and + * null will be used if no web-fragment.xml was found. Any JARs + * known not contain fragments will be skipped. + * + * @return A map of JAR name to processed web fragment (if any) + */ + protected Map processJarsForWebFragments() { + // TODO SERVLET3 + return new HashMap(); + } + + + /** + * Merges the web-fragment.xml and web.xml files as per the rules in the + * Servlet spec. + * + * @param application The application web.xml file + * @param fragments The map of JARs to web fragments + */ + protected void mergeWebFragments(WebXml application, + Map fragments) { + // TODO SERVLET3 + // Check order + + // Merge fragments in order - conflict == error + + // Merge fragment into application - conflict == application wins + } + + + protected void processAnnotationsInJars(Map fragments) { + for(String jar : fragments.keySet()) { + WebXml fragment = fragments.get(jar); + if (fragment == null || !fragment.isMetadataComplete()) { + // Scan jar for annotations + // TODO SERVLET3 + } + } + } + + protected static class ContextErrorHandler implements ErrorHandler { diff --git a/java/org/apache/catalina/startup/LocalStrings.properties b/java/org/apache/catalina/startup/LocalStrings.properties index 6a93bd726..594f4e4c1 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -14,27 +14,25 @@ # limitations under the License. catalina.stopServer=No shutdown port configured. Shut down server through OS signal. Server not shut down. -contextConfig.applicationClose=Error closing application web.xml -contextConfig.applicationConfig=Configuration error in application web.xml -contextConfig.applicationListener=Exception creating listener of class {0} +contextConfig.altDDNotFound=alt-dd file {0} not found +contextConfig.applicationUrl=Unable to determine URL for application web.xml contextConfig.applicationMissing=Missing application web.xml, using defaults only contextConfig.applicationParse=Parse error in application web.xml file at {0} contextConfig.applicationPosition=Occurred at line {0} column {1} +contextConfig.applicationStart=Parsing application web.xml file at {0} contextConfig.authenticatorConfigured=Configured an authenticator for method {0} contextConfig.authenticatorInstantiate=Cannot instantiate an authenticator of class {0} contextConfig.authenticatorMissing=Cannot configure an authenticator for method {0} contextConfig.authenticatorResources=Cannot load authenticators mapping list +contectConfig.baseError=Unable to determine $CATALINA_BASE contextConfig.cce=Lifecycle event data object {0} is not a Context -contextConfig.certificatesConfig.added=Added certificates -> request attribute Valve -contextConfig.certificatesConfig.error=Exception adding CertificatesValve: contextConfig.contextClose=Error closing context.xml contextConfig.contextMissing=Missing context.xml: {0} contextConfig.contextParse=Parse error in context.xml for {0} -contextConfig.defaultClose=Error closing default web.xml -contextConfig.defaultConfig=Configuration error in default web.xml -contextConfig.defaultMissing=Missing default web.xml, using application web.xml only -contextConfig.defaultParse=Parse error in default web.xml +contextConfig.defaultError=Error processed default web.xml named {0} at {1} +contextConfig.defaultMissing=No global web.xml found contextConfig.defaultPosition=Occurred at line {0} column {1} +contextConfig.destroy=ContextConfig: Destroying contextConfig.fixDocBase=Exception fixing docBase for context [{0}] contextConfig.init=ContextConfig: Initializing contextConfig.missingRealm=No Realm has been configured to authenticate against @@ -43,13 +41,8 @@ contextConfig.role.link=WARNING: Security role name {0} used in a wi contextConfig.role.runas=WARNING: Security role name {0} used in a without being defined in a contextConfig.start=ContextConfig: Processing START contextConfig.stop=ContextConfig: Processing STOP -contextConfig.tldEntryException=Exception processing TLD {0} in JAR at resource path {1} in context {2} -contextConfig.tldFileException=Exception processing TLD at resource path {0} in context {1} -contextConfig.tldJarException=Exception processing JAR at resource path {0} in context {1} -contextConfig.tldResourcePath=Invalid TLD resource path {0} -contextConfig.xmlSettings=Context [{0}] will parse web.xml and web-fragment.xml files with validation:{1} and namespaceAware:{2} contextConfig.unavailable=Marking this application unavailable due to previous error(s) -contextConfig.altDDNotFound=alt-dd file {0} not found +contextConfig.xmlSettings=Context [{0}] will parse web.xml and web-fragment.xml files with validation:{1} and namespaceAware:{2} embedded.alreadyStarted=Embedded service has already been started embedded.noEngines=No engines have been defined yet embedded.notmp=Cannot find specified temporary folder at {0} diff --git a/java/org/apache/catalina/startup/LocalStrings_es.properties b/java/org/apache/catalina/startup/LocalStrings_es.properties index 1e49be560..d4c132ee5 100644 --- a/java/org/apache/catalina/startup/LocalStrings_es.properties +++ b/java/org/apache/catalina/startup/LocalStrings_es.properties @@ -12,9 +12,7 @@ # 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. -contextConfig.applicationClose = Error durante el cierre del archivo web.xml de la aplicaci\u00F3n -contextConfig.applicationConfig = Error de configuraci\u00F3n en el archivo web.xml de la aplicaci\u00F3n -contextConfig.applicationListener = Excepci\u00F3n durante la creaci\u00F3n de la clase de escucha (listener) {0} +contextConfig.altDDNotFound = fichero alt-dd {0} no hallado contextConfig.applicationMissing = Falta el archivo web.xml de la aplicaci\u00F3n. Utilizando los par\u00E1metros por defecto contextConfig.applicationParse = Error de evaluaci\u00F3n (parse) en el archivo web.xml de la aplicaci\u00F3n a {0} contextConfig.applicationPosition = Se ha producido en la l\u00EDnea {0} columna {1} @@ -23,15 +21,9 @@ contextConfig.authenticatorInstantiate = Imposible de instanciar un autenticador contextConfig.authenticatorMissing = Imposible de configurar un autentificador (authenticator) para el m\u00E9todo {0} contextConfig.authenticatorResources = Imposible de cargar la lista de correspondencia de autenticadores (authenticators) contextConfig.cce = El objeto de los datos de evento de ciclo de vida (Lifecycle event data object) {0} no es un Contexto -contextConfig.certificatesConfig.added = Adici\u00F3n de certificados -> requiere v\u00E1lvula de atributo (attribute Valve) -contextConfig.certificatesConfig.error = Excepci\u00F3n durante la adici\u00F3n de "CertificatesValve"\: contextConfig.contextClose = Error cerrando context.xml\: {0} contextConfig.contextMissing = Falta context.xml\: {0} contextConfig.contextParse = Error de an\u00E1lisis en context.xml\: {0} -contextConfig.defaultClose = Error durante el cierre del archivo web.xml por defecto -contextConfig.defaultConfig = Error de configuraci\u00F3n en el archivo web.xml por defecto -contextConfig.defaultMissing = Falta el archivo web.xml por defecto, utilizando s\u00F3lo el archivo web.xml de la aplicaci\u00F3n -contextConfig.defaultParse = Error de evaluaci\u00F3n (parse) en el arcivo web.xml por defecto contextConfig.defaultPosition = Se ha producido en la l\u00EDnea {0} columna {1} contextConfig.fixDocBase = Excepci\u00F3n arreglando docBase\: {0} contextConfig.init = ContextConfig\: Inicializando @@ -41,12 +33,7 @@ contextConfig.role.link = ATENCI\u00D3N\: El nombre de papel de seguridad {0} es contextConfig.role.runas = ATENCI\u00D3N\: El nombre de papel de seguridad {0} es usado en un sin haber sido definido en contextConfig.start = "ContextConfig"\: Tratamiento del "START" contextConfig.stop = "ContextConfig"\: Tratamiento del "STOP" -contextConfig.tldEntryException = Excepci\u00F3n durante el tratamiento de la TLD {0} en el JAR indicado por la trayectoria de recurso {1} en contexto {2} -contextConfig.tldFileException = Excepci\u00F3n durante el tratamiento de la TLD indicada por la trayectoria de recurso {0} en contexto {1} -contextConfig.tldJarException = Excepci\u00F3n durante el tratamiento del JAR indicado por la trayectoria de recurso {0} en contexto {1} -contextConfig.tldResourcePath = Trayectoria de recurso TLD {0} inv\u00E1lida contextConfig.unavailable = Esta aplicaci\u00F3n est\u00E1 marcada como no disponible debido a los errores precedentes -contextConfig.altDDNotFound = fichero alt-dd {0} no hallado embedded.alreadyStarted = El servicio embebido (embedded service) ya ha sido arrancado embedded.noEngines = Alg\u00FAn motor (engine) no ha sido a\u00FAn definido embedded.notmp = No puedo hallar carpeta temporal especificada en {0} diff --git a/java/org/apache/catalina/startup/LocalStrings_fr.properties b/java/org/apache/catalina/startup/LocalStrings_fr.properties index 564ede9e6..c709d2aab 100644 --- a/java/org/apache/catalina/startup/LocalStrings_fr.properties +++ b/java/org/apache/catalina/startup/LocalStrings_fr.properties @@ -13,9 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -contextConfig.applicationClose=Erreur lors de la fermeture du fichier web.xml de l''application -contextConfig.applicationConfig=Erreur de configuration dans le fichier web.xml de l''application -contextConfig.applicationListener=Exception lors de la cr\u00e9ation de la classe d''\u00e9coute (listener) {0} contextConfig.applicationMissing=Le fichier web.xml de l''application est absent, utilisation des param\u00eatres par d\u00e9faut contextConfig.applicationParse=Erreur d''\u00e9valuation (parse) dans le fichier web.xml de l''application \u00e0 {0} contextConfig.applicationPosition=S''est produite \u00e0 la ligne {0} colonne {1} @@ -24,12 +21,6 @@ contextConfig.authenticatorInstantiate=Impossible d''instancier un authentificat contextConfig.authenticatorMissing=Impossible de configurer un authentificateur (authenticator) pour la m\u00e9thode {0} contextConfig.authenticatorResources=Impossible de charger la liste de correspondance des authentificateur (authenticators) contextConfig.cce=L''objet donn\u00e9e \u00e9v\u00e8nement cycle de vie (Lifecycle event data object) {0} n''est pas un Contexte -contextConfig.certificatesConfig.added=Ajout de certificats -> requ\u00eate Attribut de Valve (attribute Valve) -contextConfig.certificatesConfig.error=Exception lors de l''ajout des "CertificatesValve": -contextConfig.defaultClose=Erreur lors de la fermeture du fichier web.xml par d\u00e9faut -contextConfig.defaultConfig=Erreur de configuration dans le fichier web.xml par d\u00e9faut -contextConfig.defaultMissing=Le fichier web.xml par d\u00e9faut est absent, utilisation du fichier web.xml de l''application web.xml seulement -contextConfig.defaultParse=Erreur d''\u00e9valuation (parse) dans le fichier web.xml par d\u00e9faut contextConfig.defaultPosition=S''est produite \u00e0 la ligne {0} colonne {1} contextConfig.missingRealm=Aucun royaume (realm) n''a \u00e9t\u00e9 configur\u00e9 pour r\u00e9aliser l''authentification contextConfig.role.auth=ATTENTION: Le nom de r\u00f4le de s\u00e9curit\u00e9 {0} est utilis\u00e9 dans un sans avoir \u00e9t\u00e9 d\u00e9fini dans @@ -37,10 +28,6 @@ contextConfig.role.link=ATTENTION: Le nom de r\u00f4le de s\u00e9curit\u00e9 {0} contextConfig.role.runas=ATTENTION: Le nom de r\u00f4le de s\u00e9curit\u00e9 {0} est utilis\u00e9 dans un sans avoir \u00e9t\u00e9 d\u00e9fini dans contextConfig.start="ContextConfig": Traitement du "START" contextConfig.stop="ContextConfig": Traitement du "STOP" -contextConfig.tldEntryException=Exception lors du traitement de la TLD {0} dans le JAR indiqu\u00e9 par le chemin de ressource {1} dans le contexte {2} -contextConfig.tldFileException=Exception lors du traitement de la TLD indiqu\u00e9 par le chemin de ressource {0} dans le contexte {1} -contextConfig.tldJarException=Exception lors du traitement du JAR indiqu\u00e9 par le chemin de ressource {0} dans le contexte {1} -contextConfig.tldResourcePath=Chemin de ressource TLD {0} invalide contextConfig.unavailable=Cette application est marqu\u00e9e comme non disponible suite aux erreurs pr\u00e9c\u00e9dentes embedded.alreadyStarted=Le service enfoui (embedded service) a d\u00e9j\u00e0 \u00e9t\u00e9 d\u00e9marr\u00e9 embedded.noEngines=Aucun moteur (engine) n''a encore \u00e9t\u00e9 d\u00e9fini diff --git a/java/org/apache/catalina/startup/LocalStrings_ja.properties b/java/org/apache/catalina/startup/LocalStrings_ja.properties index 41466088a..ea9173831 100644 --- a/java/org/apache/catalina/startup/LocalStrings_ja.properties +++ b/java/org/apache/catalina/startup/LocalStrings_ja.properties @@ -13,9 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -contextConfig.applicationClose=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306eweb.xml\u3092\u30af\u30ed\u30fc\u30ba\u4e2d\u306e\u30a8\u30e9\u30fc\u3067\u3059 -contextConfig.applicationConfig=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306eweb.xml\u306e\u8a2d\u5b9a\u30a8\u30e9\u30fc\u3067\u3059 -contextConfig.applicationListener=\u30af\u30e9\u30b9 {0} \u306e\u30ea\u30b9\u30ca\u3092\u4f5c\u6210\u4e2d\u306e\u4f8b\u5916\u3067\u3059 contextConfig.applicationMissing=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306eweb.xml\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u3060\u3051\u3092\u4f7f\u7528\u3057\u307e\u3059 contextConfig.applicationParse=\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306eweb.xml\u30d5\u30a1\u30a4\u30eb {0} \u306e\u89e3\u6790\u30a8\u30e9\u30fc\u3067\u3059 contextConfig.applicationPosition={0}\u884c\u306e{1}\u5217\u76ee\u3067\u767a\u751f\u3057\u307e\u3057\u305f @@ -24,12 +21,6 @@ contextConfig.authenticatorInstantiate=\u30af\u30e9\u30b9 {0} \u306e\u30aa\u30fc contextConfig.authenticatorMissing=\u30e1\u30bd\u30c3\u30c9 {0} \u306e\u30aa\u30fc\u30bb\u30f3\u30c6\u30a3\u30b1\u30fc\u30bf\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093 contextConfig.authenticatorResources=\u30aa\u30fc\u30bb\u30f3\u30c6\u30a3\u30b1\u30fc\u30bf\u306e\u30de\u30c3\u30d7\u30ea\u30b9\u30c8\u3092\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093 contextConfig.cce=\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u30a4\u30d9\u30f3\u30c8\u30c7\u30fc\u30bf\u30aa\u30d6\u30b8\u30a7\u30af\u30c8 {0} \u306f\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u306f\u3042\u308a\u307e\u305b\u3093 -contextConfig.certificatesConfig.added=\u8a3c\u660e\u66f8\u3092\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u5c5e\u6027\u5024\u306b\u8ffd\u52a0\u3057\u307e\u3059 -contextConfig.certificatesConfig.error=CertificatesValve\u3092\u8ffd\u52a0\u4e2d\u306b\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f: -contextConfig.defaultClose=\u30c7\u30d5\u30a9\u30eb\u30c8\u306eweb.xml\u306e\u30af\u30ed\u30fc\u30ba\u4e2d\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f -contextConfig.defaultConfig=\u30c7\u30d5\u30a9\u30eb\u30c8\u306eweb.xml\u306e\u4e2d\u306e\u8a2d\u5b9a\u30a8\u30e9\u30fc\u3067\u3059 -contextConfig.defaultMissing=\u30c7\u30d5\u30a9\u30eb\u30c8\u306eweb.xml\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306eweb.xml\u3060\u3051\u3092\u4f7f\u7528\u3057\u307e\u3059 -contextConfig.defaultParse=\u30c7\u30d5\u30a9\u30eb\u30c8\u306eweb.xml\u4e2d\u306e\u89e3\u6790\u30a8\u30e9\u30fc\u3067\u3059 contextConfig.defaultPosition={0}\u884c\u306e{1}\u5217\u76ee\u3067\u767a\u751f\u3057\u307e\u3057\u305f contextConfig.missingRealm=\u8a8d\u8a3c\u3059\u308b\u305f\u3081\u306b\u30ec\u30eb\u30e0\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 contextConfig.role.auth=\u8b66\u544a: \u306b\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u306a\u3044\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ed\u30fc\u30eb\u540d {0} \u304c\u306e\u4e2d\u3067\u4f7f\u7528\u3055\u308c\u307e\u3057\u305f @@ -37,10 +28,6 @@ contextConfig.role.link=\u8b66\u544a: \u306b\u5b9a\u7fa9\u3055\u3 contextConfig.role.runas=\u8b66\u544a: \u306b\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u306a\u3044\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ed\u30fc\u30eb\u540d {0} \u304c\u306e\u4e2d\u3067\u4f7f\u7528\u3055\u308c\u307e\u3057\u305f contextConfig.start=ContextConfig: \u51e6\u7406\u3092\u958b\u59cb\u3057\u307e\u3059 contextConfig.stop=ContextConfig: \u51e6\u7406\u3092\u505c\u6b62\u3057\u307e\u3059 -contextConfig.tldEntryException=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8 {2} \u306e\u30ea\u30bd\u30fc\u30b9\u30d1\u30b9 {1} \u306eJAR\u30d5\u30a1\u30a4\u30eb\u306eTLD {0} \u3092\u51e6\u7406\u4e2d\u306e\u4f8b\u5916\u3067\u3059 -contextConfig.tldFileException=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8 {1} \u306e\u30ea\u30bd\u30fc\u30b9\u30d1\u30b9 {0} \u306eTLD\u3092\u51e6\u7406\u4e2d\u306e\u4f8b\u5916\u3067\u3059 -contextConfig.tldJarException=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8 {1} \u306e\u30ea\u30bd\u30fc\u30b9\u30d1\u30b9 {0} \u306eJAR\u30d5\u30a1\u30a4\u30eb\u3092\u51e6\u7406\u4e2d\u306e\u4f8b\u5916\u3067\u3059 -contextConfig.tldResourcePath=\u7121\u52b9\u306aTLD\u306e\u30ea\u30bd\u30fc\u30b9\u30d1\u30b9 {0} contextConfig.unavailable=\u524d\u306e\u30a8\u30e9\u30fc\u306e\u305f\u3081\u306b\u3053\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306f\u5229\u7528\u3067\u304d\u306a\u3044\u3088\u3046\u306b\u30de\u30fc\u30af\u3057\u307e\u3059 embedded.alreadyStarted=\u7d44\u307f\u8fbc\u307f\u30b5\u30fc\u30d3\u30b9\u306f\u65e2\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059 embedded.noEngines=\u307e\u3060\u30a8\u30f3\u30b8\u30f3\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093 diff --git a/java/org/apache/catalina/startup/WebRuleSet.java b/java/org/apache/catalina/startup/WebRuleSet.java index 345f02202..69b6b3825 100644 --- a/java/org/apache/catalina/startup/WebRuleSet.java +++ b/java/org/apache/catalina/startup/WebRuleSet.java @@ -22,11 +22,10 @@ package org.apache.catalina.startup; import java.lang.reflect.Method; import java.util.ArrayList; -import org.apache.catalina.Context; -import org.apache.catalina.Wrapper; import org.apache.catalina.deploy.ContextHandler; import org.apache.catalina.deploy.ContextService; import org.apache.catalina.deploy.SecurityConstraint; +import org.apache.catalina.deploy.ServletDef; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tomcat.util.digester.CallMethodRule; import org.apache.tomcat.util.digester.CallParamRule; @@ -128,7 +127,7 @@ public class WebRuleSet extends RuleSetBase { new IgnoreAnnotationsRule()); digester.addCallMethod(prefix + "web-app/context-param", - "addParameter", 2); + "addContextParam", 2); digester.addCallParam(prefix + "web-app/context-param/param-name", 0); digester.addCallParam(prefix + "web-app/context-param/param-value", 1); @@ -156,7 +155,7 @@ public class WebRuleSet extends RuleSetBase { digester.addObjectCreate(prefix + "web-app/filter", "org.apache.catalina.deploy.FilterDef"); digester.addSetNext(prefix + "web-app/filter", - "addFilterDef", + "addFilter", "org.apache.catalina.deploy.FilterDef"); digester.addCallMethod(prefix + "web-app/filter/description", @@ -184,7 +183,7 @@ public class WebRuleSet extends RuleSetBase { digester.addObjectCreate(prefix + "web-app/filter-mapping", "org.apache.catalina.deploy.FilterMap"); digester.addSetNext(prefix + "web-app/filter-mapping", - "addFilterMap", + "addFilterMapping", "org.apache.catalina.deploy.FilterMap"); digester.addCallMethod(prefix + "web-app/filter-mapping/filter-name", @@ -198,13 +197,34 @@ public class WebRuleSet extends RuleSetBase { "setDispatcher", 0); digester.addCallMethod(prefix + "web-app/listener/listener-class", - "addApplicationListener", 0); + "addListener", 0); digester.addRule(prefix + "web-app/jsp-config", jspConfig); - + + digester.addObjectCreate(prefix + "web-app/jsp-config/jsp-property-group", + "org.apache.catalina.deploy.JspPropertyGroup"); + digester.addSetNext(prefix + "web-app/jsp-config/jsp-property-group", + "addJspPropertyGroup", + "org.apache.catalina.deploy.JspPropertyGroup"); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/deferred-syntax-allowed-as-literal", + "setDeferredSyntax", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/el-ignored", + "setElIgnored", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/include-coda", + "addIncludeCoda", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/include-prelude", + "addIncludePrelude", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/is-xml", + "setIsXml", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/page-encoding", + "setPageEncoding", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/scripting-invalid", + "setScriptingInvalid", 0); + digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/trim-directive-whitespaces", + "setTrimWhitespace", 0); digester.addCallMethod(prefix + "web-app/jsp-config/jsp-property-group/url-pattern", - "addJspMapping", 0); + "setUrlPattern", 0); digester.addRule(prefix + "web-app/login-config", loginConfig); @@ -233,7 +253,7 @@ public class WebRuleSet extends RuleSetBase { digester.addObjectCreate(prefix + "web-app/security-constraint", "org.apache.catalina.deploy.SecurityConstraint"); digester.addSetNext(prefix + "web-app/security-constraint", - "addConstraint", + "addSecurityConstraint", "org.apache.catalina.deploy.SecurityConstraint"); digester.addRule(prefix + "web-app/security-constraint/auth-constraint", @@ -261,10 +281,10 @@ public class WebRuleSet extends RuleSetBase { "addSecurityRole", 0); digester.addRule(prefix + "web-app/servlet", - new WrapperCreateRule()); + new ServletDefCreateRule()); digester.addSetNext(prefix + "web-app/servlet", - "addChild", - "org.apache.catalina.Container"); + "addServlet", + "org.apache.catalina.deploy.ServletDef"); digester.addCallMethod(prefix + "web-app/servlet/init-param", "addInitParameter", 2); @@ -276,19 +296,19 @@ public class WebRuleSet extends RuleSetBase { digester.addCallMethod(prefix + "web-app/servlet/jsp-file", "setJspFile", 0); digester.addCallMethod(prefix + "web-app/servlet/load-on-startup", - "setLoadOnStartupString", 0); + "setLoadOnStartup", 0); digester.addCallMethod(prefix + "web-app/servlet/run-as/role-name", "setRunAs", 0); digester.addCallMethod(prefix + "web-app/servlet/security-role-ref", - "addSecurityReference", 2); + "addSecurityRoleRef", 2); digester.addCallParam(prefix + "web-app/servlet/security-role-ref/role-link", 1); digester.addCallParam(prefix + "web-app/servlet/security-role-ref/role-name", 0); digester.addCallMethod(prefix + "web-app/servlet/servlet-class", "setServletClass", 0); digester.addCallMethod(prefix + "web-app/servlet/servlet-name", - "setName", 0); + "setServletName", 0); digester.addRule(prefix + "web-app/servlet-mapping", new CallMethodMultiRule("addServletMapping", 2, 0)); @@ -321,7 +341,7 @@ public class WebRuleSet extends RuleSetBase { "addWelcomeFile", 0); digester.addCallMethod(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping", - "addLocaleEncodingMappingParameter", 2); + "addLocaleEncodingMapping", 2); digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/locale", 0); digester.addCallParam(prefix + "web-app/locale-encoding-mapping-list/locale-encoding-mapping/encoding", 1); @@ -331,10 +351,9 @@ public class WebRuleSet extends RuleSetBase { //ejb-local-ref digester.addObjectCreate(prefix + "web-app/ejb-local-ref", "org.apache.catalina.deploy.ContextLocalEjb"); - digester.addRule(prefix + "web-app/ejb-local-ref", - new SetNextNamingRule("addLocalEjb", - "org.apache.catalina.deploy.ContextLocalEjb")); - + digester.addSetNext(prefix + "web-app/ejb-local-ref", + "addEjbLocalRef", + "org.apache.catalina.deploy.ContextLocalEjb"); digester.addCallMethod(prefix + "web-app/ejb-local-ref/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/ejb-local-ref/ejb-link", @@ -352,10 +371,9 @@ public class WebRuleSet extends RuleSetBase { //ejb-ref digester.addObjectCreate(prefix + "web-app/ejb-ref", "org.apache.catalina.deploy.ContextEjb"); - digester.addRule(prefix + "web-app/ejb-ref", - new SetNextNamingRule("addEjb", - "org.apache.catalina.deploy.ContextEjb")); - + digester.addSetNext(prefix + "web-app/ejb-ref", + "addEjbRef", + "org.apache.catalina.deploy.ContextEjb"); digester.addCallMethod(prefix + "web-app/ejb-ref/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/ejb-ref/ejb-link", @@ -373,10 +391,9 @@ public class WebRuleSet extends RuleSetBase { //env-entry digester.addObjectCreate(prefix + "web-app/env-entry", "org.apache.catalina.deploy.ContextEnvironment"); - digester.addRule(prefix + "web-app/env-entry", - new SetNextNamingRule("addEnvironment", - "org.apache.catalina.deploy.ContextEnvironment")); - + digester.addSetNext(prefix + "web-app/env-entry", + "addEnvEntry", + "org.apache.catalina.deploy.ContextEnvironment"); digester.addCallMethod(prefix + "web-app/env-entry/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/env-entry/env-entry-name", @@ -390,10 +407,9 @@ public class WebRuleSet extends RuleSetBase { //resource-env-ref digester.addObjectCreate(prefix + "web-app/resource-env-ref", "org.apache.catalina.deploy.ContextResourceEnvRef"); - digester.addRule(prefix + "web-app/resource-env-ref", - new SetNextNamingRule("addResourceEnvRef", - "org.apache.catalina.deploy.ContextResourceEnvRef")); - + digester.addSetNext(prefix + "web-app/resource-env-ref", + "addResourceEnvRef", + "org.apache.catalina.deploy.ContextResourceEnvRef"); digester.addCallMethod(prefix + "web-app/resource-env-ref/resource-env-ref-name", "setName", 0); digester.addCallMethod(prefix + "web-app/resource-env-ref/resource-env-ref-type", @@ -406,7 +422,6 @@ public class WebRuleSet extends RuleSetBase { digester.addSetNext(prefix + "web-app/message-destination", "addMessageDestination", "org.apache.catalina.deploy.MessageDestination"); - digester.addCallMethod(prefix + "web-app/message-destination/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/message-destination/display-name", @@ -424,7 +439,6 @@ public class WebRuleSet extends RuleSetBase { digester.addSetNext(prefix + "web-app/message-destination-ref", "addMessageDestinationRef", "org.apache.catalina.deploy.MessageDestinationRef"); - digester.addCallMethod(prefix + "web-app/message-destination-ref/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/message-destination-ref/message-destination-link", @@ -441,10 +455,9 @@ public class WebRuleSet extends RuleSetBase { //resource-ref digester.addObjectCreate(prefix + "web-app/resource-ref", "org.apache.catalina.deploy.ContextResource"); - digester.addRule(prefix + "web-app/resource-ref", - new SetNextNamingRule("addResource", - "org.apache.catalina.deploy.ContextResource")); - + digester.addSetNext(prefix + "web-app/resource-ref", + "addResourceRef", + "org.apache.catalina.deploy.ContextResource"); digester.addCallMethod(prefix + "web-app/resource-ref/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/resource-ref/res-auth", @@ -460,10 +473,9 @@ public class WebRuleSet extends RuleSetBase { //service-ref digester.addObjectCreate(prefix + "web-app/service-ref", "org.apache.catalina.deploy.ContextService"); - digester.addRule(prefix + "web-app/service-ref", - new SetNextNamingRule("addService", - "org.apache.catalina.deploy.ContextService")); - + digester.addSetNext(prefix + "web-app/service-ref", + "addServiceRef", + "org.apache.catalina.deploy.ContextService"); digester.addCallMethod(prefix + "web-app/service-ref/description", "setDescription", 0); digester.addCallMethod(prefix + "web-app/service-ref/display-name", @@ -638,11 +650,11 @@ final class SetDistributableRule extends Rule { public void begin(String namespace, String name, Attributes attributes) throws Exception { - Context context = (Context) digester.peek(); - context.setDistributable(true); + WebXml webXml = (WebXml) digester.peek(); + webXml.setDistributable(true); if (digester.getLogger().isDebugEnabled()) { digester.getLogger().debug - (context.getClass().getName() + ".setDistributable( true)"); + (webXml.getClass().getName() + ".setDistributable(true)"); } } @@ -695,26 +707,24 @@ final class SetPublicIdRule extends Rule { * create the object that is to be added to the stack. */ -final class WrapperCreateRule extends Rule { +final class ServletDefCreateRule extends Rule { - public WrapperCreateRule() { + public ServletDefCreateRule() { } public void begin(String namespace, String name, Attributes attributes) throws Exception { - Context context = - (Context) digester.peek(digester.getCount() - 1); - Wrapper wrapper = context.createWrapper(); - digester.push(wrapper); + ServletDef servletDef = new ServletDef(); + digester.push(servletDef); if (digester.getLogger().isDebugEnabled()) - digester.getLogger().debug("new " + wrapper.getClass().getName()); + digester.getLogger().debug("new " + servletDef.getClass().getName()); } public void end(String namespace, String name) throws Exception { - Wrapper wrapper = (Wrapper) digester.pop(); + ServletDef servletDef = (ServletDef) digester.pop(); if (digester.getLogger().isDebugEnabled()) - digester.getLogger().debug("pop " + wrapper.getClass().getName()); + digester.getLogger().debug("pop " + servletDef.getClass().getName()); } } @@ -857,15 +867,15 @@ final class IgnoreAnnotationsRule extends Rule { public void begin(String namespace, String name, Attributes attributes) throws Exception { - Context context = (Context) digester.peek(digester.getCount() - 1); + WebXml webxml = (WebXml) digester.peek(digester.getCount() - 1); String value = attributes.getValue("metadata-complete"); if ("true".equals(value)) { - context.setIgnoreAnnotations(true); + webxml.setMetadataComplete(true); } if (digester.getLogger().isDebugEnabled()) { digester.getLogger().debug - (context.getClass().getName() + ".setIgnoreAnnotations( " + - context.getIgnoreAnnotations() + ")"); + (webxml.getClass().getName() + ".setMetadataComplete( " + + webxml.isMetadataComplete() + ")"); } } @@ -955,9 +965,9 @@ final class TaglibLocationRule extends Rule { @Override public void begin(String namespace, String name, Attributes attributes) throws Exception { - Context context = (Context) digester.peek(digester.getCount() - 1); + WebXml webXml = (WebXml) digester.peek(digester.getCount() - 1); // If we have a public ID, this is not a 2.4 or later webapp - boolean havePublicId = (context.getPublicId() != null); + boolean havePublicId = (webXml.getPublicId() != null); // havePublicId and isServlet24OrLater should be mutually exclusive if (havePublicId == isServlet24OrLater) { throw new IllegalArgumentException( diff --git a/java/org/apache/catalina/startup/WebXml.java b/java/org/apache/catalina/startup/WebXml.java index a1e67cee5..0b28568f2 100644 --- a/java/org/apache/catalina/startup/WebXml.java +++ b/java/org/apache/catalina/startup/WebXml.java @@ -18,11 +18,52 @@ package org.apache.catalina.startup; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; -public class WebXml extends WebXmlCommon { +import org.apache.catalina.Context; +import org.apache.catalina.Wrapper; +import org.apache.catalina.deploy.ContextEjb; +import org.apache.catalina.deploy.ContextEnvironment; +import org.apache.catalina.deploy.ContextLocalEjb; +import org.apache.catalina.deploy.ContextResource; +import org.apache.catalina.deploy.ContextResourceEnvRef; +import org.apache.catalina.deploy.ContextService; +import org.apache.catalina.deploy.ErrorPage; +import org.apache.catalina.deploy.FilterDef; +import org.apache.catalina.deploy.FilterMap; +import org.apache.catalina.deploy.JspPropertyGroup; +import org.apache.catalina.deploy.LoginConfig; +import org.apache.catalina.deploy.MessageDestination; +import org.apache.catalina.deploy.MessageDestinationRef; +import org.apache.catalina.deploy.SecurityConstraint; +import org.apache.catalina.deploy.SecurityRoleRef; +import org.apache.catalina.deploy.ServletDef; +import org.apache.tomcat.util.res.StringManager; + +/** + * Representation of common elements of web.xml and web-fragment.xml. Provides + * a repository for parsed data before the elements are merged. + * Validation is spread between multiple classes: + * The digester checks for structural correctness (eg single login-config) + * This class checks for invalid duplicates (eg filter/servlet names) + * StandardContext will check validity of values (eg URL formats etc) + */ +public class WebXml { + + protected static final String ORDER_OTHERS = + "org.apache.catalina.order.others"; + + protected static final StringManager sm = + StringManager.getManager(Constants.Package); + + private static org.apache.juli.logging.Log log= + org.apache.juli.logging.LogFactory.getLog(WebXml.class); + // web.xml only elements // Absolute Ordering private Set absoluteOrdering = new LinkedHashSet(); public void addAbsoluteOrdering(String name) { @@ -32,4 +73,464 @@ public class WebXml extends WebXmlCommon { absoluteOrdering.add(ORDER_OTHERS); } + // web-fragment.xml only elements + // Relative ordering + private Set after = new LinkedHashSet(); + public void addAfterOrdering(String name) { + after.add(name); + } + public void addAfterOrderingOthers() { + if (before.contains(ORDER_OTHERS)) { + throw new IllegalArgumentException(sm.getString( + "webXmlFragment.multipleOther")); + } + after.add(ORDER_OTHERS); + } + private Set before = new LinkedHashSet(); + public void addBeforeOrdering(String name) { + before.add(name); + } + public void addBeforeOrderingOthers() { + if (after.contains(ORDER_OTHERS)) { + throw new IllegalArgumentException(sm.getString( + "webXmlFragment.multipleOther")); + } + before.add(ORDER_OTHERS); + } + + // Common elements and attributes + + // Required attribute of web-app element + private String version = null; + public String getVersion() { return version; } + public void setVersion(String version) { this.version = version; } + + // Optional publicId attribute + private String publicId = null; + public String getPublicId() { return publicId; } + public void setPublicId(String publicId) { this.publicId = publicId; } + + // Optional metadata-complete attribute + private boolean metadataComplete = false; + public boolean isMetadataComplete() { return metadataComplete; } + public void setMetadataComplete(boolean metadataComplete) { + this.metadataComplete = metadataComplete; } + + // Optional name element + private String name = null; + public String getName() { return name; } + public void setName(String name) { + if (ORDER_OTHERS.equalsIgnoreCase(name)) { + // This is unusual. This name will be ignored. Log the fact. + log.warn(sm.getString("webXmlCommon.reservedName", name)); + } else { + this.name = name; + } + } + + // web-app elements + // TODO: Ignored elements: + // - description + // - icon + + // display-name - TODO should support multiple with language + private String displayName = null; + public String getDisplayName() { return displayName; } + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + // distributable + private boolean distributable = false; + public boolean isDistributable() { return distributable; } + public void setDistributable(boolean distributable) { + this.distributable = distributable; + } + + // context-param + // TODO: description (multiple with language) is ignored + private Map contextParams = new HashMap(); + public void addContextParam(String name, String value) { + contextParams.put(name, value); + } + public Map getContextParams() { return contextParams; } + + // filter + // TODO: Should support multiple description elements with language + // TODO: Should support multiple display-name elements with language + // TODO: Should support multiple icon elements + // TODO: Description for init-param is ignored + private Map filters = new HashMap(); + public void addFilter(FilterDef filter) { + if (filters.containsKey(filter.getFilterName())) { + // Filter names must be unique within a web(-fragment).xml + throw new IllegalArgumentException( + sm.getString("webXmlCommon.duplicateFilter")); + } + filters.put(filter.getFilterName(), filter); + } + public Map getFilters() { return filters; } + + // filter-mapping + private Set filterMaps = new HashSet(); + public void addFilterMapping(FilterMap filterMap) { + filterMaps.add(filterMap); + } + public Set getFilterMappings() { return filterMaps; } + + // listener + // TODO: description (multiple with language) is ignored + // TODO: display-name (multiple with language) is ignored + // TODO: icon (multiple) is ignored + private Set listeners = new LinkedHashSet(); + public void addListener(String className) { + listeners.add(className); + } + public Set getListeners() { return listeners; } + + // servlet + // TODO: description (multiple with language) is ignored + // TODO: display-name (multiple with language) is ignored + // TODO: icon (multiple) is ignored + // TODO: init-param/description (multiple with language) is ignored + // TODO: security-role-ref/description (multiple with language) is ignored + private Map servlets = new HashMap(); + public void addServlet(ServletDef servletDef) { + servlets.put(servletDef.getServletName(), servletDef); + } + public Map getServlets() { return servlets; } + + // servlet-mapping + private Map servletMappings = new HashMap(); + public void addServletMapping(String urlPattern, String servletName) { + servletMappings.put(urlPattern, servletName); + } + public Map getServletMappings() { return servletMappings; } + + // session-config/session-timeout + // Digester will check there is only one of these + private Integer sessionTimeout = null; + public void setSessionTimeout(String timeout) { + sessionTimeout = Integer.valueOf(timeout); + } + public Integer getSessionTimeout() { return sessionTimeout; } + + // mime-mapping + private Map mimeMappings = new HashMap(); + public void addMimeMapping(String extension, String mimeType) { + mimeMappings.put(extension, mimeType); + } + public Map getMimeMappings() { return mimeMappings; } + + // welcome-file-list + // When merging web.xml files it may be necessary for any new welcome files + // to completely replace the current set + private boolean replaceWelcomeFiles = false; + public void setReplaceWelcomeFiles(boolean replaceWelcomeFiles) { + this.replaceWelcomeFiles = replaceWelcomeFiles; + } + private Set welcomeFiles = new LinkedHashSet(); + public void addWelcomeFile(String welcomeFile) { + if (replaceWelcomeFiles) { + welcomeFiles.clear(); + replaceWelcomeFiles = false; + } + welcomeFiles.add(welcomeFile); + } + + // error-page + private Set errorPages = new HashSet(); + public void addErrorPage(ErrorPage errorPage) { + errorPages.add(errorPage); + } + public Set getErrorPages() { return errorPages; } + + // Digester will check there is only one jsp-config + // jsp-config/taglib or taglib (2.3 and earlier) + private Map taglibs = new HashMap(); + public void addTaglib(String uri, String location) { + taglibs.put(uri, location); + } + public Map getTaglibs() { return taglibs; } + + // jsp-config/jsp-property-group + private Set jspPropertyGroups = + new HashSet(); + public void addJspPropertyGroup(JspPropertyGroup propertyGroup) { + jspPropertyGroups.add(propertyGroup); + } + public Set getJspPropertyGroups() { + return jspPropertyGroups; + } + + // security-constraint + // TODO: Should support multiple display-name elements with language + // TODO: Should support multiple description elements with language + private Set securityConstraints = + new HashSet(); + public void addSecurityConstraint(SecurityConstraint securityConstraint) { + securityConstraints.add(securityConstraint); + } + public Set getSecurityConstraints() { + return securityConstraints; + } + + // login-config + // Digester will check there is only one of these + private LoginConfig loginConfig = null; + public void setLoginConfig(LoginConfig loginConfig) { + this.loginConfig = loginConfig; + } + public LoginConfig getLoginConfig() { return loginConfig; } + + // security-role + // TODO: description (multiple with language) is ignored + private Set securityRoles = new HashSet(); + public void addSecurityRole(String securityRole) { + securityRoles.add(securityRole); + } + public Set getSecurityRoles() { return securityRoles; } + + // env-entry + // TODO: Should support multiple description elements with language + private Map envEntries = + new HashMap(); + public void addEnvEntry(ContextEnvironment envEntry) { + if (envEntries.containsKey(envEntry.getName())) { + // env-entry names must be unique within a web(-fragment).xml + throw new IllegalArgumentException( + sm.getString("webXmlCommon.duplicateEnvEntry")); + } + envEntries.put(envEntry.getName(),envEntry); + } + public Map getEnvEntries() { return envEntries; } + + // ejb-ref + // TODO: Should support multiple description elements with language + private Set ejbRefs = new HashSet(); + public void addEjbRef(ContextEjb ejbRef) { ejbRefs.add(ejbRef); } + public Set getEjbRefs() { return ejbRefs; } + + // ejb-local-ref + // TODO: Should support multiple description elements with language + private Set ejbLocalRefs = new HashSet(); + public void addEjbLocalRef(ContextLocalEjb ejbLocalRef) { + ejbLocalRefs.add(ejbLocalRef); + } + public Set getEjbLocalRefs() { return ejbLocalRefs; } + + // service-ref + // TODO: Should support multiple description elements with language + // TODO: Should support multiple display-names elements with language + // TODO: Should support multiple icon elements ??? + private Set serviceRefs = new HashSet(); + public void addServiceRef(ContextService serviceRef) { + serviceRefs.add(serviceRef); + } + public Set getServiceRefs() { return serviceRefs; } + + // resource-ref + // TODO: Should support multiple description elements with language + private Map resourceRefs = + new HashMap(); + public void addResourceRef(ContextResource resourceRef) { + if (resourceRefs.containsKey(resourceRef.getName())) { + // resource-ref names must be unique within a web(-fragment).xml + throw new IllegalArgumentException( + sm.getString("webXmlCommon.duplicateResourceRef")); + } + resourceRefs.put(resourceRef.getName(), resourceRef); + } + public Map getResourceRefs() { + return resourceRefs; + } + + // resource-env-ref + // TODO: Should support multiple description elements with language + private Map resourceEnvRefs = + new HashMap(); + public void addResourceEnvRef(ContextResourceEnvRef resourceEnvRef) { + if (resourceEnvRefs.containsKey(resourceEnvRef.getName())) { + // resource-env-ref names must be unique within a web(-fragment).xml + throw new IllegalArgumentException( + sm.getString("webXmlCommon.duplicateResourceEnvRef")); + } + resourceEnvRefs.put(resourceEnvRef.getName(), resourceEnvRef); + } + public Map getResourceEnvRefs() { + return resourceEnvRefs; + } + + // message-destination-ref + // TODO: Should support multiple description elements with language + private Map messageDestinationRefs = + new HashMap(); + public void addMessageDestinationRef( + MessageDestinationRef messageDestinationRef) { + if (messageDestinationRefs.containsKey( + messageDestinationRef.getName())) { + // message-destination-ref names must be unique within a + // web(-fragment).xml + throw new IllegalArgumentException(sm.getString( + "webXmlCommon.duplicateMessageDestinationRef")); + } + messageDestinationRefs.put(messageDestinationRef.getName(), + messageDestinationRef); + } + public Map getMessageDestinationRefs() { + return messageDestinationRefs; + } + + // message-destination + // TODO: Should support multiple description elements with language + // TODO: Should support multiple display-names elements with language + // TODO: Should support multiple icon elements ??? + private Map messageDestinations = + new HashMap(); + public void addMessageDestination( + MessageDestination messageDestination) { + if (messageDestinations.containsKey( + messageDestination.getName())) { + // message-destination names must be unique within a + // web(-fragment).xml + throw new IllegalArgumentException( + sm.getString("webXmlCommon.duplicateMessageDestination")); + } + messageDestinations.put(messageDestination.getName(), + messageDestination); + } + public Map getMessageDestinations() { + return messageDestinations; + } + + // locale-encoging-mapping-list + private Map localeEncodingMappings = + new HashMap(); + public void addLocaleEncodingMapping(String locale, String encoding) { + localeEncodingMappings.put(locale, encoding); + } + public Map getLocalEncodingMappings() { + return localeEncodingMappings; + } + + /** + * Configure a {@link Context} using the stored web.xml representation. + * + * @param context The context to be configured + */ + public void configureContext(Context context) { + // As far as possible, process in alphabetical order so it is easy to + // check everything is present + // Some validation depends on correct public ID + context.setPublicId(publicId); + + // Everything else in order + for (String contextParam : contextParams.keySet()) { + context.addParameter(contextParam, contextParams.get(contextParam)); + } + context.setDisplayName(displayName); + context.setDistributable(distributable); + for (ContextLocalEjb ejbLocalRef : ejbLocalRefs) { + context.getNamingResources().addLocalEjb(ejbLocalRef); + } + for (ContextEjb ejbRef : ejbRefs) { + context.getNamingResources().addEjb(ejbRef); + } + for (ContextEnvironment environment : envEntries.values()) { + context.getNamingResources().addEnvironment(environment); + } + for (ErrorPage errorPage : errorPages) { + context.addErrorPage(errorPage); + } + for (FilterDef filter : filters.values()) { + context.addFilterDef(filter); + } + for (FilterMap filterMap : filterMaps) { + context.addFilterMap(filterMap); + } + // jsp-property-group needs to be after servlet configuration + for (String listener : listeners) { + context.addApplicationListener(listener); + } + for (String locale : localeEncodingMappings.keySet()) { + context.addLocaleEncodingMappingParameter(locale, + localeEncodingMappings.get(locale)); + } + // Prevents IAE + if (loginConfig != null) { + context.setLoginConfig(loginConfig); + } + for (MessageDestinationRef mdr : messageDestinationRefs.values()) { + context.getNamingResources().addMessageDestinationRef(mdr); + } + + // messageDestinations were ignored in Tomcat 6, so ignore here + + // TODO SERVLET3 - This needs to be more fine-grained. Whether or not to + // process annotations on destroy() will depend on where + // the filter/servlet was loaded from. Joy. + context.setIgnoreAnnotations(metadataComplete); + for (String extension : mimeMappings.keySet()) { + context.addMimeMapping(extension, mimeMappings.get(extension)); + } + // Name is just used for ordering + for (ContextResourceEnvRef resource : resourceEnvRefs.values()) { + context.getNamingResources().addResourceEnvRef(resource); + } + for (ContextResource resource : resourceRefs.values()) { + context.getNamingResources().addResource(resource); + } + for (SecurityConstraint constraint : securityConstraints) { + context.addConstraint(constraint); + } + for (String role : securityRoles) { + context.addSecurityRole(role); + } + for (ContextService service : serviceRefs) { + context.getNamingResources().addService(service); + } + for (ServletDef servlet : servlets.values()) { + Wrapper wrapper = context.createWrapper(); + // Description is ignored + // Display name is ignored + // Icons are ignored + wrapper.setJspFile(servlet.getJspFile()); + if (servlet.getLoadOnStartup() != null) { + wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue()); + } + wrapper.setName(servlet.getServletName()); + Map params = servlet.getParameterMap(); + for (String param : params.keySet()) { + wrapper.addInitParameter(param, params.get(param)); + } + wrapper.setRunAs(servlet.getRunAs()); + Set roleRefs = servlet.getSecurityRoleRefs(); + for (SecurityRoleRef roleRef : roleRefs) { + wrapper.addSecurityReference( + roleRef.getName(), roleRef.getLink()); + } + wrapper.setServletClass(servlet.getServletClass()); + context.addChild(wrapper); + } + for (String pattern : servletMappings.keySet()) { + context.addServletMapping(pattern, servletMappings.get(pattern)); + } + if (sessionTimeout != null) { + context.setSessionTimeout(sessionTimeout.intValue()); + } + for (String uri : taglibs.keySet()) { + context.addTaglib(uri, taglibs.get(uri)); + } + + // Context doesn't use version directly + + for (String welcomeFile : welcomeFiles) { + context.addWelcomeFile(welcomeFile); + } + + // Do this last as it depends on servlets + for (JspPropertyGroup jspPropertyGroup : jspPropertyGroups) { + context.addJspMapping(jspPropertyGroup.getUrlPattern()); + } + } } diff --git a/java/org/apache/catalina/startup/WebXmlCommon.java b/java/org/apache/catalina/startup/WebXmlCommon.java deleted file mode 100644 index 05570e468..000000000 --- a/java/org/apache/catalina/startup/WebXmlCommon.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.catalina.startup; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.catalina.Wrapper; -import org.apache.catalina.deploy.ContextEjb; -import org.apache.catalina.deploy.ContextEnvironment; -import org.apache.catalina.deploy.ContextLocalEjb; -import org.apache.catalina.deploy.ContextResource; -import org.apache.catalina.deploy.ContextResourceEnvRef; -import org.apache.catalina.deploy.ContextService; -import org.apache.catalina.deploy.ErrorPage; -import org.apache.catalina.deploy.FilterDef; -import org.apache.catalina.deploy.FilterMap; -import org.apache.catalina.deploy.LoginConfig; -import org.apache.catalina.deploy.MessageDestination; -import org.apache.catalina.deploy.MessageDestinationRef; -import org.apache.catalina.deploy.SecurityConstraint; -import org.apache.jasper.compiler.JspConfig; -import org.apache.tomcat.util.res.StringManager; - -/** - * Representation of common elements of web.xml and web-fragment.xml. Provides - * a repository for parsed data before the elements are merged. - * Validation is spread between multiple classes: - * The digester checks for structural correctness (eg single login-config) - * This class checks for invalid duplicates (eg filter/servlet names) - * StandardContext will check validity of values (eg URL formats etc) - */ -public abstract class WebXmlCommon { - - protected static final String ORDER_OTHERS = - "org.apache.catalina.order.others"; - - protected static final StringManager sm = - StringManager.getManager(Constants.Package); - - private static org.apache.juli.logging.Log log= - org.apache.juli.logging.LogFactory.getLog(WebXmlCommon.class); - - // Required attribute of web-app element - private String version = null; - public String getVersion() { return version; } - public void setVersion(String version) { this.version = version; } - - // Optional metadata-complete attribute - private boolean metadataComplete = false; - public boolean getMetadataComplete() { return metadataComplete; } - public void setMetadataComplete(boolean metadataComplete) { - this.metadataComplete = metadataComplete; } - - // Optional name element - private String name = null; - public String getName() { return name; } - public void setName(String name) { - if (ORDER_OTHERS.equalsIgnoreCase(name)) { - // This is unusual. This name will be ignored. Log the fact. - log.warn(sm.getString("webXmlCommon.reservedName", name)); - } else { - this.name = name; - } - } - - // web-app elements - // TODO: Ignored elements: - // - description - // - icon - - // display-name - TODO should support multiple with language - private String displayName = null; - public String getDisplayName() { return displayName; } - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - // distributable - private boolean distributable = false; - public boolean getDistributable() { return distributable; } - public void setDistributable(boolean distributable) { - this.distributable = distributable; - } - - // context-param - // TODO: description (multiple with language) is ignored - private Map contextParams = new HashMap(); - public void addContextParam(String name, String value) { - contextParams.put(name, value); - } - public Map getContextParams() { return contextParams; } - - // filter - // TODO: Should support multiple description elements with language - // TODO: Should support multiple display-name elements with language - // TODO: Should support multiple icon elements - // TODO: Description for init-param is ignored - private Map filters = new HashMap(); - public void addFilter(FilterDef filter) { - if (filters.containsKey(filter.getFilterName())) { - // Filter names must be unique within a web(-fragment).xml - throw new IllegalArgumentException( - sm.getString("webXmlCommon.duplicateFilter")); - } - filters.put(filter.getFilterName(), filter); - } - public Map getFilters() { return filters; } - - // filter-mapping - private Map filterMaps = new HashMap(); - public void addFilterMapping(FilterMap filterMap) { - filterMaps.put(filterMap.getFilterName(), filterMap); - } - public Map getFilterMappings() { return filterMaps; } - - // listener - // TODO: description (multiple with language) is ignored - // TODO: display-name (multiple with language) is ignored - // TODO: icon (multiple) is ignored - private Set listeners = new LinkedHashSet(); - public void addListener(String className) { - listeners.add(className); - } - public Set getListeners() { return listeners; } - - // servlet - // TODO: description (multiple with language) is ignored - // TODO: display-name (multiple with language) is ignored - // TODO: icon (multiple) is ignored - // TODO: init-param/description (multiple with language) is ignored - // TODO: security-role-ref/description (multiple with language) is ignored - private Map servlets = new HashMap(); - public void addServlet(Wrapper wrapper) { - servlets.put(wrapper.getName(), wrapper); - } - public Map getServlets() { return servlets; } - - // servlet-mapping - private Map servletMappings = new HashMap(); - public void addServletMapping(String servletName, String urlPattern) { - servletMappings.put(servletName, urlPattern); - } - public Map getServletMappings() { return servletMappings; } - - // session-config/session-timeout - // Digester will check there is only one of these - private Integer sessionTimeout = null; - public void setSessionTimeout(String timeout) { - sessionTimeout = Integer.valueOf(timeout); - } - public Integer getSessionTimeout() { return sessionTimeout; } - - // mime-mapping - private Map mimeMappings = new HashMap(); - public void addMimeMapping(String extension, String mimeType) { - mimeMappings.put(extension, mimeType); - } - public Map getMimeMappings() { return mimeMappings; } - - // welcome-file-list - private Set welcomeFiles = new LinkedHashSet(); - public void addWelcomeFile(String welcomeFile) { - welcomeFiles.add(welcomeFile); - } - - // error-page - private Set errorPages = new HashSet(); - public void addErrorPage(ErrorPage errorPage) { - errorPages.add(errorPage); - } - public Set getErrorPages() { return errorPages; } - - // Digester will check there is only one jsp-config - // jsp-config/taglib or taglib (2.3 and earlier) - private Map taglibs = new HashMap(); - public void addTaglib(String uri, String location) { - taglibs.put(uri, location); - } - public Map getTaglibs() { return taglibs; } - - // jsp-config/jsp-property-group - private Set jspPropertyGroups = - new HashSet(); - public void addJspPropertyGroup(JspConfig.JspPropertyGroup propertyGroup) { - jspPropertyGroups.add(propertyGroup); - } - public Set getJspPropertyGroups() { - return jspPropertyGroups; - } - - // security-constraint - // TODO: Should support multiple display-name elements with language - // TODO: Should support multiple description elements with language - private Set securityConstraints = - new HashSet(); - public void addSecurityConstraint(SecurityConstraint securityConstraint) { - securityConstraints.add(securityConstraint); - } - public Set getSecurityConstraints() { - return securityConstraints; - } - - // login-config - // Digester will check there is only one of these - private LoginConfig loginConfig = null; - public void setLoginConfig(LoginConfig loginConfig) { - this.loginConfig = loginConfig; - } - public LoginConfig getLoginConfig() { return loginConfig; } - - // security-role - // TODO: description (multiple with language) is ignored - private Set securityRoles = new HashSet(); - public void addSecurityRole(String securityRole) { - securityRoles.add(securityRole); - } - public Set getSecurityRoles() { return securityRoles; } - - // env-entry - // TODO: Should support multiple description elements with language - private Map envEntries = - new HashMap(); - public void addEnvEntry(ContextEnvironment envEntry) { - if (envEntries.containsKey(envEntry.getName())) { - // env-entry names must be unique within a web(-fragment).xml - throw new IllegalArgumentException( - sm.getString("webXmlCommon.duplicateEnvEntry")); - } - envEntries.put(envEntry.getName(),envEntry); - } - public Map getEnvEntries() { return envEntries; } - - // ejb-ref - // TODO: Should support multiple description elements with language - private Set ejbRefs = new HashSet(); - public void addEjbRef(ContextEjb ejbRef) { ejbRefs.add(ejbRef); } - public Set getEjbRefs() { return ejbRefs; } - - // ejb-local-ref - // TODO: Should support multiple description elements with language - private Set ejbLocalRefs = new HashSet(); - public void addEjbLocalRef(ContextLocalEjb ejbLocalRef) { - ejbLocalRefs.add(ejbLocalRef); - } - public Set getEjbLocalRefs() { return ejbLocalRefs; } - - // service-ref - // TODO: Should support multiple description elements with language - // TODO: Should support multiple display-names elements with language - // TODO: Should support multiple icon elements ??? - private Set serviceRefs = new HashSet(); - public void addServiceRef(ContextService serviceRef) { - serviceRefs.add(serviceRef); - } - public Set getServiceRefs() { return serviceRefs; } - - // resource-ref - // TODO: Should support multiple description elements with language - private Map resourceRefs = - new HashMap(); - public void addResourceRef(ContextResource resourceRef) { - if (resourceRefs.containsKey(resourceRef.getName())) { - // resource-ref names must be unique within a web(-fragment).xml - throw new IllegalArgumentException( - sm.getString("webXmlCommon.duplicateResourceRef")); - } - resourceRefs.put(resourceRef.getName(), resourceRef); - } - public Map getResourceRefs() { - return resourceRefs; - } - - // resource-env-ref - // TODO: Should support multiple description elements with language - private Map resourceEnvRefs = - new HashMap(); - public void addResourceEnvRef(ContextResourceEnvRef resourceEnvRef) { - if (resourceEnvRefs.containsKey(resourceEnvRef.getName())) { - // resource-env-ref names must be unique within a web(-fragment).xml - throw new IllegalArgumentException( - sm.getString("webXmlCommon.duplicateResourceEnvRef")); - } - resourceEnvRefs.put(resourceEnvRef.getName(), resourceEnvRef); - } - public Map getResourceEnvRefs() { - return resourceEnvRefs; - } - - // message-destination-ref - // TODO: Should support multiple description elements with language - private Map messageDestinationRefs = - new HashMap(); - public void addMessageDestinationRef( - MessageDestinationRef messageDestinationRef) { - if (messageDestinationRefs.containsKey( - messageDestinationRef.getName())) { - // message-destination-ref names must be unique within a - // web(-fragment).xml - throw new IllegalArgumentException(sm.getString( - "webXmlCommon.duplicateMessageDestinationRef")); - } - messageDestinationRefs.put(messageDestinationRef.getName(), - messageDestinationRef); - } - public Map getMessageDestinationRefs() { - return messageDestinationRefs; - } - - // message-destination - // TODO: Should support multiple description elements with language - // TODO: Should support multiple display-names elements with language - // TODO: Should support multiple icon elements ??? - private Map messageDestinations = - new HashMap(); - public void addMessageDestination( - MessageDestination messageDestination) { - if (messageDestinations.containsKey( - messageDestination.getName())) { - // message-destination names must be unique within a - // web(-fragment).xml - throw new IllegalArgumentException( - sm.getString("webXmlCommon.duplicateMessageDestination")); - } - messageDestinations.put(messageDestination.getName(), - messageDestination); - } - public Map getMessageDestinations() { - return messageDestinations; - } - - // locale-encoging-mapping-list - private Map localeEncodingMappings = - new HashMap(); - public void addLocaleEncodingMapping(String locale, String encoding) { - localeEncodingMappings.put(locale, encoding); - } - public Map getLocalEncodingMappings() { - return localeEncodingMappings; - } -} diff --git a/java/org/apache/catalina/startup/WebXmlFragment.java b/java/org/apache/catalina/startup/WebXmlFragment.java deleted file mode 100644 index 32f044671..000000000 --- a/java/org/apache/catalina/startup/WebXmlFragment.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.catalina.startup; - -import java.util.LinkedHashSet; -import java.util.Set; - -public class WebXmlFragment extends WebXmlCommon { - - // Relative ordering - private Set after = new LinkedHashSet(); - public void addAfterOrdering(String name) { - after.add(name); - } - public void addAfterOrderingOthers() { - if (before.contains(ORDER_OTHERS)) { - throw new IllegalArgumentException(sm.getString( - "webXmlFragment.multipleOther")); - } - after.add(ORDER_OTHERS); - } - private Set before = new LinkedHashSet(); - public void addBeforeOrdering(String name) { - before.add(name); - } - public void addBeforeOrderingOthers() { - if (after.contains(ORDER_OTHERS)) { - throw new IllegalArgumentException(sm.getString( - "webXmlFragment.multipleOther")); - } - before.add(ORDER_OTHERS); - } -} -- 2.11.0