|
|||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| XMLObjectCache.java | 100% | 100% | 100% | 100% |
|
||||||||||||||
| 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 |
|
|
||||||||||