From: markt Date: Tue, 10 Nov 2009 00:31:25 +0000 (+0000) Subject: Add merge code for the remaining elements in web.xml X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=6a4d40450bba22eb81f0e8972a4083b7165d4ccf;p=tomcat7.0 Add merge code for the remaining elements in web.xml git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@834286 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/startup/LocalStrings.properties b/java/org/apache/catalina/startup/LocalStrings.properties index 3eff77dad..d43ca4702 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -115,9 +115,11 @@ webXml.duplicateResourceEnvRef=Duplicate resource-env-ref name webXml.duplicateResourceRef=Duplicate resource-ref name webXml.reservedName=A web.xml file was detected using a reserved name [{0}]. The name element will be ignored for this fragment. webXml.mergeConflictDisplayName=The display name was defined in multiple fragments with different values including fragment with name [{0}] located at [{1}] -webXml.mergeConflictErrorPage=The Error Page for [{0}] was defined in multiple fragments including fragment with name [{1}] located at [{2}] -webXml.mergeConflictListener=Listener [{0}] was defined in multiple fragments including fragment with name [{1}] located at [{2}] -webXml.mergeConflictLoginConfig=A LoginConfig was defined in multiple fragments including fragment with name [{1}] located at [{2}] -webXml.mergeConflictResource=The Resource [{0}] was defined in multiple fragments including fragment with name [{1}] located at [{2}] -webXml.mergeConflictString=The [{0}] with name [{1}] was defined in multiple fragments including fragment with name [{2}] located at [{3}] +webXml.mergeConflictErrorPage=The Error Page for [{0}] was defined inconsistently in multiple fragments including fragment with name [{1}] located at [{2}] +webXml.mergeConflictFilter=The Filter [{0}] was defined inconsistently in multiple fragments including fragment with name [{1}] located at [{2}] +webXml.mergeConflictLoginConfig=A LoginConfig was defined inconsistently in multiple fragments including fragment with name [{1}] located at [{2}] +webXml.mergeConflictResource=The Resource [{0}] was defined inconsistently in multiple fragments including fragment with name [{1}] located at [{2}] +webXml.mergeConflictFilter=The Servlet [{0}] was defined inconsistently in multiple fragments including fragment with name [{1}] located at [{2}] +webXml.mergeConflictSessionTimeout=The session timeout was defined inconsistently in multiple fragments with different values including fragment with name [{0}] located at [{1}] +webXml.mergeConflictString=The [{0}] with name [{1}] was defined inconsistently in multiple fragments including fragment with name [{2}] located at [{3}] webXml.multipleOther=Multiple others entries in ordering diff --git a/java/org/apache/catalina/startup/WebXml.java b/java/org/apache/catalina/startup/WebXml.java index dd2263b03..9855615a8 100644 --- a/java/org/apache/catalina/startup/WebXml.java +++ b/java/org/apache/catalina/startup/WebXml.java @@ -250,6 +250,7 @@ public class WebXml { } welcomeFiles.add(welcomeFile); } + public Set getWelcomeFiles() { return welcomeFiles; } // error-page private Map errorPages = new HashMap(); @@ -341,11 +342,12 @@ public class WebXml { // 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(); + private Map serviceRefs = + new HashMap(); public void addServiceRef(ContextService serviceRef) { - serviceRefs.add(serviceRef); + serviceRefs.put(serviceRef.getName(), serviceRef); } - public Set getServiceRefs() { return serviceRefs; } + public Map getServiceRefs() { return serviceRefs; } // resource-ref // TODO: Should support multiple description elements with language @@ -512,7 +514,7 @@ public class WebXml { for (String role : securityRoles) { context.addSecurityRole(role); } - for (ContextService service : serviceRefs) { + for (ContextService service : serviceRefs.values()) { context.getNamingResources().addService(service); } for (ServletDef servlet : servlets.values()) { @@ -660,6 +662,27 @@ public class WebXml { } for (WebXml fragment : fragments) { + for (Map.Entry entry : + fragment.getFilters().entrySet()) { + if (filters.containsKey(entry.getKey())) { + mergeFilter(entry.getValue(), + filters.get(entry.getKey()), false); + } else { + if (!(mergeFilter(entry.getValue(), + temp.getFilters().get(entry.getKey()), true))) { + log.error(sm.getString( + "webXml.mergeConflictFilter", + entry.getKey(), + fragment.getName(), + fragment.getURL())); + + return false; + } + } + } + } + + for (WebXml fragment : fragments) { for (JspPropertyGroup jspPropertyGroup : fragment.getJspPropertyGroups()) { // Always additive addJspPropertyGroup(jspPropertyGroup); @@ -757,8 +780,77 @@ public class WebXml { } } + for (WebXml fragment : fragments) { + if (!mergeResourceMap(fragment.getServiceRefs(), serviceRefs, + temp.getServiceRefs(), mergeInjectionFlags, fragment)) { + return false; + } + } + serviceRefs.putAll(temp.getServiceRefs()); + mergeInjectionFlags.clear(); + + for (WebXml fragment : fragments) { + for (Map.Entry mapping : + fragment.getServletMappings().entrySet()) { + // Always additive + addServletMapping(mapping.getKey(), mapping.getValue()); + } + } + + for (WebXml fragment : fragments) { + for (Map.Entry entry : + fragment.getServlets().entrySet()) { + if (servlets.containsKey(entry.getKey())) { + mergeServlet(entry.getValue(), + servlets.get(entry.getKey()), false); + } else { + if (!(mergeServlet(entry.getValue(), + temp.getServlets().get(entry.getKey()), true))) { + log.error(sm.getString( + "webXml.mergeConflictServlet", + entry.getKey(), + fragment.getName(), + fragment.getURL())); + + return false; + } + } + } + } + - // TODO SERVLET3 - Merge remaining elements + if (sessionTimeout == null) { + for (WebXml fragment : fragments) { + Integer value = fragment.getSessionTimeout(); + if (value != null) { + if (temp.getSessionTimeout() == null) { + temp.setSessionTimeout(value.toString()); + } else { + log.error(sm.getString( + "webXml.mergeConflictSessionTimeout", + fragment.getName(), + fragment.getURL())); + return false; + } + } + } + sessionTimeout = temp.getSessionTimeout(); + } + + for (WebXml fragment : fragments) { + if (!mergeMap(fragment.getTaglibs(), taglibs, + temp.getTaglibs(), fragment, "Taglibs")) { + return false; + } + } + taglibs.putAll(temp.getTaglibs()); + + for (WebXml fragment : fragments) { + for (String welcomeFile : fragment.getWelcomeFiles()) { + // Always additive + addWelcomeFile(welcomeFile); + } + } return true; } @@ -828,4 +920,88 @@ public class WebXml { } return true; } + + private boolean mergeFilter(FilterDef src, FilterDef dest, boolean failOnConflict) { + if (src.isAsyncSupported() != dest.isAsyncSupported()) { + // Always fail + return false; + } + + if (dest.getFilterClass() == null) { + dest.setFilterClass(src.getFilterClass()); + } else if (src.getFilterClass() != null) { + if (failOnConflict && + !src.getFilterClass().equals(dest.getFilterClass())) { + return false; + } + } + + for (Map.Entry srcEntry : + src.getParameterMap().entrySet()) { + if (dest.getParameterMap().containsKey(srcEntry.getKey())) { + if (failOnConflict && !dest.getParameterMap().get( + srcEntry.getKey()).equals(srcEntry.getValue())) { + return false; + } + } else { + dest.addInitParameter(srcEntry.getKey(), srcEntry.getValue()); + } + } + return true; + } + + private boolean mergeServlet(ServletDef src, ServletDef dest, boolean failOnConflict) { + // These tests should be unnecessary... + if (dest.getServletClass() != null && dest.getJspFile() != null) { + return false; + } + if (src.getServletClass() != null && src.getJspFile() != null) { + return false; + } + + + if (dest.getServletClass() == null && dest.getJspFile() == null) { + dest.setServletClass(src.getServletClass()); + dest.setJspFile(src.getJspFile()); + } else if (failOnConflict) { + if (src.getServletClass() != null && + (dest.getJspFile() != null || + !src.getServletClass().equals(dest.getServletClass()))) { + return false; + } + if (src.getJspFile() != null && + (dest.getServletClass() != null || + !src.getJspFile().equals(dest.getJspFile()))) { + return false; + } + } + + // Additive + for (SecurityRoleRef securityRoleRef : src.getSecurityRoleRefs()) { + dest.addSecurityRoleRef(securityRoleRef); + } + + if (dest.getLoadOnStartup() == null) { + dest.setLoadOnStartup(src.getServletClass()); + } else if (src.getLoadOnStartup() != null) { + if (failOnConflict && + !src.getLoadOnStartup().equals(dest.getLoadOnStartup())) { + return false; + } + } + + for (Map.Entry srcEntry : + src.getParameterMap().entrySet()) { + if (dest.getParameterMap().containsKey(srcEntry.getKey())) { + if (failOnConflict && !dest.getParameterMap().get( + srcEntry.getKey()).equals(srcEntry.getValue())) { + return false; + } + } else { + dest.addInitParameter(srcEntry.getKey(), srcEntry.getValue()); + } + } + return true; + } + }