From: markt Date: Sat, 24 Oct 2009 20:07:42 +0000 (+0000) Subject: Implement merge rules for a few more web.xml elements X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=cde993ae7788a18497e641400e840b6c6a7f9b99;p=tomcat7.0 Implement merge rules for a few more web.xml elements Required some refactoring as some of the rules depend on all fragments and the main web.xml git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@829440 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/startup/ContextConfig.java b/java/org/apache/catalina/startup/ContextConfig.java index 6afbd6c19..3b6ed4918 100644 --- a/java/org/apache/catalina/startup/ContextConfig.java +++ b/java/org/apache/catalina/startup/ContextConfig.java @@ -1215,6 +1215,7 @@ public class ContextConfig */ protected void webConfig() { WebXml webXml = new WebXml(); + // Parse global web.xml if present InputSource globalWebXml = getGlobalWebXmlSource(); if (globalWebXml == null) { @@ -1242,14 +1243,14 @@ public class ContextConfig // 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 + + // Apply merged web.xml to Context + webXml.configureContext(context); } else { // Apply merged web.xml to Context webXml.configureContext(context); @@ -1601,18 +1602,9 @@ public class ContextConfig // TODO SERVLET3 Relative ordering } - // Merge fragments in order - conflict == error - WebXml mergedFragments = new WebXml(); - for (WebXml fragment : orderedFragments) { - ok = mergedFragments.merge(fragment, false); - if (ok == false) { - break; - } - } - - // Merge fragment into application - conflict == application wins + // Merge fragment into application if (ok) { - ok = application.merge(mergedFragments, true); + ok = application.merge(orderedFragments); } } diff --git a/java/org/apache/catalina/startup/LocalStrings.properties b/java/org/apache/catalina/startup/LocalStrings.properties index 07b0d850d..45fc02e7e 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -114,5 +114,8 @@ webXml.duplicateMessageDestinationRef=Duplicate message-destination-ref name 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.mergeConflictContextParam=Context parameter [{0}] was defined in multiple fragments with different values including fragment with name [{1}] located at [{2}] +webXml.mergeConflictDisplayName=The display name was defined in multiple fragments with different values including fragment with name [{0}] located at [{1}] +webXml.mergeConflictEjbLocalRef=The EjbLocalRef [{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.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 0eb84f5f1..e13e66fc4 100644 --- a/java/org/apache/catalina/startup/WebXml.java +++ b/java/org/apache/catalina/startup/WebXml.java @@ -323,11 +323,14 @@ public class WebXml { // ejb-local-ref // TODO: Should support multiple description elements with language - private Set ejbLocalRefs = new HashSet(); + private Map ejbLocalRefs = + new HashMap(); public void addEjbLocalRef(ContextLocalEjb ejbLocalRef) { - ejbLocalRefs.add(ejbLocalRef); + ejbLocalRefs.put(ejbLocalRef.getName(),ejbLocalRef); + } + public Map getEjbLocalRefs() { + return ejbLocalRefs; } - public Set getEjbLocalRefs() { return ejbLocalRefs; } // service-ref // TODO: Should support multiple description elements with language @@ -448,7 +451,7 @@ public class WebXml { } context.setDisplayName(displayName); context.setDistributable(distributable); - for (ContextLocalEjb ejbLocalRef : ejbLocalRefs) { + for (ContextLocalEjb ejbLocalRef : ejbLocalRefs.values()) { context.getNamingResources().addLocalEjb(ejbLocalRef); } for (ContextEjb ejbRef : ejbRefs) { @@ -558,30 +561,131 @@ public class WebXml { } /** - * Merge the supplied web fragment into this this one. + * Merge the supplied web fragments into this main web.xml. * - * @param source The fragment to merge in - * @boolean ignoreConflicts Flag that indicates that conflicts should be - * ignored and the existing value used + * @param fragments The fragments to merge in * @return true if merge is successful, else * false */ - public boolean merge(WebXml source, boolean ignoreConflicts) { - // TODO SERVLET3 + public boolean merge(Set fragments) { + // As far as possible, process in alphabetical order so it is easy to + // check everything is present + + // Merge rules vary from element to element. See SRV.8.2.3 + + WebXml temp = new WebXml(); + + for (WebXml fragment : fragments) { + for (String contextParam : fragment.getContextParams().keySet()) { + if (!contextParams.containsKey(contextParam)) { + // Not defined in main web.xml + String value = + fragment.getContextParams().get(contextParam); + if (temp.getContextParams().containsKey(contextParam)) { + if (value != null && !value.equals( + temp.getContextParams().get(contextParam))) { + log.error(sm.getString( + "webXml.mergeConflictContextParam", + contextParam, + fragment.getName(), + fragment.getURL())); + return false; + } + } else { + temp.addContextParam(contextParam, value); + } + } + } + } + contextParams.putAll(temp.getContextParams()); + + if (displayName == null) { + for (WebXml fragment : fragments) { + String value = fragment.getDisplayName(); + if (value != null) { + if (temp.getDisplayName() == null) { + temp.setDisplayName(value); + } else { + log.error(sm.getString( + "webXml.mergeConflictDisplayName", + fragment.getName(), + fragment.getURL())); + return false; + } + } + } + } + displayName = temp.getDisplayName(); + + if (distributable) { + for (WebXml fragment : fragments) { + if (!fragment.isDistributable()) { + distributable = false; + break; + } + } + } - // Just do listeners for now since that is what my simple test case is - // using - for (String listener : source.getListeners()) { - if (listeners.contains(listener)) { - if (!ignoreConflicts) { - log.error(sm.getString("webXml.mergeConflictListener", - listener, source.getName(), source.getURL())); - return false; + Map mergeInjectionFlags = + new HashMap(); + for (WebXml fragment : fragments) { + for (ContextLocalEjb ejbLocalRef : + fragment.getEjbLocalRefs().values()) { + String name = ejbLocalRef.getName(); + boolean mergeInjectionFlag = false; + if (ejbLocalRefs.containsKey(name)) { + if (mergeInjectionFlags.containsKey(name)) { + mergeInjectionFlag = + mergeInjectionFlags.get(name).booleanValue(); + } else { + if (ejbLocalRefs.get( + name).getInjectionTargets().size() == 0) { + mergeInjectionFlag = true; + } + mergeInjectionFlags.put(name, + Boolean.valueOf(mergeInjectionFlag)); + } + if (mergeInjectionFlag) { + ejbLocalRefs.get(name).getInjectionTargets().addAll( + ejbLocalRef.getInjectionTargets()); + } + } else { + // Not defined in main web.xml + if (temp.getEjbLocalRefs().containsKey(name)) { + log.error(sm.getString( + "webXml.mergeConflictEjbLocalRef", + name, + fragment.getName(), + fragment.getURL())); + return false; + } else { + temp.getEjbLocalRefs().put(name, ejbLocalRef); + } + } + } + } + ejbLocalRefs.putAll(temp.getEjbLocalRefs()); + + // TODO SERVLET3 - Merge remaining elements + + for (WebXml fragment : fragments) { + for (String listener : fragment.getListeners()) { + if (!listeners.contains(listener)) { + // Not defined in main web.xml + if (temp.getListeners().contains(listener)) { + log.error(sm.getString( + "webXml.mergeConflictListener", + listener, + fragment.getName(), + fragment.getURL())); + return false; + } else { + temp.addListener(listener); + } } - } else { - listeners.add(listener); } } + listeners.addAll(temp.getListeners()); return true; }