Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 71813 invoked from network); 26 Jan 2011 16:03:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 26 Jan 2011 16:03:34 -0000 Received: (qmail 56819 invoked by uid 500); 26 Jan 2011 16:03:33 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 56462 invoked by uid 500); 26 Jan 2011 16:03:30 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 56455 invoked by uid 99); 26 Jan 2011 16:03:29 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Jan 2011 16:03:29 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Jan 2011 16:03:28 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id BDFF0238890B; Wed, 26 Jan 2011 16:03:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1063769 - in /commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules: ./ BaseRules.java Date: Wed, 26 Jan 2011 16:03:07 -0000 To: commits@commons.apache.org From: simonetripodi@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110126160307.BDFF0238890B@eris.apache.org> Author: simonetripodi Date: Wed Jan 26 16:03:07 2011 New Revision: 1063769 URL: http://svn.apache.org/viewvc?rev=1063769&view=rev Log: first checkin of BaseRules class, a polished version of RulesBase from proper digester /trunk Added: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/ commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java (with props) Added: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java URL: http://svn.apache.org/viewvc/commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java?rev=1063769&view=auto ============================================================================== --- commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java (added) +++ commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java Wed Jan 26 16:03:07 2011 @@ -0,0 +1,178 @@ +/* $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.digester3.rules; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.digester3.Rule; +import org.apache.commons.digester3.spi.Rules; + +/** + *

Default implementation of the {@code Rules} interface that supports + * the standard rule matching behavior. This class can also be used as a + * base class for specialized {@code Rules} implementations.

+ * + *

The matching policies implemented by this class support two different + * types of pattern matching rules:

+ *
    + *
  • Exact Match - A pattern "a/b/c" exactly matches a + * {@code <c>} element, nested inside a {@code <b>} + * element, which is nested inside an {@code <a>} element.
  • + *
  • Tail Match - A pattern "*/a/b" matches a + * {@code <b>} element, nested inside an {@code <a>} + * element, no matter how deeply the pair is nested.
  • + *
+ * + *

Note that wildcard patterns are ignored if an explicit match can be found + * (and when multiple wildcard patterns match, only the longest, ie most + * explicit, pattern is considered a match).

+ */ +public class BaseRules implements Rules { + + /** + * The set of registered Rule instances, keyed by the matching pattern. + * Each value is a List containing the Rules for that pattern, in the + * order that they were orginally registered. + */ + private Map> cache = new LinkedHashMap>(); + + /** + * The set of registered Rule instances, in the order that they were + * originally registered. + */ + private List rules = new ArrayList(); + + /** + * Register a new Rule instance matching the specified pattern. + * + * @param pattern Nesting pattern to be matched for this Rule + * @param rule Rule instance to be registered + */ + public void add(String pattern, Rule rule) { + // to help users who accidently add '/' to the end of their patterns + int patternLength = pattern.length(); + if (patternLength > 1 && pattern.endsWith("/")) { + pattern = pattern.substring(0, patternLength - 1); + } + + List list = this.cache.get(pattern); + if (list == null) { + list = new ArrayList(); + this.cache.put(pattern, list); + } + list.add(rule); + this.rules.add(rule); + } + + /** + * Clear all existing Rule instance registrations. + */ + public void clear() { + this.cache.clear(); + this.rules.clear(); + } + + /** + * {@inheritDoc} + */ + public List match(String namespaceURI, String pattern) { + List rulesList = lookup(namespaceURI, pattern); + if ((rulesList == null) || (rulesList.size() < 1)) { + // Find the longest key, ie more discriminant + String longKey = ""; + for (String key : this.cache.keySet()) { + if (key.startsWith("*/")) { + if (pattern.equals(key.substring(2)) + || pattern.endsWith(key.substring(1))) { + if (key.length() > longKey.length()) { + rulesList = lookup(namespaceURI, key); + longKey = key; + } + } + } + } + } + + if (rulesList == null) { + rulesList = new ArrayList(); + } + + return rulesList; + } + + /** + * {@inheritDoc} + */ + public List rules() { + return this.rules; + } + + /** + * Return a List of all registered patterns. + * + * @return A List of all registered patterns. + */ + protected Iterable patterns() { + return this.cache.keySet(); + } + + /** + * Return a List of Rule instances for the specified pattern. + * + * @param pattern Pattern to be matched + * @return The list of Rule instances for the specified pattern + */ + protected List lookup(String pattern) { + return this.cache.get(pattern); + } + + /** + * Return a List of Rule instances for the specified pattern that also + * match the specified namespace URI (if any). If there are no such + * rules, return {@code null}. + * + * @param namespaceURI Namespace URI to match, or {@code null} to + * select matching rules regardless of namespace URI + * @param pattern Pattern to be matched + * @return The list of Rule instances for the specified pattern + */ + private List lookup(String namespaceURI, String pattern) { + // Optimize when no namespace URI is specified + List list = this.cache.get(pattern); + if (list == null) { + return (null); + } + if ((namespaceURI == null) || (namespaceURI.length() == 0)) { + return (list); + } + + // Select only Rules that match on the specified namespace URI + ArrayList results = new ArrayList(); + for (Rule item : list) { + if ((namespaceURI.equals(item.getNamespaceURI())) + || (item.getNamespaceURI() == null)) { + results.add(item); + } + } + return results; + } + +} Propchange: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/sandbox/digester3/trunk/src/main/java/org/apache/commons/digester3/rules/BaseRules.java ------------------------------------------------------------------------------ svn:mime-type = text/plain