Author: markt
Date: Sat Oct 24 20:07:42 2009
New Revision: 829440

URL: http://svn.apache.org/viewvc?rev=829440&view=rev
Log:
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

Modified:
    tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/startup/WebXml.java

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=829440&r1=829439&r2=829440&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Sat Oct 24 
20:07:42 2009
@@ -1215,6 +1215,7 @@
      */
     protected void webConfig() {
         WebXml webXml = new WebXml();
+
         // Parse global web.xml if present
         InputSource globalWebXml = getGlobalWebXmlSource();
         if (globalWebXml == null) {
@@ -1242,14 +1243,14 @@
             // 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 @@
             // 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);
         }
     }
 

Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=829440&r1=829439&r2=829440&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Sat 
Oct 24 20:07:42 2009
@@ -114,5 +114,8 @@
 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

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=829440&r1=829439&r2=829440&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebXml.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebXml.java Sat Oct 24 
20:07:42 2009
@@ -323,11 +323,14 @@
     
     // ejb-local-ref
     // TODO: Should support multiple description elements with language
-    private Set<ContextLocalEjb> ejbLocalRefs = new HashSet<ContextLocalEjb>();
+    private Map<String,ContextLocalEjb> ejbLocalRefs =
+        new HashMap<String,ContextLocalEjb>();
     public void addEjbLocalRef(ContextLocalEjb ejbLocalRef) {
-        ejbLocalRefs.add(ejbLocalRef);
+        ejbLocalRefs.put(ejbLocalRef.getName(),ejbLocalRef);
+    }
+    public Map<String,ContextLocalEjb> getEjbLocalRefs() {
+        return ejbLocalRefs;
     }
-    public Set<ContextLocalEjb> getEjbLocalRefs() { return ejbLocalRefs; }
     
     // service-ref
     // TODO: Should support multiple description elements with language
@@ -448,7 +451,7 @@
         }
         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 @@
     }
     
     /**
-     * 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 <code>true</code> if merge is successful, else
      *         <code>false</code>
      */
-    public boolean merge(WebXml source, boolean ignoreConflicts) {
-        // TODO SERVLET3
+    public boolean merge(Set<WebXml> 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<String,Boolean> mergeInjectionFlags =
+            new HashMap<String, Boolean>();
+        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;
     }



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

Reply via email to