You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2009/12/29 13:50:55 UTC

svn commit: r894372 - in /tomcat/trunk: java/org/apache/catalina/ java/org/apache/catalina/core/ java/org/apache/catalina/startup/ java/org/apache/tomcat/util/scan/ webapps/docs/config/

Author: markt
Date: Tue Dec 29 12:50:54 2009
New Revision: 894372

URL: http://svn.apache.org/viewvc?rev=894372&view=rev
Log:
Add configuration option that allows the effective web.xml to be logged on context start.
Expose the effective web.xml through a context attribute so other components (eg Jasper) can use it.

Modified:
    tomcat/trunk/java/org/apache/catalina/Context.java
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/WebXml.java
    tomcat/trunk/java/org/apache/tomcat/util/scan/Constants.java
    tomcat/trunk/webapps/docs/config/context.xml

Modified: tomcat/trunk/java/org/apache/catalina/Context.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Context.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Context.java Tue Dec 29 12:50:54 2009
@@ -1101,5 +1101,16 @@
      * <code>null</code> if none is used.
      */
     public Authenticator getAuthenticator();
+    
+    /**
+     * Set whether or not the effective web.xml for this context should be
+     * logged on context start.
+     */
+    public void setLogEffectiveWebXml(boolean logEffectiveWebXml);
+    
+    /**
+     * Should the effective web.xml for this context be logged on context start?
+     */
+    public boolean getLogEffectiveWebXml();
 }
 

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Tue Dec 29 12:50:54 2009
@@ -758,8 +758,20 @@
      */
     private boolean clearReferencesStopThreads = false;
 
+    /**
+     * Should the effective web.xml be logged when the context starts?
+     */
+    private boolean logEffectiveWebXml = false;
+
     // ----------------------------------------------------- Context Properties
 
+    public void setLogEffectiveWebXml(boolean logEffectiveWebXml) {
+        this.logEffectiveWebXml = logEffectiveWebXml;
+    }
+    
+    public boolean getLogEffectiveWebXml() {
+        return logEffectiveWebXml;
+    }
 
     public Authenticator getAuthenticator() {
         if (this instanceof Authenticator)

Modified: tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Tue Dec 29 12:50:54 2009
@@ -32,7 +32,6 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -1224,6 +1223,15 @@
             // Apply merged web.xml to Context
             webXml.configureContext(context);
         }
+        // Make the merged web.xml available to other components, specifically
+        // Jasper, to save those components from having to re-generate it.
+        String mergedWebXml = webXml.toXml();
+        context.getServletContext().setAttribute(
+               org.apache.tomcat.util.scan.Constants.MERGED_WEB_XML,
+                mergedWebXml);
+        if (context.getLogEffectiveWebXml()) {
+            log.info("web.xml:\n" + mergedWebXml);
+        }
     }
 
     

Modified: tomcat/trunk/java/org/apache/catalina/startup/WebXml.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebXml.java?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebXml.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebXml.java Tue Dec 29 12:50:54 2009
@@ -21,6 +21,7 @@
 import java.net.URL;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -34,6 +35,7 @@
 import org.apache.catalina.Wrapper;
 import org.apache.catalina.deploy.ContextEjb;
 import org.apache.catalina.deploy.ContextEnvironment;
+import org.apache.catalina.deploy.ContextHandler;
 import org.apache.catalina.deploy.ContextLocalEjb;
 import org.apache.catalina.deploy.ContextResource;
 import org.apache.catalina.deploy.ContextResourceEnvRef;
@@ -41,12 +43,14 @@
 import org.apache.catalina.deploy.ErrorPage;
 import org.apache.catalina.deploy.FilterDef;
 import org.apache.catalina.deploy.FilterMap;
+import org.apache.catalina.deploy.InjectionTarget;
 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.MultipartDef;
 import org.apache.catalina.deploy.ResourceBase;
+import org.apache.catalina.deploy.SecurityCollection;
 import org.apache.catalina.deploy.SecurityConstraint;
 import org.apache.catalina.deploy.SecurityRoleRef;
 import org.apache.catalina.deploy.ServletDef;
@@ -65,7 +69,7 @@
     protected static final String ORDER_OTHERS =
         "org.apache.catalina.order.others";
     
-    protected static final StringManager sm =
+    private static final StringManager sm =
         StringManager.getManager(Constants.Package);
 
     private static final org.apache.juli.logging.Log log=
