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: [email protected]
For additional commands, e-mail: [email protected]