1
2
3
4
5
6
7
8 package org.dom4j.util;
9
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.Iterator;
13 import java.util.List;
14 import java.util.Map;
15
16 import org.dom4j.Attribute;
17 import org.dom4j.Element;
18 import org.dom4j.Node;
19 import org.dom4j.QName;
20 import org.dom4j.tree.BackedList;
21 import org.dom4j.tree.DefaultElement;
22
23 /***
24 * <p>
25 * <code>IndexedElement</code> is an implementation of {@link Element}which
26 * maintains an index of the attributes and elements it contains to optimise
27 * lookups via name.
28 * </p>
29 *
30 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
31 * @version $Revision: 1.10 $
32 */
33 public class IndexedElement extends DefaultElement {
34 /*** Lazily constructed index for elements */
35 private Map elementIndex;
36
37 /*** Lazily constructed index for attributes */
38 private Map attributeIndex;
39
40 public IndexedElement(String name) {
41 super(name);
42 }
43
44 public IndexedElement(QName qname) {
45 super(qname);
46 }
47
48 public IndexedElement(QName qname, int attributeCount) {
49 super(qname, attributeCount);
50 }
51
52 public Attribute attribute(String name) {
53 return (Attribute) attributeIndex().get(name);
54 }
55
56 public Attribute attribute(QName qName) {
57 return (Attribute) attributeIndex().get(qName);
58 }
59
60 public Element element(String name) {
61 return asElement(elementIndex().get(name));
62 }
63
64 public Element element(QName qName) {
65 return asElement(elementIndex().get(qName));
66 }
67
68 public List elements(String name) {
69 return asElementList(elementIndex().get(name));
70 }
71
72 public List elements(QName qName) {
73 return asElementList(elementIndex().get(qName));
74 }
75
76
77
78 protected Element asElement(Object object) {
79 if (object instanceof Element) {
80 return (Element) object;
81 } else if (object != null) {
82 List list = (List) object;
83
84 if (list.size() >= 1) {
85 return (Element) list.get(0);
86 }
87 }
88
89 return null;
90 }
91
92 protected List asElementList(Object object) {
93 if (object instanceof Element) {
94 return createSingleResultList(object);
95 } else if (object != null) {
96 List list = (List) object;
97 BackedList answer = createResultList();
98
99 for (int i = 0, size = list.size(); i < size; i++) {
100 answer.addLocal(list.get(i));
101 }
102
103 return answer;
104 }
105
106 return createEmptyList();
107 }
108
109 /***
110 * DOCUMENT ME!
111 *
112 * @param object
113 * DOCUMENT ME!
114 *
115 * @return DOCUMENT ME!
116 *
117 * @deprecated WILL BE REMOVED IN dom4j-1.6 !!
118 */
119 protected Iterator asElementIterator(Object object) {
120 return asElementList(object).iterator();
121 }
122
123
124 protected void addNode(Node node) {
125 super.addNode(node);
126
127 if ((elementIndex != null) && node instanceof Element) {
128 addToElementIndex((Element) node);
129 } else if ((attributeIndex != null) && node instanceof Attribute) {
130 addToAttributeIndex((Attribute) node);
131 }
132 }
133
134 protected boolean removeNode(Node node) {
135 if (super.removeNode(node)) {
136 if ((elementIndex != null) && node instanceof Element) {
137 removeFromElementIndex((Element) node);
138 } else if ((attributeIndex != null) && node instanceof Attribute) {
139 removeFromAttributeIndex((Attribute) node);
140 }
141
142 return true;
143 }
144
145 return false;
146 }
147
148 protected Map attributeIndex() {
149 if (attributeIndex == null) {
150 attributeIndex = createAttributeIndex();
151
152 for (Iterator iter = attributeIterator(); iter.hasNext();) {
153 addToAttributeIndex((Attribute) iter.next());
154 }
155 }
156
157 return attributeIndex;
158 }
159
160 protected Map elementIndex() {
161 if (elementIndex == null) {
162 elementIndex = createElementIndex();
163
164 for (Iterator iter = elementIterator(); iter.hasNext();) {
165 addToElementIndex((Element) iter.next());
166 }
167 }
168
169 return elementIndex;
170 }
171
172 /***
173 * A Factory Method to create the index for attributes
174 *
175 * @return DOCUMENT ME!
176 */
177 protected Map createAttributeIndex() {
178 Map answer = createIndex();
179
180 return answer;
181 }
182
183 /***
184 * A Factory Method to create the index for elements
185 *
186 * @return DOCUMENT ME!
187 */
188 protected Map createElementIndex() {
189 Map answer = createIndex();
190
191 return answer;
192 }
193
194 protected void addToElementIndex(Element element) {
195 QName qName = element.getQName();
196 String name = qName.getName();
197 addToElementIndex(qName, element);
198 addToElementIndex(name, element);
199 }
200
201 protected void addToElementIndex(Object key, Element value) {
202 Object oldValue = elementIndex.get(key);
203
204 if (oldValue == null) {
205 elementIndex.put(key, value);
206 } else {
207 if (oldValue instanceof List) {
208 List list = (List) oldValue;
209 list.add(value);
210 } else {
211 List list = createList();
212 list.add(oldValue);
213 list.add(value);
214 elementIndex.put(key, list);
215 }
216 }
217 }
218
219 protected void removeFromElementIndex(Element element) {
220 QName qName = element.getQName();
221 String name = qName.getName();
222 removeFromElementIndex(qName, element);
223 removeFromElementIndex(name, element);
224 }
225
226 protected void removeFromElementIndex(Object key, Element value) {
227 Object oldValue = elementIndex.get(key);
228
229 if (oldValue instanceof List) {
230 List list = (List) oldValue;
231 list.remove(value);
232 } else {
233 elementIndex.remove(key);
234 }
235 }
236
237 protected void addToAttributeIndex(Attribute attribute) {
238 QName qName = attribute.getQName();
239 String name = qName.getName();
240 addToAttributeIndex(qName, attribute);
241 addToAttributeIndex(name, attribute);
242 }
243
244 protected void addToAttributeIndex(Object key, Attribute value) {
245 Object oldValue = attributeIndex.get(key);
246
247 if (oldValue != null) {
248 attributeIndex.put(key, value);
249 }
250 }
251
252 protected void removeFromAttributeIndex(Attribute attribute) {
253 QName qName = attribute.getQName();
254 String name = qName.getName();
255 removeFromAttributeIndex(qName, attribute);
256 removeFromAttributeIndex(name, attribute);
257 }
258
259 protected void removeFromAttributeIndex(Object key, Attribute value) {
260 Object oldValue = attributeIndex.get(key);
261
262 if ((oldValue != null) && oldValue.equals(value)) {
263 attributeIndex.remove(key);
264 }
265 }
266
267 /***
268 * Factory method to return a new map implementation for indices
269 *
270 * @return DOCUMENT ME!
271 */
272 protected Map createIndex() {
273 return new HashMap();
274 }
275
276 /***
277 * Factory method to return a list implementation for indices
278 *
279 * @return DOCUMENT ME!
280 */
281 protected List createList() {
282 return new ArrayList();
283 }
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321