Author: markt
Date: Fri Oct 23 16:39:32 2009
New Revision: 829121
URL: http://svn.apache.org/viewvc?rev=829121&view=rev
Log:
Add support for absolute ordering of web fragments and the start of the
fragment merge code
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/WebRuleSet.java
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=829121&r1=829120&r2=829121&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java Fri Oct 23
16:39:32 2009
@@ -29,8 +29,10 @@
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -1235,7 +1237,7 @@
if (!webXml.isMetadataComplete()) {
// Have to process JARs for fragments
- Map<URL,WebXml> fragments = processJarsForWebFragments();
+ Map<String,WebXml> fragments = processJarsForWebFragments();
// Merge the fragments into the main web.xml
mergeWebFragments(webXml, fragments);
@@ -1452,7 +1454,7 @@
*
* @return A map of JAR name to processed web fragment (if any)
*/
- protected Map<URL,WebXml> processJarsForWebFragments() {
+ protected Map<String,WebXml> processJarsForWebFragments() {
JarScanner jarScanner = context.getJarScanner();
FragmentJarScannerCallback callback = new FragmentJarScannerCallback();
@@ -1467,7 +1469,7 @@
private static final String FRAGMENT_LOCATION =
"META-INF/web-fragment.xml";
- private Map<URL,WebXml> fragments = new HashMap<URL,WebXml>();
+ private Map<String,WebXml> fragments = new HashMap<String,WebXml>();
@Override
public void scan(JarURLConnection urlConn) throws IOException {
@@ -1505,7 +1507,15 @@
// ignore
}
}
- fragments.put(urlConn.getURL(), fragment);
+ if (fragment == null) {
+ fragments.put(urlConn.getURL().toString(), fragment);
+ } else {
+ fragment.setURL(urlConn.getURL());
+ if (fragment.getName() == null) {
+ fragment.setName(fragment.getURL().toString());
+ }
+ fragments.put(fragment.getName(), fragment);
+ }
}
}
@@ -1533,11 +1543,19 @@
// ignore
}
}
- fragments.put(file.toURI().toURL(), fragment);
+ if (fragment == null) {
+ fragments.put(file.toURI().toURL().toString(), fragment);
+ } else {
+ fragment.setURL(file.toURI().toURL());
+ if (fragment.getName() == null) {
+ fragment.setName(fragment.getURL().toString());
+ }
+ fragments.put(fragment.getName(), fragment);
+ }
}
}
- public Map<URL,WebXml> getFragments() {
+ public Map<String,WebXml> getFragments() {
return fragments;
}
}
@@ -1547,22 +1565,61 @@
* Servlet spec.
*
* @param application The application web.xml file
- * @param fragments The map of JARs to web fragments
+ * @param fragments The map of fragment names to web fragments
*/
protected void mergeWebFragments(WebXml application,
- Map<URL,WebXml> fragments) {
- // TODO SERVLET3
- // Check order
+ Map<String,WebXml> fragments) {
+
+ Set<WebXml> orderedFragments = new LinkedHashSet<WebXml>();
+
+ boolean absoluteOrdering =
+ (application.getAbsoluteOrdering() != null);
+
+ if (absoluteOrdering) {
+ // Only those fragments listed should be processed
+ Set<String> requestedOrder = application.getAbsoluteOrdering();
+
+ for (String requestedName : requestedOrder) {
+ if (WebXml.ORDER_OTHERS.equals(requestedName)) {
+ // Add all fragments not named explicitly at this point
+ for (String name : fragments.keySet()) {
+ if (!requestedOrder.contains(name)) {
+ WebXml fragment = fragments.get(name);
+ if (fragment != null) {
+ orderedFragments.add(fragment);
+ }
+ }
+ }
+ } else {
+ WebXml fragment = fragments.get(requestedName);
+ if (fragment != null) {
+ orderedFragments.add(fragment);
+ }
+ }
+ }
+ } else {
+ // 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 - conflict == application wins
+ if (ok) {
+ ok = application.merge(mergedFragments, true);
+ }
}
- protected void processAnnotationsInJars(Map<URL,WebXml> fragments) {
- for(URL url : fragments.keySet()) {
- WebXml fragment = fragments.get(url);
+ protected void processAnnotationsInJars(Map<String,WebXml> fragments) {
+ for(String name : fragments.keySet()) {
+ WebXml fragment = fragments.get(name);
if (fragment == null || !fragment.isMetadataComplete()) {
// Scan jar for annotations
// TODO SERVLET3
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=829121&r1=829120&r2=829121&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Fri
Oct 23 16:39:32 2009
@@ -105,11 +105,14 @@
userConfig.error=Error deploying web application for user {0}
userConfig.start=UserConfig: Processing START
userConfig.stop=UserConfig: Processing STOP
-webXmlCommon.duplicateEnvEntry=Duplicate env-entry name
-webXmlCommon.duplicateFilter=Duplicate filter name
-webXmlCommon.duplicateMessageDestination=Duplicate message-destination name
-webXmlCommon.duplicateMessageDestinationRef=Duplicate message-destination-ref
name
-webXmlCommon.duplicateResourceEnvRef=Duplicate resource-env-ref name
-webXmlCommon.duplicateResourceRef=Duplicate resource-ref name
-webXmlCommon.reservedName=A web.xml file was detected using a reserved name
[{0}]. The name element will be ignored for this fragment.
-webXmlFragment.multipleOther=Multiple others entries in ordering
+webRuleSet.absoluteOrdering=<absolute-ordering> element not valid in
web-fragment.xml and will be ignored
+webRuleSet.relativeOrdering=<ordering> element not valid in web.xml and will
be ignored
+webXml.duplicateEnvEntry=Duplicate env-entry name
+webXml.duplicateFilter=Duplicate filter name
+webXml.duplicateMessageDestination=Duplicate message-destination name
+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.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/WebRuleSet.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java?rev=829121&r1=829120&r2=829121&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java Fri Oct 23
16:39:32 2009
@@ -33,6 +33,7 @@
import org.apache.tomcat.util.digester.Rule;
import org.apache.tomcat.util.digester.RuleSetBase;
import org.apache.tomcat.util.digester.SetNextRule;
+import org.apache.tomcat.util.res.StringManager;
import org.xml.sax.Attributes;
@@ -46,6 +47,11 @@
public class WebRuleSet extends RuleSetBase {
+ /**
+ * The string resources for this package.
+ */
+ protected static final StringManager sm =
+ StringManager.getManager(Constants.Package);
// ----------------------------------------------------- Instance Variables
@@ -62,6 +68,12 @@
protected String fullPrefix = null;
/**
+ * Flag that indicates if this ruleset is for a web-fragment.xml file or
for
+ * a web.xml file.
+ */
+ protected boolean fragment = false;
+
+ /**
* The <code>SetSessionConfig</code> rule used to parse the web.xml
*/
protected SetSessionConfig sessionConfig;
@@ -116,13 +128,13 @@
super();
this.namespaceURI = null;
this.prefix = prefix;
+ this.fragment = fragment;
if(fragment) {
fullPrefix = prefix + "web-fragment";
} else {
fullPrefix = prefix + "web-app";
}
-
}
@@ -148,6 +160,31 @@
digester.addRule(fullPrefix,
new IgnoreAnnotationsRule());
+ digester.addCallMethod(fullPrefix + "/name",
+ "setName", 0);
+
+ if (fragment) {
+ // web-fragment.xml
+ digester.addRule(fullPrefix + "/absolute-ordering",
+ new AbsoluteOrderingRule());
+ digester.addCallMethod(fullPrefix + "/ordering/after/name",
+ "addAfterOrdering", 0);
+ digester.addCallMethod(fullPrefix + "/ordering/after/others",
+ "addAfterOrderingOthers");
+ digester.addCallMethod(fullPrefix + "/ordering/before/name",
+ "addBeforeOrdering", 0);
+ digester.addCallMethod(fullPrefix + "/ordering/before/others",
+ "addBeforeOrderingOthers");
+ } else {
+ // web.xml
+ digester.addRule(fullPrefix + "/ordering",
+ new RelativeOrderingRule());
+ digester.addCallMethod(fullPrefix + "/absolute-ordering/name",
+ "addAbsoluteOrdering", 0);
+ digester.addCallMethod(fullPrefix +
"/absolute-ordering/name/others",
+ "addAbsoluteOrderingOthers");
+ }
+
digester.addCallMethod(fullPrefix + "/context-param",
"addContextParam", 2);
digester.addCallParam(fullPrefix + "/context-param/param-name", 0);
@@ -904,6 +941,36 @@
}
/**
+ * A rule that logs a warning if absolute ordering is configured.
+ */
+final class AbsoluteOrderingRule extends Rule {
+
+ public AbsoluteOrderingRule() {
+ }
+
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ digester.getLogger().warn(
+ WebRuleSet.sm.getString("webRuleSet.absoluteOrdering"));
+ }
+}
+
+/**
+ * A rule that logs a warning if relative ordering is configured.
+ */
+final class RelativeOrderingRule extends Rule {
+
+ public RelativeOrderingRule() {
+ }
+
+ public void begin(String namespace, String name, Attributes attributes)
+ throws Exception {
+ digester.getLogger().warn(
+ WebRuleSet.sm.getString("webRuleSet.relativeOrdering"));
+ }
+}
+
+/**
* A Rule that sets soap headers on the ContextHandler.
*
*/
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=829121&r1=829120&r2=829121&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/WebXml.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/WebXml.java Fri Oct 23
16:39:32 2009
@@ -18,6 +18,7 @@
package org.apache.catalina.startup;
+import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -65,13 +66,22 @@
// web.xml only elements
// Absolute Ordering
- private Set<String> absoluteOrdering = new LinkedHashSet<String>();
+ private Set<String> absoluteOrdering = null;
public void addAbsoluteOrdering(String name) {
+ if (absoluteOrdering == null) {
+ absoluteOrdering = new LinkedHashSet<String>();
+ }
absoluteOrdering.add(name);
}
public void addAbsoluteOrderingOthers() {
+ if (absoluteOrdering == null) {
+ absoluteOrdering = new LinkedHashSet<String>();
+ }
absoluteOrdering.add(ORDER_OTHERS);
}
+ public Set<String> getAbsoluteOrdering() {
+ return absoluteOrdering;
+ }
// web-fragment.xml only elements
// Relative ordering
@@ -82,7 +92,7 @@
public void addAfterOrderingOthers() {
if (before.contains(ORDER_OTHERS)) {
throw new IllegalArgumentException(sm.getString(
- "webXmlFragment.multipleOther"));
+ "webXml.multipleOther"));
}
after.add(ORDER_OTHERS);
}
@@ -93,7 +103,7 @@
public void addBeforeOrderingOthers() {
if (after.contains(ORDER_OTHERS)) {
throw new IllegalArgumentException(sm.getString(
- "webXmlFragment.multipleOther"));
+ "webXml.multipleOther"));
}
before.add(ORDER_OTHERS);
}
@@ -122,7 +132,7 @@
public void setName(String name) {
if (ORDER_OTHERS.equalsIgnoreCase(name)) {
// This is unusual. This name will be ignored. Log the fact.
- log.warn(sm.getString("webXmlCommon.reservedName", name));
+ log.warn(sm.getString("webXml.reservedName", name));
} else {
this.name = name;
}
@@ -165,7 +175,7 @@
if (filters.containsKey(filter.getFilterName())) {
// Filter names must be unique within a web(-fragment).xml
throw new IllegalArgumentException(
- sm.getString("webXmlCommon.duplicateFilter"));
+ sm.getString("webXml.duplicateFilter"));
}
filters.put(filter.getFilterName(), filter);
}
@@ -299,7 +309,7 @@
if (envEntries.containsKey(envEntry.getName())) {
// env-entry names must be unique within a web(-fragment).xml
throw new IllegalArgumentException(
- sm.getString("webXmlCommon.duplicateEnvEntry"));
+ sm.getString("webXml.duplicateEnvEntry"));
}
envEntries.put(envEntry.getName(),envEntry);
}
@@ -337,7 +347,7 @@
if (resourceRefs.containsKey(resourceRef.getName())) {
// resource-ref names must be unique within a web(-fragment).xml
throw new IllegalArgumentException(
- sm.getString("webXmlCommon.duplicateResourceRef"));
+ sm.getString("webXml.duplicateResourceRef"));
}
resourceRefs.put(resourceRef.getName(), resourceRef);
}
@@ -353,7 +363,7 @@
if (resourceEnvRefs.containsKey(resourceEnvRef.getName())) {
// resource-env-ref names must be unique within a
web(-fragment).xml
throw new IllegalArgumentException(
- sm.getString("webXmlCommon.duplicateResourceEnvRef"));
+ sm.getString("webXml.duplicateResourceEnvRef"));
}
resourceEnvRefs.put(resourceEnvRef.getName(), resourceEnvRef);
}
@@ -372,7 +382,7 @@
// message-destination-ref names must be unique within a
// web(-fragment).xml
throw new IllegalArgumentException(sm.getString(
- "webXmlCommon.duplicateMessageDestinationRef"));
+ "webXml.duplicateMessageDestinationRef"));
}
messageDestinationRefs.put(messageDestinationRef.getName(),
messageDestinationRef);
@@ -394,7 +404,7 @@
// message-destination names must be unique within a
// web(-fragment).xml
throw new IllegalArgumentException(
- sm.getString("webXmlCommon.duplicateMessageDestination"));
+ sm.getString("webXml.duplicateMessageDestination"));
}
messageDestinations.put(messageDestination.getName(),
messageDestination);
@@ -413,6 +423,14 @@
return localeEncodingMappings;
}
+
+ // Attributes not defined in web.xml or web-fragment.xml
+
+ // URL of web-fragment
+ private URL uRL = null;
+ public void setURL(URL url) { this.uRL = url; }
+ public URL getURL() { return uRL; }
+
/**
* Configure a {...@link Context} using the stored web.xml representation.
*
@@ -538,4 +556,33 @@
context.addJspMapping(jspPropertyGroup.getUrlPattern());
}
}
+
+ /**
+ * Merge the supplied web fragment into this this one.
+ *
+ * @param source The fragment to merge in
+ * @boolean ignoreConflicts Flag that indicates that conflicts should be
+ * ignored and the existing value used
+ * @return <code>true</code> if merge is successful, else
+ * <code>false</code>
+ */
+ public boolean merge(WebXml source, boolean ignoreConflicts) {
+ // TODO SERVLET3
+
+ // 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;
+ }
+ } else {
+ listeners.add(listener);
+ }
+ }
+
+ return true;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]