Coverage Report - com.jeantessier.dependency.NodeHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
NodeHandler
84%
104/123
87%
47/54
3.071
 
 1  
 /*
 2  
  *  Copyright (c) 2001-2009, Jean Tessier
 3  
  *  All rights reserved.
 4  
  *  
 5  
  *  Redistribution and use in source and binary forms, with or without
 6  
  *  modification, are permitted provided that the following conditions
 7  
  *  are met:
 8  
  *  
 9  
  *      * Redistributions of source code must retain the above copyright
 10  
  *        notice, this list of conditions and the following disclaimer.
 11  
  *  
 12  
  *      * Redistributions in binary form must reproduce the above copyright
 13  
  *        notice, this list of conditions and the following disclaimer in the
 14  
  *        documentation and/or other materials provided with the distribution.
 15  
  *  
 16  
  *      * Neither the name of Jean Tessier nor the names of his contributors
 17  
  *        may be used to endorse or promote products derived from this software
 18  
  *        without specific prior written permission.
 19  
  *  
 20  
  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21  
  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22  
  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23  
  *  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
 24  
  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 25  
  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 26  
  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 27  
  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 28  
  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 29  
  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 30  
  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31  
  */
 32  
 
 33  
 package com.jeantessier.dependency;
 34  
 
 35  
 import java.util.*;
 36  
 
 37  
 import org.apache.log4j.*;
 38  
 import org.xml.sax.*;
 39  
 import org.xml.sax.helpers.*;
 40  
 
 41  
 public class NodeHandler extends DefaultHandler {
 42  
     private static final int PACKAGE = 1;
 43  
     private static final int CLASS   = 2;
 44  
     private static final int FEATURE = 3;
 45  
 
 46  
     private NodeFactory  factory;
 47  
 
 48  
     private int          currentNodeType;
 49  
     private int          currentDependencyType;
 50  
     private Attributes   currentDependencyAttributes;
 51  
     private Node         currentNode;
 52  
     private Attributes   currentPackageAttributes;
 53  
     private Attributes   currentClassAttributes;
 54  
     private Attributes   currentFeatureAttributes;
 55  31
     private StringBuffer currentName = new StringBuffer();
 56  
 
 57  31
     private HashSet<DependencyListener> dependencyListeners = new HashSet<DependencyListener>();
 58  
 
 59  
     public NodeHandler() {
 60  30
         this(new NodeFactory());
 61  30
     }
 62  
 
 63  31
     public NodeHandler(NodeFactory factory) {
 64  31
         this.factory = factory;
 65  31
     }
 66  
 
 67  
     public NodeFactory getFactory() {
 68  301
         return factory;
 69  
     }
 70  
 
 71  
     public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
 72  137
         Logger.getLogger(getClass()).debug("qName = " + qName);
 73  
 
 74  204
         for (int i=0; i<atts.getLength(); i++) {
 75  67
             Logger.getLogger(getClass()).debug("    " + atts.getQName(i) + ": " + atts.getValue(i));
 76  
         }
 77  
 
 78  137
         currentName.delete(0, currentName.length());
 79  
 
 80  137
         if ("dependencies".equals(qName)) {
 81  29
             fireBeginSession();
 82  108
         } else if ("package".equals(qName)) {
 83  29
             currentNodeType = PACKAGE;
 84  29
             currentPackageAttributes = new AttributesImpl(atts);
 85  79
         } else if ("class".equals(qName)) {
 86  8
             currentNodeType = CLASS;
 87  8
             currentClassAttributes = new AttributesImpl(atts);
 88  71
         } else if ("feature".equals(qName)) {
 89  5
             currentNodeType = FEATURE;
 90  5
             currentFeatureAttributes = new AttributesImpl(atts);
 91  66
         } else if ("inbound".equals(qName) || "outbound".equals(qName)) {
 92  24
             if ("package".equals(atts.getValue("type"))) {
 93  8
                 currentDependencyType = PACKAGE;
 94  16
             } else if ("class".equals(atts.getValue("type"))) {
 95  8
                 currentDependencyType = CLASS;
 96  8
             } else if ("feature".equals(atts.getValue("type"))) {
 97  8
                 currentDependencyType = FEATURE;
 98  
             }
 99  24
             currentDependencyAttributes = new AttributesImpl(atts);
 100  
         }
 101  
 
 102  137
         Logger.getLogger(getClass()).debug("    current node type: " + currentNodeType);
 103  137
         Logger.getLogger(getClass()).debug("    current dependency type: " + currentDependencyType);
 104  137
     }
 105  
 
 106  
     public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
 107  137
         Logger.getLogger(getClass()).debug("qName = " + qName);
 108  
 
 109  137
         if ("dependencies".equals(qName)) {
 110  29
             fireEndSession();
 111  108
         } else if ("name".equals(qName)) {
 112  42
             Logger.getLogger(getClass()).debug("    Processing <name> tag:");
 113  42
             Logger.getLogger(getClass()).debug("        current name: " + currentName);
 114  42
             Logger.getLogger(getClass()).debug("        current node type: " + currentNodeType);
 115  
 
 116  42
             switch (currentNodeType) {
 117  
                 case PACKAGE:
 118  29
                     currentNode = getFactory().createPackage(currentName.toString(), isConfirmed(currentPackageAttributes));
 119  29
                     break;
 120  
                 case CLASS:
 121  8
                     currentNode = getFactory().createClass(currentName.toString(), isConfirmed(currentClassAttributes));
 122  8
                     fireBeginClass(currentNode.getName());
 123  8
                     break;
 124  
                 case FEATURE:
 125  5
                     currentNode = getFactory().createFeature(currentName.toString(), isConfirmed(currentFeatureAttributes));
 126  42
                     break;
 127  
             }
 128  66
         } else if ("outbound".equals(qName)) {
 129  12
             Logger.getLogger(getClass()).debug("    Processing <outbound> tag:");
 130  12
             Logger.getLogger(getClass()).debug("        current_name: " + currentName);
 131  12
             Logger.getLogger(getClass()).debug("        current_dependency_type: " + currentDependencyType);
 132  
 
 133  12
             Node other = null;
 134  12
             switch (currentDependencyType) {
 135  
                 case PACKAGE:
 136  4
                     other = getFactory().createPackage(currentName.toString(), isConfirmed(currentDependencyAttributes));
 137  4
                     break;
 138  
                 case CLASS:
 139  4
                     other = getFactory().createClass(currentName.toString(), isConfirmed(currentDependencyAttributes));
 140  4
                     break;
 141  
                 case FEATURE:
 142  4
                     other = getFactory().createFeature(currentName.toString(), isConfirmed(currentDependencyAttributes));
 143  
                     break;
 144  
             }
 145  12
             currentNode.addDependency(other);
 146  12
             fireDependency(currentNode, other);
 147  12
         } else if ("inbound".equals(qName)) {
 148  12
             Logger.getLogger(getClass()).debug("    Processing <inbound> tag:");
 149  12
             Logger.getLogger(getClass()).debug("        current_name: " + currentName);
 150  12
             Logger.getLogger(getClass()).debug("        current_dependency_type: " + currentDependencyType);
 151  
 
 152  12
             Node other = null;
 153  12
             switch (currentDependencyType) {
 154  
                 case PACKAGE:
 155  4
                     other = getFactory().createPackage(currentName.toString(), isConfirmed(currentDependencyAttributes));
 156  4
                     break;
 157  
                 case CLASS:
 158  4
                     other = getFactory().createClass(currentName.toString(), isConfirmed(currentDependencyAttributes));
 159  4
                     break;
 160  
                 case FEATURE:
 161  4
                     other = getFactory().createFeature(currentName.toString(), isConfirmed(currentDependencyAttributes));
 162  
                     break;
 163  
             }
 164  12
             other.addDependency(currentNode);
 165  12
             fireDependency(other, currentNode);
 166  
         }
 167  137
     }
 168  
 
 169  
     public void characters(char[] ch, int start, int length) throws SAXException {
 170  91
         currentName.append(ch, start, length);
 171  91
         Logger.getLogger(getClass()).debug("characters: \"" + new String(ch, start, length) + "\"");
 172  91
     }
 173  
 
 174  
     public void addDependencyListener(DependencyListener listener) {
 175  0
         synchronized(dependencyListeners) {
 176  0
             dependencyListeners.add(listener);
 177  0
         }
 178  0
     }
 179  
 
 180  
     public void removeDependencyListener(DependencyListener listener) {
 181  0
         synchronized(dependencyListeners) {
 182  0
             dependencyListeners.remove(listener);
 183  0
         }
 184  0
     }
 185  
 
 186  
     protected void fireBeginSession() {
 187  29
         DependencyEvent event = new DependencyEvent(this);
 188  
 
 189  
         HashSet<DependencyListener> listeners;
 190  29
         synchronized(dependencyListeners) {
 191  29
             listeners = (HashSet<DependencyListener>) dependencyListeners.clone();
 192  29
         }
 193  
 
 194  29
         for (DependencyListener listener : listeners) {
 195  0
             listener.beginSession(event);
 196  
         }
 197  29
     }
 198  
     
 199  
     protected void fireBeginClass(String classname) {
 200  8
         DependencyEvent event = new DependencyEvent(this, classname);
 201  
 
 202  
         HashSet<DependencyListener> listeners;
 203  8
         synchronized(dependencyListeners) {
 204  8
             listeners = (HashSet<DependencyListener>) dependencyListeners.clone();
 205  8
         }
 206  
 
 207  8
         for (DependencyListener listener : listeners) {
 208  0
             listener.beginClass(event);
 209  
         }
 210  8
     }
 211  
 
 212  
     protected void fireDependency(Node dependent, Node dependable) {
 213  24
         DependencyEvent event = new DependencyEvent(this, dependent, dependable);
 214  
 
 215  
         HashSet<DependencyListener> listeners;
 216  24
         synchronized(dependencyListeners) {
 217  24
             listeners = (HashSet<DependencyListener>) dependencyListeners.clone();
 218  24
         }
 219  
 
 220  24
         for (DependencyListener listener : listeners) {
 221  0
             listener.dependency(event);
 222  
         }
 223  24
     }
 224  
 
 225  
     protected void fireEndClass(String classname) {
 226  0
         DependencyEvent event = new DependencyEvent(this, classname);
 227  
 
 228  
         HashSet<DependencyListener> listeners;
 229  0
         synchronized(dependencyListeners) {
 230  0
             listeners = (HashSet<DependencyListener>) dependencyListeners.clone();
 231  0
         }
 232  
 
 233  0
         for (DependencyListener listener : listeners) {
 234  0
             listener.endClass(event);
 235  
         }
 236  0
     }
 237  
 
 238  
     protected void fireEndSession() {
 239  29
         DependencyEvent event = new DependencyEvent(this);
 240  
 
 241  
         HashSet<DependencyListener> listeners;
 242  29
         synchronized(dependencyListeners) {
 243  29
             listeners = (HashSet<DependencyListener>) dependencyListeners.clone();
 244  29
         }
 245  
 
 246  29
         for (DependencyListener listener : listeners) {
 247  0
             listener.endSession(event);
 248  
         }
 249  29
     }
 250  
 
 251  
     private boolean isConfirmed(Attributes atts) {
 252  66
         return atts.getValue("confirmed") == null || "yes".equalsIgnoreCase(atts.getValue("confirmed"));
 253  
     }
 254  
 }