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