From 89101cf067533fe5f7a87d6621895b9877eda767 Mon Sep 17 00:00:00 2001 From: markt Date: Mon, 13 Jul 2009 16:43:26 +0000 Subject: [PATCH] Track the TLD URIs processed for each webapp and don't process duplicates. Because this tracks duplicate status in the RuleSet, each digester needs its own RuleSet rather than sharing the static one. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@793621 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/startup/TldConfig.java | 31 +++++++++--- java/org/apache/catalina/startup/TldRuleSet.java | 60 +++++++++++++++++++++++- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/java/org/apache/catalina/startup/TldConfig.java b/java/org/apache/catalina/startup/TldConfig.java index 2edf35764..58e6f036f 100644 --- a/java/org/apache/catalina/startup/TldConfig.java +++ b/java/org/apache/catalina/startup/TldConfig.java @@ -80,8 +80,6 @@ public final class TldConfig implements LifecycleListener { */ private static Digester[] tldDigesters = new Digester[4]; - private static final TldRuleSet tldRuleSet = new TldRuleSet(); - /* * Initializes the set of JARs that are known not to contain any TLDs */ @@ -145,25 +143,25 @@ public final class TldConfig implements LifecycleListener { if (!namespaceAware && !validation) { if (tldDigesters[0] == null) { tldDigesters[0] = DigesterFactory.newDigester(validation, - namespaceAware, tldRuleSet); + namespaceAware, new TldRuleSet()); } digester = tldDigesters[0]; } else if (!namespaceAware && validation) { if (tldDigesters[1] == null) { tldDigesters[1] = DigesterFactory.newDigester(validation, - namespaceAware, tldRuleSet); + namespaceAware, new TldRuleSet()); } digester = tldDigesters[1]; } else if (namespaceAware && !validation) { if (tldDigesters[2] == null) { tldDigesters[2] = DigesterFactory.newDigester(validation, - namespaceAware, tldRuleSet); + namespaceAware, new TldRuleSet()); } digester = tldDigesters[2]; } else { if (tldDigesters[3] == null) { tldDigesters[3] = DigesterFactory.newDigester(validation, - namespaceAware, tldRuleSet); + namespaceAware, new TldRuleSet()); } digester = tldDigesters[3]; } @@ -199,11 +197,32 @@ public final class TldConfig implements LifecycleListener { private boolean rescan=true; + /** + * Set of URIs discovered for the associated context. Used to enforce the + * correct processing priority. Only the TLD associated with the first + * instance of any URI will be processed. + */ + private Set taglibUris = new HashSet(); + private ArrayList listeners = new ArrayList(); // --------------------------------------------------------- Public Methods /** + * Adds a taglib URI to the list of known URIs. + */ + public void addTaglibUri(String uri) { + taglibUris.add(uri); + } + + /** + * Determines if the provided URI is a known taglib URI. + */ + public boolean isKnownTaglibUri(String uri) { + return taglibUris.contains(uri); + } + + /** * Sets the list of JARs that are known not to contain any TLDs. * * @param jarNames List of comma-separated names of JAR files that are diff --git a/java/org/apache/catalina/startup/TldRuleSet.java b/java/org/apache/catalina/startup/TldRuleSet.java index e11ea9963..b24218e05 100644 --- a/java/org/apache/catalina/startup/TldRuleSet.java +++ b/java/org/apache/catalina/startup/TldRuleSet.java @@ -20,6 +20,7 @@ package org.apache.catalina.startup; import org.apache.tomcat.util.digester.Digester; +import org.apache.tomcat.util.digester.Rule; import org.apache.tomcat.util.digester.RuleSetBase; @@ -87,10 +88,65 @@ public class TldRuleSet extends RuleSetBase { */ public void addRuleInstances(Digester digester) { - digester.addCallMethod(prefix + "taglib/listener/listener-class", - "addApplicationListener", 0); + TaglibUriRule taglibUriRule = new TaglibUriRule(); + + digester.addRule(prefix + "taglib/uri", taglibUriRule); + + digester.addRule(prefix + "taglib/listener/listener-class", + new TaglibListenerRule(taglibUriRule)); } } + +final class TaglibUriRule extends Rule { + + private boolean duplicateUri; + + public TaglibUriRule() { + } + + @Override + public void body(String namespace, String name, String text) + throws Exception { + TldConfig tldConfig = + (TldConfig) digester.peek(digester.getCount() - 1); + if (tldConfig.isKnownTaglibUri(text)) { + // Already seen this URI + duplicateUri = true; + digester.getLogger().info( + "TLD skipped. URI: " + text + " is already defined"); + } else { + // New URI. Add it to known list and carry on + duplicateUri = false; + tldConfig.addTaglibUri(text); + } + } + + public boolean isDuplicateUri() { + return duplicateUri; + } +} + +final class TaglibListenerRule extends Rule { + + private final TaglibUriRule taglibUriRule; + + public TaglibListenerRule(TaglibUriRule taglibUriRule) { + this.taglibUriRule = taglibUriRule; + } + + @Override + public void body(String namespace, String name, String text) + throws Exception { + TldConfig tldConfig = + (TldConfig) digester.peek(digester.getCount() - 1); + + // Only process the listener if the URI is not a duplicate + if (!taglibUriRule.isDuplicateUri()) { + tldConfig.addApplicationListener(text); + } + } + +} \ No newline at end of file -- 2.11.0