Clover coverage report - JFCUnit Test Coverage
Coverage timestamp: Mon Dec 20 2004 23:38:10 MST
file stats: LOC: 238   Methods: 10
NCLOC: 122   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XMLObjectCache.java 100% 100% 100% 100%
coverage
 1   
 package junit.extensions.xml;
 2   
 
 3   
 import java.util.HashMap;
 4   
 import java.util.Iterator;
 5   
 import java.util.Map;
 6   
 import java.util.Vector;
 7   
 
 8   
 
 9   
 /**
 10   
  * <p>Title: XMLObjectCache</p>
 11   
  * <p>Description: Multi level hashmap to contain
 12   
  * name value pairs. A parent level can be explicitly
 13   
  * accessed by prefixing the name with "../"
 14   
  * otherwise the parent level will only be searched
 15   
  * if the object does not exist at the current level. </p>
 16   
  * <p>Copyright: Copyright (c) 2003</p>
 17   
  * <p>Company: jfcunit project</p>
 18   
  * @author Kevin Wilson
 19   
  * @version 1.0
 20   
  */
 21   
 public class XMLObjectCache {
 22   
     /**
 23   
      * Internal hashmap used to hold the property/procedure mappings.
 24   
      */
 25   
     private final HashMap m_map = new HashMap();
 26   
 
 27   
     /**
 28   
      * The parent XMLObjectCache.
 29   
      */
 30   
     private XMLObjectCache m_parent;
 31   
 
 32   
     /**
 33   
      * Empty contructor. Parent is assumed to be null. It can be
 34   
      * set at a later time.
 35   
      */
 36  2112
     public XMLObjectCache() {
 37  2112
         this(null);
 38   
     }
 39   
 
 40   
     /**
 41   
      * Constructor.
 42   
      * @param parent Parent object cache to be set.
 43   
      */
 44  2900
     public XMLObjectCache(final XMLObjectCache parent) {
 45  2900
         setParent(parent);
 46   
     }
 47   
 
 48   
     /**
 49   
      * Do a reverse lookup of a mapping.
 50   
      * Return the name of a object based upon the value.
 51   
      * @param value Value to return the name for.
 52   
      * @return The first matching name is returned.
 53   
      */
 54  5
     public final String getName(final Object value) {
 55  5
         String ret = null;
 56   
 
 57  5
         if (m_map.containsValue(value)) {
 58  3
             Iterator entries = m_map.entrySet().iterator();
 59   
 
 60  3
             while (entries.hasNext() && (ret == null)) {
 61  6
                 Map.Entry entry = (Map.Entry) entries.next();
 62   
 
 63  6
                 if (entry.getValue().equals(value)) {
 64  3
                     ret = (String) entry.getKey();
 65   
                 }
 66   
             }
 67   
         }
 68   
 
 69  5
         if ((m_parent != null) && (ret == null)) {
 70  1
             ret = m_parent.getName(value);
 71   
         }
 72   
 
 73  5
         return ret;
 74   
     }
 75   
 
 76   
     /**
 77   
      * Get all of the names of the objects currently
 78   
      * in the cache. Parent objects will be prefixed
 79   
      * with the ../
 80   
      *
 81   
      * @return list of names.
 82   
      */
 83  14
     public final String[] getNames() {
 84  14
         int      size        = m_map.size();
 85  14
         int      parentSize  = 0;
 86  14
         String[] parentNames;
 87   
 
 88  14
         if (m_parent == null) {
 89  9
             parentNames = new String[0];
 90   
         } else {
 91  5
             parentNames = m_parent.getNames();
 92   
         }
 93   
 
 94  14
         String[] names = new String[parentNames.length + size];
 95  14
         int      idx  = 0;
 96  14
         Iterator keys = m_map.keySet().iterator();
 97   
 
 98  14
         while (keys.hasNext()) {
 99  13
             names[idx++] = (String) keys.next();
 100   
         }
 101   
 
 102  14
         for (int i = 0; i < parentNames.length; i++) {
 103  3
             names[idx++] = "../" + parentNames[i];
 104   
         }
 105   
 
 106  14
         return names;
 107   
     }
 108   
 
 109   
     /**
 110   
      * Set the parent object cache.
 111   
      * @param parent Parent object cache to be traversed by
 112   
      * get and explicitly traversed by put/remove.
 113   
      */
 114  4662
     public final void setParent(final XMLObjectCache parent) {
 115   
         // Move any pre-existing keys that have been
 116   
         // defined at the parent level before the parent
 117   
         // was set to the parents cache.
 118  4662
         if ((parent != null) && (m_map.size() > 0)) {
 119   
             // Move keys with ../ prefix to parent.
 120  1
             Vector   moves = new Vector();
 121  1
             Iterator iter = m_map.keySet().iterator();
 122   
 
 123  1
             while (iter.hasNext()) {
 124  2
                 String key = (String) iter.next();
 125   
 
 126  2
                 if (key.startsWith("../")) {
 127  1
                     moves.add(key);
 128   
                 }
 129   
             }
 130   
 
 131  1
             iter = moves.iterator();
 132   
 
 133  1
             while (iter.hasNext()) {
 134  1
                 String key   = (String) iter.next();
 135  1
                 Object value = m_map.remove(key);
 136  1
                 key = key.substring(3);
 137  1
                 parent.put(key, value);
 138   
             }
 139   
         }
 140   
 
 141  4662
         m_parent = parent;
 142   
     }
 143   
 
 144   
     /**
 145   
      * Get the parent object cache.
 146   
      * @return Parent object cache.
 147   
      */
 148  2
     public final XMLObjectCache getParent() {
 149  2
         return m_parent;
 150   
     }
 151   
 
 152   
     /**
 153   
      * Clear the cache.
 154   
      */
 155  81
     public final void clear() {
 156  81
         m_map.clear();
 157   
     }
 158   
 
 159   
     /**
 160   
      * Put a new mapping into the cache. If the
 161   
      * name starts with ../ then place the object
 162   
      * in the parent cache.
 163   
      *
 164   
      * @param name Name of the property or procedure.
 165   
      * @param value Value of the property or procedure.
 166   
      */
 167  341
     public final void put(final String name, final Object value) {
 168   
         // Navigate up a level
 169  341
         if ((m_parent != null) && name.startsWith("../")) {
 170  4
             m_parent.put(
 171   
                 name.substring(3),
 172   
                 value);
 173   
 
 174  4
             return;
 175   
         }
 176   
 
 177  337
         if (name.startsWith("./")) {
 178  1
             m_map.put(
 179   
                 name.substring(2),
 180   
                 value);
 181   
         } else {
 182  336
             m_map.put(name, value);
 183   
         }
 184   
     }
 185   
 
 186   
     /**
 187   
      * Remove the object from the cache.
 188   
      * If the name starts with ../ then propagate the
 189   
      * remove to the parent.
 190   
      *
 191   
      * @param name Name of the object in the cache.
 192   
      */
 193  47
     public final void remove(final String name) {
 194  47
         if ((m_parent != null) && name.startsWith("../")) {
 195  1
             m_parent.remove(name.substring(3));
 196   
         }
 197   
 
 198  47
         if (name.startsWith("./")) {
 199  1
             m_map.remove(name.substring(2));
 200   
         } else {
 201  46
             m_map.remove(name);
 202   
         }
 203   
     }
 204   
 
 205   
     /**
 206   
      * Get a object from the cache. If the object does not
 207   
      * exist in the cache then try the parent cache. If a parent
 208   
      * cache does not exist then try the System properties.
 209   
      * @param name Name of the value to be retrieved.
 210   
      * @return Return the value.
 211   
      */
 212  8474
     public Object get(final String name) {
 213  8474
         if ((name != null) && (m_parent != null) && name.startsWith("../")) {
 214  3
             return m_parent.get(name.substring(3));
 215   
         }
 216   
 
 217  8471
         boolean searchParent = true;
 218  8471
         Object  object;
 219   
 
 220  8471
         if ((name != null) && name.startsWith("./")) {
 221  2
             object           = m_map.get(name.substring(2));
 222  2
             searchParent     = false;
 223   
         } else {
 224  8469
             object = m_map.get(name);
 225   
         }
 226   
 
 227  8471
         if ((object != null) || !searchParent) {
 228  606
             return object;
 229   
         }
 230   
 
 231  7865
         if (m_parent != null) {
 232  3570
             return m_parent.get(name);
 233   
         }
 234   
 
 235  4295
         return null;
 236   
     }
 237   
 }
 238