Clover coverage report - dom4j - 1.6.1
Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00
file stats: LOC: 306   Methods: 10
NCLOC: 159   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Mode.java 39,2% 47,3% 70% 45,1%
coverage coverage
 1    /*
 2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 3    *
 4    * This software is open source.
 5    * See the bottom of this file for the licence.
 6    */
 7   
 8    package org.dom4j.rule;
 9   
 10    import java.util.HashMap;
 11    import java.util.Map;
 12   
 13    import org.dom4j.Attribute;
 14    import org.dom4j.Document;
 15    import org.dom4j.Element;
 16    import org.dom4j.Node;
 17   
 18    /**
 19    * <p>
 20    * <code>Mode</code> manages a number of RuleSet instances for the mode in a
 21    * stylesheet. It is responsible for finding the correct rule for a given DOM4J
 22    * Node using the XSLT processing model uses the smallest possible RuleSet to
 23    * reduce the number of Rule evaluations.
 24    * </p>
 25    *
 26    * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
 27    * @version $Revision: 1.9 $
 28    */
 29    public class Mode {
 30    private RuleSet[] ruleSets = new RuleSet[Pattern.NUMBER_OF_TYPES];
 31   
 32    /** Map of exact (local) element names to RuleSet instances */
 33    private Map elementNameRuleSets;
 34   
 35    /** Map of exact (local) attribute names to RuleSet instances */
 36    private Map attributeNameRuleSets;
 37   
 38  4 public Mode() {
 39    }
 40   
 41    /**
 42    * Runs the actions associated with the given node
 43    *
 44    * @param node
 45    * DOCUMENT ME!
 46    *
 47    * @throws Exception
 48    * DOCUMENT ME!
 49    */
 50  30 public void fireRule(Node node) throws Exception {
 51  30 if (node != null) {
 52  30 Rule rule = getMatchingRule(node);
 53   
 54  30 if (rule != null) {
 55  28 Action action = rule.getAction();
 56   
 57  28 if (action != null) {
 58  28 action.run(node);
 59    }
 60    }
 61    }
 62    }
 63   
 64  5 public void applyTemplates(Element element) throws Exception {
 65  5 for (int i = 0, size = element.attributeCount(); i < size; i++) {
 66  1 Attribute attribute = element.attribute(i);
 67  1 fireRule(attribute);
 68    }
 69   
 70  5 for (int i = 0, size = element.nodeCount(); i < size; i++) {
 71  13 Node node = element.node(i);
 72  13 fireRule(node);
 73    }
 74    }
 75   
 76  1 public void applyTemplates(Document document) throws Exception {
 77  1 for (int i = 0, size = document.nodeCount(); i < size; i++) {
 78  1 Node node = document.node(i);
 79  1 fireRule(node);
 80    }
 81    }
 82   
 83  28 public void addRule(Rule rule) {
 84  28 int matchType = rule.getMatchType();
 85  28 String name = rule.getMatchesNodeName();
 86   
 87  28 if (name != null) {
 88  0 if (matchType == Node.ELEMENT_NODE) {
 89  0 elementNameRuleSets = addToNameMap(elementNameRuleSets, name,
 90    rule);
 91  0 } else if (matchType == Node.ATTRIBUTE_NODE) {
 92  0 attributeNameRuleSets = addToNameMap(attributeNameRuleSets,
 93    name, rule);
 94    }
 95    }
 96   
 97  28 if (matchType >= Pattern.NUMBER_OF_TYPES) {
 98  0 matchType = Pattern.ANY_NODE;
 99    }
 100   
 101  28 if (matchType == Pattern.ANY_NODE) {
 102    // add rule to all other RuleSets if they exist
 103  0 for (int i = 1, size = ruleSets.length; i < size; i++) {
 104  0 RuleSet ruleSet = ruleSets[i];
 105   
 106  0 if (ruleSet != null) {
 107  0 ruleSet.addRule(rule);
 108    }
 109    }
 110    }
 111   
 112  28 getRuleSet(matchType).addRule(rule);
 113    }
 114   
 115  0 public void removeRule(Rule rule) {
 116  0 int matchType = rule.getMatchType();
 117  0 String name = rule.getMatchesNodeName();
 118   
 119  0 if (name != null) {
 120  0 if (matchType == Node.ELEMENT_NODE) {
 121  0 removeFromNameMap(elementNameRuleSets, name, rule);
 122  0 } else if (matchType == Node.ATTRIBUTE_NODE) {
 123  0 removeFromNameMap(attributeNameRuleSets, name, rule);
 124    }
 125    }
 126   
 127  0 if (matchType >= Pattern.NUMBER_OF_TYPES) {
 128  0 matchType = Pattern.ANY_NODE;
 129    }
 130   
 131  0 getRuleSet(matchType).removeRule(rule);
 132   
 133  0 if (matchType != Pattern.ANY_NODE) {
 134  0 getRuleSet(Pattern.ANY_NODE).removeRule(rule);
 135    }
 136    }
 137   
 138    /**
 139    * Performs an XSLT processing model match for the rule which matches the
 140    * given Node the best.
 141    *
 142    * @param node
 143    * is the DOM4J Node to match against
 144    *
 145    * @return the matching Rule or no rule if none matched
 146    */
 147  30 public Rule getMatchingRule(Node node) {
 148  30 int matchType = node.getNodeType();
 149   
 150  30 if (matchType == Node.ELEMENT_NODE) {
 151  12 if (elementNameRuleSets != null) {
 152  0 String name = node.getName();
 153  0 RuleSet ruleSet = (RuleSet) elementNameRuleSets.get(name);
 154   
 155  0 if (ruleSet != null) {
 156  0 Rule answer = ruleSet.getMatchingRule(node);
 157   
 158  0 if (answer != null) {
 159  0 return answer;
 160    }
 161    }
 162    }
 163  18 } else if (matchType == Node.ATTRIBUTE_NODE) {
 164  1 if (attributeNameRuleSets != null) {
 165  0 String name = node.getName();
 166  0 RuleSet ruleSet = (RuleSet) attributeNameRuleSets.get(name);
 167   
 168  0 if (ruleSet != null) {
 169  0 Rule answer = ruleSet.getMatchingRule(node);
 170   
 171  0 if (answer != null) {
 172  0 return answer;
 173    }
 174    }
 175    }
 176    }
 177   
 178  30 if ((matchType < 0) || (matchType >= ruleSets.length)) {
 179  0 matchType = Pattern.ANY_NODE;
 180    }
 181   
 182  30 Rule answer = null;
 183  30 RuleSet ruleSet = ruleSets[matchType];
 184   
 185  30 if (ruleSet != null) {
 186    // try rules that match this kind of node first
 187  28 answer = ruleSet.getMatchingRule(node);
 188    }
 189   
 190  30 if ((answer == null) && (matchType != Pattern.ANY_NODE)) {
 191    // try general rules that match any kind of node
 192  2 ruleSet = ruleSets[Pattern.ANY_NODE];
 193   
 194  2 if (ruleSet != null) {
 195  0 answer = ruleSet.getMatchingRule(node);
 196    }
 197    }
 198   
 199  30 return answer;
 200    }
 201   
 202    /**
 203    * DOCUMENT ME!
 204    *
 205    * @param matchType
 206    * DOCUMENT ME!
 207    *
 208    * @return the RuleSet for the given matching type. This method will never
 209    * return null, a new instance will be created.
 210    */
 211  28 protected RuleSet getRuleSet(int matchType) {
 212  28 RuleSet ruleSet = ruleSets[matchType];
 213   
 214  28 if (ruleSet == null) {
 215  14 ruleSet = new RuleSet();
 216  14 ruleSets[matchType] = ruleSet;
 217   
 218    // add the patterns that match any node
 219  14 if (matchType != Pattern.ANY_NODE) {
 220  14 RuleSet allRules = ruleSets[Pattern.ANY_NODE];
 221   
 222  14 if (allRules != null) {
 223  0 ruleSet.addAll(allRules);
 224    }
 225    }
 226    }
 227   
 228  28 return ruleSet;
 229    }
 230   
 231    /**
 232    * Adds the Rule to a RuleSet for the given name.
 233    *
 234    * @param map
 235    * DOCUMENT ME!
 236    * @param name
 237    * DOCUMENT ME!
 238    * @param rule
 239    * DOCUMENT ME!
 240    *
 241    * @return the Map (which will be created if the given map was null
 242    */
 243  0 protected Map addToNameMap(Map map, String name, Rule rule) {
 244  0 if (map == null) {
 245  0 map = new HashMap();
 246    }
 247   
 248  0 RuleSet ruleSet = (RuleSet) map.get(name);
 249   
 250  0 if (ruleSet == null) {
 251  0 ruleSet = new RuleSet();
 252  0 map.put(name, ruleSet);
 253    }
 254   
 255  0 ruleSet.addRule(rule);
 256   
 257  0 return map;
 258    }
 259   
 260  0 protected void removeFromNameMap(Map map, String name, Rule rule) {
 261  0 if (map != null) {
 262  0 RuleSet ruleSet = (RuleSet) map.get(name);
 263   
 264  0 if (ruleSet != null) {
 265  0 ruleSet.removeRule(rule);
 266    }
 267    }
 268    }
 269    }
 270   
 271    /*
 272    * Redistribution and use of this software and associated documentation
 273    * ("Software"), with or without modification, are permitted provided that the
 274    * following conditions are met:
 275    *
 276    * 1. Redistributions of source code must retain copyright statements and
 277    * notices. Redistributions must also contain a copy of this document.
 278    *
 279    * 2. Redistributions in binary form must reproduce the above copyright notice,
 280    * this list of conditions and the following disclaimer in the documentation
 281    * and/or other materials provided with the distribution.
 282    *
 283    * 3. The name "DOM4J" must not be used to endorse or promote products derived
 284    * from this Software without prior written permission of MetaStuff, Ltd. For
 285    * written permission, please contact dom4j-info@metastuff.com.
 286    *
 287    * 4. Products derived from this Software may not be called "DOM4J" nor may
 288    * "DOM4J" appear in their names without prior written permission of MetaStuff,
 289    * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
 290    *
 291    * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
 292    *
 293    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
 294    * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 295    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 296    * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
 297    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 298    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 299    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 300    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 301    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 302    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 303    * POSSIBILITY OF SUCH DAMAGE.
 304    *
 305    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 306    */