@@ -461,8 +465,563 @@
         return buf.toString();
     }
     
+    private static final String INDENT2 = "  ";
+    private static final String INDENT4 = "    ";
+    private static final String INDENT6 = "      ";
     
     /**
+     * Generate a web.xml in String form that matches the representation stored
+     * in this object.
+     * 
+     * @return The complete contents of web.xml as a String
+     */
+    public String toXml() {
+        StringBuilder sb = new StringBuilder(2048);
+        
+        // TODO - Various, icon, description etc elements are skipped - mainly
+        //        because they are ignored when web.xml is parsed - see above
+
+        // Declaration
+        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        
+        // Root element
+        sb.append("<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n");
+        sb.append("         xmlns:xsi=");
+        sb.append("\"http://www.w3.org/2001/XMLSchema-instance\"\n");
+        sb.append("         xsi:schemaLocation=");
+        sb.append("\"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"\n");
+        sb.append("         version=\"3.0\"\n");
+        sb.append("         metadata-complete=\"true\">\n\n");
+
+        appendElement(sb, INDENT2, "display-name", displayName);
+        
+        if (isDistributable()) {
+            sb.append("  <distributable/>\n\n");
+        }
+        
+        for (Map.Entry<String, String> entry : contextParams.entrySet()) {
+            sb.append("  <context-param>\n");
+            appendElement(sb, INDENT4, "param-name", entry.getKey());
+            appendElement(sb, INDENT4, "param-valuee", entry.getValue());
+            sb.append("  </context-param>\n");
+        }
+        sb.append('\n');
+        
+        for (Map.Entry<String, FilterDef> entry : filters.entrySet()) {
+            FilterDef filterDef = entry.getValue();
+            sb.append("  <filter>\n");
+            appendElement(sb, INDENT4, "description",
+                    filterDef.getDescription());
+            appendElement(sb, INDENT4, "display-name",
+                    filterDef.getDisplayName());
+            appendElement(sb, INDENT4, "filter-name",
+                    filterDef.getFilterName());
+            appendElement(sb, INDENT4, "filter-class",
+                    filterDef.getFilterClass());
+            appendElement(sb, INDENT4, "async-supported",
+                    filterDef.getAsyncSupported());
+            for (Map.Entry<String, String> param :
+                    filterDef.getParameterMap().entrySet()) {
+                sb.append("    <init-param>\n");
+                appendElement(sb, INDENT6, "param-name", param.getKey());
+                appendElement(sb, INDENT6, "param-value", param.getValue());
+                sb.append("    </init-param>\n");
+            }
+            sb.append("  </filter>\n");
+        }
+        sb.append('\n');
+
+        for (FilterMap filterMap : filterMaps) {
+            sb.append("  <filter-mapping>\n");
+            appendElement(sb, INDENT4, "filter-name",
+                    filterMap.getFilterName());
+            if (filterMap.getMatchAllServletNames()) {
+                sb.append("    <servlet-name>*</servlet-name>\n");
+            } else {
+                for (String servletName : filterMap.getServletNames()) {
+                    appendElement(sb, INDENT4, "servlet-name", servletName);
+                }
+            }
+            if (filterMap.getMatchAllUrlPatterns()) {
+                sb.append("    <url-pattern>*</url-pattern>\n");
+            } else {
+                for (String urlPattern : filterMap.getURLPatterns()) {
+                    appendElement(sb, INDENT4, "url-pattern", urlPattern);
+                }
+            }
+            for (String dispatcher : filterMap.getDispatcherNames()) {
+                appendElement(sb, INDENT4, "dispatcher", dispatcher);
+            }
+            sb.append("  </filter-mapping>\n");
+        }
+        sb.append('\n');
+
+        for (String listener : listeners) {
+            sb.append("  <listener>\n");
+            appendElement(sb, INDENT4, "listener-class", listener);
+            sb.append("  </listener>\n");
+        }
+        sb.append('\n');
+
+        for (Map.Entry<String, ServletDef> entry : servlets.entrySet()) {
+            ServletDef servletDef = entry.getValue();
+            sb.append("  <servlet>\n");
+            appendElement(sb, INDENT4, "description",
+                    servletDef.getDescription());
+            appendElement(sb, INDENT4, "display-name",
+                    servletDef.getDisplayName());
+            appendElement(sb, INDENT4, "servlet-name", entry.getKey());
+            appendElement(sb, INDENT4, "servlet-class",
+                    servletDef.getServletClass());
+            appendElement(sb, INDENT4, "jsp-file", servletDef.getJspFile());
+            for (Map.Entry<String, String> param :
+                    servletDef.getParameterMap().entrySet()) {
+                sb.append("    <init-param>\n");
+                appendElement(sb, INDENT6, "param-name", param.getKey());
+                appendElement(sb, INDENT6, "param-value", param.getValue());
+                sb.append("    </init-param>\n");
+            }
+            appendElement(sb, INDENT4, "load-on-startup",
+                    servletDef.getLoadOnStartup());
+            // TODO enabled
+            appendElement(sb, INDENT4, "async-supported",
+                    servletDef.getAsyncSupported());
+            sb.append("    <run-as>\n");
+            appendElement(sb, INDENT6, "role-name", servletDef.getRunAs());
+            sb.append("    </run-as>\n");
+            for (SecurityRoleRef roleRef : servletDef.getSecurityRoleRefs()) {
+                sb.append("    <security-role-ref>\n");
+                appendElement(sb, INDENT6, "role-name", roleRef.getName());
+                appendElement(sb, INDENT6, "role-link", roleRef.getLink());
+                sb.append("    </security-role-ref>\n");
+            }
+            MultipartDef multipartDef = servletDef.getMultipartDef();
+            if (multipartDef != null) {
+                sb.append("    <multipart-config>\n");
+                appendElement(sb, INDENT6, "location",
+                        multipartDef.getLocation());
+                appendElement(sb, INDENT6, "max-file-size",
+                        multipartDef.getMaxFileSize());
+                appendElement(sb, INDENT6, "max-request-size",
+                        multipartDef.getMaxRequestSize());
+                appendElement(sb, INDENT6, "file-size-threshold",
+                        multipartDef.getFileSizeThreshold());
+                sb.append("    </multipart-config>\n");
+            }
+            sb.append("  </servlet>\n");
+        }
+        sb.append('\n');
+
+        for (Map.Entry<String, String> entry : servletMappings.entrySet()) {
+            sb.append("  <servlet-mapping>\n");
+            appendElement(sb, INDENT4, "servlet-name", entry.getValue());
+            appendElement(sb, INDENT4, "url-pattern", entry.getKey());
+            sb.append("  </servlet-mapping>\n");
+        }
+        sb.append('\n');
+        
+        if (sessionTimeout != null) {
+            sb.append("  <session-config>\n");
+            appendElement(sb, INDENT4, "session-timeout",
+                    sessionTimeout.toString());
+            // TODO cookie-config
+            // TODO tracking-mode
+            sb.append("  </session-config>\n\n");
+        }
+        
+        for (Map.Entry<String, String> entry : mimeMappings.entrySet()) {
+            sb.append("  <mime-mapping>\n");
+            appendElement(sb, INDENT4, "extension", entry.getKey());
+            appendElement(sb, INDENT4, "mime-type", entry.getValue());
+            sb.append("  </mime-mapping>\n");
+        }
+        sb.append('\n');
+        
+        if (welcomeFiles.size() > 0) {
+            sb.append("  <welcome-file-list>\n");
+            for (String welcomeFile : welcomeFiles) {
+                appendElement(sb, INDENT4, "welcome-file", welcomeFile);
+            }
+            sb.append("  </welcome-file-list>\n\n");
+        }
+        
+        for (ErrorPage errorPage : errorPages.values()) {
+            sb.append("  <error-page>\n");
+            if (errorPage.getExceptionType() == null) {
+                appendElement(sb, INDENT4, "error-code",
+                        Integer.toString(errorPage.getErrorCode()));
+            } else {
+                appendElement(sb, INDENT4, "exception-type",
+                        errorPage.getExceptionType());
+            }
+            appendElement(sb, INDENT4, "location", errorPage.getLocation());
+            sb.append("  </error-page>\n");
+        }
+        sb.append('\n');
+
+        if (taglibs.size() > 0 || jspPropertyGroups.size() > 0) {
+            sb.append("  <jsp-config>\n");
+            for (Map.Entry<String, String> entry : taglibs.entrySet()) {
+                sb.append("    <taglib>\n");
+                appendElement(sb, INDENT6, "taglib-uri", entry.getKey());
+                appendElement(sb, INDENT6, "taglib-location", entry.getValue());
+                sb.append("    </taglib>\n");
+            }
+            for (JspPropertyGroup jpg : jspPropertyGroups) {
+                sb.append("    <jsp-property-group>\n");
+                appendElement(sb, INDENT6, "url-pattern", jpg.getUrlPattern());
+                appendElement(sb, INDENT6, "el-ignored", jpg.getElIgnored());
+                appendElement(sb, INDENT6, "scripting-invalid",
+                        jpg.getScriptingInvalid());
+                appendElement(sb, INDENT6, "page-encoding",
+                        jpg.getPageEncoding());
+                for (String prelude : jpg.getIncludePreludes()) {
+                    appendElement(sb, INDENT6, "include-prelude", prelude);
+                }
+                for (String coda : jpg.getIncludeCodas()) {
+                    appendElement(sb, INDENT6, "include-coda", coda);
+                }
+                appendElement(sb, INDENT6, "is-xml", jpg.getIsXml());
+                appendElement(sb, INDENT6, "deferred-syntax-allowed-as-literal",
+                        jpg.getDeferredSyntax());
+                appendElement(sb, INDENT6, "trim-directive-whitespaces",
+                        jpg.getTrimWhitespace());
+                appendElement(sb, INDENT6, "default-content-type",
+                        jpg.getDefaultContentType());
+                appendElement(sb, INDENT6, "buffer", jpg.getBuffer());
+                appendElement(sb, INDENT6, "error-on-undeclared-namespace",
+                        jpg.getErrorOnUndeclaredNamespace());
+                sb.append("    </jsp-property-group>\n");
+            }
+            sb.append("  </jsp-config>\n\n");
+        }
+        
+        for (SecurityConstraint constraint : securityConstraints) {
+            sb.append("  <security-constraint>\n");
+            appendElement(sb, INDENT4, "display-name",
+                    constraint.getDisplayName());
+            for (SecurityCollection collection : constraint.findCollections()) {
+                sb.append("    <web-resource-collection>\n");
+                appendElement(sb, INDENT6, "web-resource-name",
+                        collection.getName());
+                appendElement(sb, INDENT6, "description",
+                        collection.getDescription());
+                for (String urlPattern : collection.findPatterns()) {
+                    appendElement(sb, INDENT6, "url-pattern", urlPattern);
+                }
+                for (String method : collection.findMethods()) {
+                    appendElement(sb, INDENT6, "http-method", method);
+                }
+                sb.append("    </web-resource-collection>\n");
+            }
+            if (constraint.findAuthRoles().length > 0) {
+                sb.append("    <auth-constraint>\n");
+                for (String role : constraint.findAuthRoles()) {
+                    appendElement(sb, INDENT6, "role-name", role);
+                }
+                sb.append("    </auth-constraint>\n");
+            }
+            if (constraint.getUserConstraint() != null) {
+                sb.append("    <user-data-constraint>\n");
+                appendElement(sb, INDENT6, "transport-guarantee",
+                        constraint.getUserConstraint());
+                sb.append("    </user-data-constraint>\n");
+            }
+            sb.append("  </security-constraint>\n");
+        }
+        sb.append('\n');
+
+        if (loginConfig != null) {
+            sb.append("  <login-config>\n");
+            appendElement(sb, INDENT4, "auth-method",
+                    loginConfig.getAuthMethod());
+            appendElement(sb,INDENT4, "realm-name",
+                    loginConfig.getRealmName());
+            if (loginConfig.getErrorPage() != null ||
+                        loginConfig.getLoginPage() != null) {
+                sb.append("    <form-login-config>\n");
+                appendElement(sb, INDENT6, "form-login-page",
+                        loginConfig.getLoginPage());
+                appendElement(sb, INDENT6, "form-error-page",
+                        loginConfig.getErrorPage());
+                sb.append("    </form-login-config>\n");
+            }
+            sb.append("  </login-config>\n\n");
+        }
+        
+        for (String roleName : securityRoles) {
+            sb.append("  <security-role>\n");
+            appendElement(sb, INDENT4, "role-name", roleName);
+            sb.append("  </security-role>\n");
+        }
+        
+        for (ContextEnvironment envEntry : envEntries.values()) {
+            sb.append("  <env-entry>\n");
+            appendElement(sb, INDENT4, "description",
+                    envEntry.getDescription());
+            appendElement(sb, INDENT4, "env-entry-name", envEntry.getName());
+            appendElement(sb, INDENT4, "env-entry-type", envEntry.getType());
+            appendElement(sb, INDENT4, "env-entry-value", envEntry.getValue());
+            // TODO mapped-name
+            for (InjectionTarget target : envEntry.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </env-entry>\n");
+        }
+        sb.append('\n');
+
+        for (ContextEjb ejbRef : ejbRefs.values()) {
+            sb.append("  <ejb-ref>\n");
+            appendElement(sb, INDENT4, "description", ejbRef.getDescription());
+            appendElement(sb, INDENT4, "ejb-ref-name", ejbRef.getName());
+            appendElement(sb, INDENT4, "ejb-ref-type", ejbRef.getType());
+            appendElement(sb, INDENT4, "home", ejbRef.getHome());
+            appendElement(sb, INDENT4, "remote", ejbRef.getRemote());
+            appendElement(sb, INDENT4, "ejb-link", ejbRef.getLink());
+            // TODO mapped-name
+            for (InjectionTarget target : ejbRef.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </ejb-ref>\n");
+        }
+        sb.append('\n');
+
+        for (ContextLocalEjb ejbLocalRef : ejbLocalRefs.values()) {
+            sb.append("  <ejb-local-ref>\n");
+            appendElement(sb, INDENT4, "description",
+                    ejbLocalRef.getDescription());
+            appendElement(sb, INDENT4, "ejb-ref-name", ejbLocalRef.getName());
+            appendElement(sb, INDENT4, "ejb-ref-type", ejbLocalRef.getType());
+            appendElement(sb, INDENT4, "local-home", ejbLocalRef.getHome());
+            appendElement(sb, INDENT4, "local", ejbLocalRef.getLocal());
+            appendElement(sb, INDENT4, "ejb-link", ejbLocalRef.getLink());
+            // TODO mapped-name
+            for (InjectionTarget target : ejbLocalRef.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </ejb-local-ref>\n");
+        }
+        sb.append('\n');
+        
+        for (ContextService serviceRef : serviceRefs.values()) {
+            sb.append("  <service-ref>\n");
+            appendElement(sb, INDENT4, "description",
+                    serviceRef.getDescription());
+            appendElement(sb, INDENT4, "display-name",
+                    serviceRef.getDisplayname());
+            appendElement(sb, INDENT4, "service-ref-name",
+                    serviceRef.getName());
+            appendElement(sb, INDENT4, "service-interface",
+                    serviceRef.getInterface());
+            appendElement(sb, INDENT4, "service-ref-type",
+                    serviceRef.getType());
+            appendElement(sb, INDENT4, "wsdl-file", serviceRef.getWsdlfile());
+            appendElement(sb, INDENT4, "jaxrpc-mapping-file",
+                    serviceRef.getJaxrpcmappingfile());
+            String qname = serviceRef.getServiceqnameNamespaceURI();
+            if (qname != null) {
+                qname = qname + ":";
+            }
+            qname = qname + serviceRef.getServiceqnameLocalpart();
+            appendElement(sb, INDENT4, "service-qname", qname);
+            Iterator<String> endpointIter = serviceRef.getServiceendpoints();
+            while (endpointIter.hasNext()) {
+                String endpoint = endpointIter.next();
+                sb.append("    <port-component-ref>\n");
+                appendElement(sb, INDENT6, "service-endpoint-interface",
+                        endpoint);
+                appendElement(sb, INDENT6, "port-component-link",
+                        serviceRef.getProperty(endpoint));
+                sb.append("    </port-component-ref>\n");
+            }
+            Iterator<String> handlerIter = serviceRef.getHandlers();
+            while (handlerIter.hasNext()) {
+                String handler = handlerIter.next();
+                sb.append("    <handler>\n");
+                ContextHandler ch = serviceRef.getHandler(handler);
+                appendElement(sb, INDENT6, "handler-name", ch.getName());
+                appendElement(sb, INDENT6, "handler-class",
+                        ch.getHandlerclass());
+                sb.append("    </handler>\n");
+            }
+            // TODO handler-chains
+            // TODO mapped-name
+            for (InjectionTarget target : serviceRef.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </service-ref>\n");
+        }
+        sb.append('\n');
+        
+        for (ContextResource resourceRef : resourceRefs.values()) {
+            sb.append("  <resource-ref>\n");
+            appendElement(sb, INDENT4, "description",
+                    resourceRef.getDescription());
+            appendElement(sb, INDENT4, "res-ref-name", resourceRef.getName());
+            appendElement(sb, INDENT4, "res-type", resourceRef.getType());
+            appendElement(sb, INDENT4, "res-auth", resourceRef.getAuth());
+            appendElement(sb, INDENT4, "res-sharing-scope",
+                    resourceRef.getScope());
+            // TODO mapped-name
+            for (InjectionTarget target : resourceRef.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </resource-ref>\n");
+        }
+        sb.append('\n');
+
+        for (ContextResourceEnvRef resourceEnvRef : resourceEnvRefs.values()) {
+            sb.append("  <resource-env-ref>\n");
+            appendElement(sb, INDENT4, "description",
+                    resourceEnvRef.getDescription());
+            appendElement(sb, INDENT4, "resource-env-ref-name",
+                    resourceEnvRef.getName());
+            appendElement(sb, INDENT4, "resource-env-ref-type",
+                    resourceEnvRef.getType());
+            // TODO mapped-name
+            for (InjectionTarget target :
+                    resourceEnvRef.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </resource-env-ref>\n");
+        }
+        sb.append('\n');
+
+        for (MessageDestinationRef mdr : messageDestinationRefs.values()) {
+            sb.append("  <message-destination-ref>\n");
+            appendElement(sb, INDENT4, "description", mdr.getDescription());
+            appendElement(sb, INDENT4, "message-destination-ref-name",
+                    mdr.getName());
+            appendElement(sb, INDENT4, "message-destination-type",
+                    mdr.getType());
+            appendElement(sb, INDENT4, "message-destination-usage",
+                    mdr.getUsage());
+            appendElement(sb, INDENT4, "message-destination-link",
+                    mdr.getLink());
+            // TODO mapped-name
+            for (InjectionTarget target : mdr.getInjectionTargets()) {
+                sb.append("    <injection-target>\n");
+                appendElement(sb, INDENT6, "injection-target-class",
+                        target.getTargetClass());
+                appendElement(sb, INDENT6, "injection-target-name",
+                        target.getTargetName());
+                sb.append("    </injection-target>\n");
+            }
+            // TODO lookup-name
+            sb.append("  </message-destination-ref>\n");
+        }
+        sb.append('\n');
+
+        for (MessageDestination md : messageDestinations.values()) {
+            sb.append("  <message-destination>\n");
+            appendElement(sb, INDENT4, "description", md.getDescription());
+            appendElement(sb, INDENT4, "display-name", md.getDisplayName());
+            appendElement(sb, INDENT4, "message-destination-name",
+                    md.getName());
+            // TODO mapped-name
+            sb.append("  </message-destination>\n");
+        }
+        sb.append('\n');
+
+        if (localeEncodingMappings.size() > 0) {
+            sb.append("  <locale-encoding-mapping-list>\n");
+            for (Map.Entry<String, String> entry :
+                    localeEncodingMappings.entrySet()) {
+                sb.append("    <locale-encoding-mapping>\n");
+                appendElement(sb, INDENT6, "locale", entry.getKey());
+                appendElement(sb, INDENT6, "encoding", entry.getValue());
+                sb.append("    </locale-encoding-mapping>\n");
+            }
+            sb.append("  </locale-encoding-mapping-list>\n");
+        }
+        sb.append("</web-app>");
+        return sb.toString();
+    }
+
+    private static void appendElement(StringBuilder sb, String indent,
+            String elementName, String value) {
+        if (value == null || value.length() == 0) return;
+        sb.append(indent);
+        sb.append('<');
+        sb.append(elementName);
+        sb.append('>');
+        sb.append(escapeXml(value));
+        sb.append("</");
+        sb.append(elementName);
+        sb.append(">\n");
+    }
+
+    private static void appendElement(StringBuilder sb, String indent,
+            String elementName, Object value) {
+        if (value == null) return;
+        appendElement(sb, indent, elementName, value.toString());
+    }
+
+
+    /**
+     * Escape the 5 entities defined by XML.
+     */
+    private static String escapeXml(String s) {
+        if (s == null)
+            return null;
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (c == '<') {
+                sb.append("&lt;");
+            } else if (c == '>') {
+                sb.append("&gt;");
+            } else if (c == '\'') {
+                sb.append("&apos;");
+            } else if (c == '&') {
+                sb.append("&amp;");
+            } else if (c == '"') {
+                sb.append("&quot;");
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+
+    /**
      * Configure a {@link Context} using the stored web.xml representation.
      *  
      * @param context   The context to be configured
@@ -726,7 +1285,8 @@
         filters.putAll(temp.getFilters());
 
         for (WebXml fragment : fragments) {
-            for (JspPropertyGroup jspPropertyGroup : fragment.getJspPropertyGroups()) {
+            for (JspPropertyGroup jspPropertyGroup :
+                    fragment.getJspPropertyGroups()) {
                 // Always additive
                 addJspPropertyGroup(jspPropertyGroup);
             }
@@ -904,7 +1464,7 @@
         return true;
     }
     
-    private <T extends ResourceBase> boolean mergeResourceMap(
+    private static <T extends ResourceBase> boolean mergeResourceMap(
             Map<String, T> fragmentResources, Map<String, T> mainResources,
             Map<String, T> tempResources,
             Map<String,Boolean> mergeInjectionFlags, WebXml fragment) {
@@ -943,7 +1503,7 @@
         return true;
     }
     
-    private <T> boolean mergeMap(Map<String,T> fragmentMap,
+    private static <T> boolean mergeMap(Map<String,T> fragmentMap,
             Map<String,T> mainMap, Map<String,T> tempMap, WebXml fragment,
             String mapName) {
         for (String key : fragmentMap.keySet()) {
@@ -969,7 +1529,8 @@
         return true;
     }
     
-    private boolean mergeFilter(FilterDef src, FilterDef dest, boolean failOnConflict) {
+    private static boolean mergeFilter(FilterDef src, FilterDef dest,
+            boolean failOnConflict) {
         if (dest.getAsyncSupported() == null) {
             dest.setAsyncSupported(src.getAsyncSupported());
         } else if (src.getAsyncSupported() != null) {
@@ -1002,7 +1563,8 @@
         return true;
     }
     
-    private boolean mergeServlet(ServletDef src, ServletDef dest, boolean failOnConflict) {
+    private static boolean mergeServlet(ServletDef src, ServletDef dest,
+            boolean failOnConflict) {
         // These tests should be unnecessary...
         if (dest.getServletClass() != null && dest.getJspFile() != null) {
             return false;
@@ -1073,7 +1635,7 @@
         return true;
     }
 
-    private boolean mergeMultipartDef(MultipartDef src, MultipartDef dest,
+    private static boolean mergeMultipartDef(MultipartDef src, MultipartDef dest,
             boolean failOnConflict) {
 
         if (dest.getLocation() == null) {
@@ -1228,4 +1790,3 @@
     }
 
 }    
-

Modified: tomcat/trunk/java/org/apache/tomcat/util/scan/Constants.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/scan/Constants.java?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/scan/Constants.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/scan/Constants.java Tue Dec 29 12:50:54 2009
@@ -24,11 +24,15 @@
 
     public static final String Package = "org.apache.tomcat.util.scan";
 
+    /* System properties */
     public static final String SKIP_JARS_PROPERTY =
         "tomcat.util.scan.DefaultJarScanner.jarsToSkip";
 
+    /* Commons strings */
     public static final String JAR_EXT = ".jar";
     public static final String WEB_INF_LIB = "/WEB-INF/lib/";
 
-
+    /* Context attributes - used to pass short-cuts to Jasper */
+    public static final String MERGED_WEB_XML =
+        "org.apache.tomcat.util.scan.MergedWebXml";
 }

Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=894372&r1=894371&r2=894372&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Tue Dec 29 12:50:54 2009
@@ -177,6 +177,15 @@
         inferred by the automatic deployment process.</p>
       </attribute>
 
+      <attribute name="logEffectiveWebXml" required="false">
+        <p>Set to <code>true</code> if you want the effective web.xml used for a
+        web application to be logged (at INFO level) when the application
+        starts. The effective web.xml is the result of combining the
+        application's web.xml with any defaults configured by Tomcat and any
+        web-fragment.xml files and annotations discovered. If not specified, the
+        default value of <code>false</code> is used.</p>
+      </attribute>
+
       <attribute name="override" required="false">
         <p>Set to <code>true</code> to have explicit settings in this
         Context element override any corresponding settings in either the global



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org