|
|||||||||||||||||||
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 |
|
|