*/
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
*/
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];
}
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<String> taglibUris = new HashSet<String>();
+
private ArrayList<String> listeners = new ArrayList<String>();
// --------------------------------------------------------- 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
import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomcat.util.digester.Rule;
import org.apache.tomcat.util.digester.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