1 package org.enhydra.xml;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.List;
6
7 import org.apache.xerces.parsers.DOMParser;
8 import org.w3c.dom.DOMException;
9 import org.w3c.dom.Document;
10 import org.w3c.dom.Node;
11 import org.w3c.dom.NodeList;
12 import org.w3c.dom.Element;
13 import org.xml.sax.SAXException;
14
15 /***
16 * @author Tweety
17 *
18 * A class representing a node in a meta-data tree, which implements
19 * the <a href="../../../../api/org/w3c/dom/Element.html">
20 *
21 * <p> Namespaces are ignored in this implementation. The terms "tag
22 * name" and "node name" are always considered to be synonymous.
23 *
24 * @version 1.0
25 */
26 public class SearchElement extends HashMapElement {
27
28 public static String TAG_SEPARATOR = "/";
29 public static String ATTR_SEPARATOR = "@";
30 public static String EQUAL_SEPARATOR = "=";
31
32 /***
33 * Constructs an empty <code>SearchElement</code>.
34 */
35 public SearchElement() {
36 }
37
38 /***
39 * Constructs an <code>SearchElement</code> with a given document owner and node name.
40 *
41 * @param ownerDoc the document owner of the node, as a <code>Document</code>.
42 * @param name the name of the node, as a <code>String</code>.
43 */
44 public SearchElement(Document ownerDoc, String name) {
45 super(ownerDoc, name);
46 }
47
48 /***
49 * Constructs an <code>SearchElement</code> with a given <code>Node</code>.
50 *
51 * @param node <code>Node</code>.
52 */
53 public SearchElement(Node node) {
54 super(node);
55 }
56
57 /***
58 * Constructs an <code>SearchElement</code> with a given <code>SearchElement</code>.
59 *
60 * @param node <code>SearchElement</code>.
61 */
62 public SearchElement(SearchElement node) {
63 super((HashMapElement) node);
64 }
65
66 /***
67 * Returns new <code>SearchElement</code> instance from a given <code>Node</code>.
68 *
69 * @param node <code>Node</code>.
70 */
71 protected Node newElementInstance(Node node) {
72 return new SearchElement(node);
73 }
74
75 /***
76 * Creates new instance of <code>SearchElement</code> from a given document
77 * as a <code>Document</code>.
78 *
79 * @param document document.
80 *
81 * @return new <code>SearchElement</code> node as a root of the <code>Document</code>.
82 */
83 public static Element newInstance(Document document) {
84 Node root = document.getDocumentElement();
85 return new SearchElement(root);
86 }
87
88 /***
89 * Returns a list of elements in the subtree of this node, with the given tag name.
90 *
91 * @param namePath relative path to the </code>Element</code> (through children).
92 *
93 * @return list of elements in the subtree of this node, with the given tag name.
94 */
95 public NodeList getSubElementsByTagName(String namePath) {
96 List list = new ArrayList();
97 getSubElementsByTagName(namePath, list);
98 return new NodeListImpl(list);
99 }
100
101 /*
102 * Recursively fullfills the <code>list</code> with all the nodes on the given path.
103 */
104 private void getSubElementsByTagName(String name, List list) {
105 String[] keys = name.split(this.TAG_SEPARATOR, 2);
106 if (keys.length == 1) {
107 List l = (List) this.children.get(name);
108 if (l != null)
109 list.addAll(l);
110 return;
111 }
112 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
113 if (tagChildren != null)
114 for (int i = 0; i < tagChildren.getLength(); i++)
115 ((SearchElement) tagChildren.item(i)).getSubElementsByTagName(
116 keys[1],
117 list);
118 }
119
120 /***
121 * Returns a list of <code>Element</code>s in the subtree of this node,
122 * which contain attribute with the given name and value.
123 *
124 * @param attrPath relative path to the attribute name.
125 * @param attrValue attribute value.
126 *
127 * @return list of <code>Element</code>s in the subtree of this node,
128 * which contain attribute with the given name and value.
129 */
130 public NodeList getSubElementsByAttrValue(String attrPath, String attrValue) {
131 String[] keys = attrPath.split(this.ATTR_SEPARATOR, 2);
132 if (keys.length != 2)
133 throw new DOMException(
134 DOMException.INVALID_ACCESS_ERR,
135 "Parameter not supported");
136 List list = new ArrayList();
137 getSubElementsByAttrValue(keys[0], keys[1], attrValue, list);
138 return new NodeListImpl(list);
139 }
140
141
142 /*
143 * Recursively fullfills the <code>list</code> with all the nodes in the given path.
144 */
145 private void getSubElementsByAttrValue(String tagName, String attrName, String attrValue, List list) {
146 String[] keys = tagName.split(this.TAG_SEPARATOR, 2);
147 if (keys.length == 1) {
148 List fList = (List) this.children.get(tagName);
149 if (fList != null) {
150 for (int i = 0; i < fList.size(); i++) {
151 Element elm = (Element) fList.get(i);
152 String val = (String) elm.getAttribute(attrName);
153 if (val != null)
154 if (val.equals(attrValue))
155 list.add(elm);
156 }
157 }
158 return;
159 }
160 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
161 if (tagChildren != null) {
162 for (int i = 0; i < tagChildren.getLength(); i++)
163 ((SearchElement) tagChildren.item(i)).getSubElementsByAttrValue(
164 keys[1],
165 attrName,
166 attrValue,
167 list);
168 }
169 }
170
171
172 /***
173 * Returns a list of <code>Element</code>s in the subtree of this node,
174 * with the given tag name and value.
175 *
176 * @param tagPath relative path to the tag name.
177 * @param tagValue <code>Element</code> value.
178 *
179 * @return list of <code>Element</code>s in the subtree of this node,
180 * with the given tag name and value.
181 */
182 public NodeList getSubElementsByTagText(String tagPath, String tagValue) {
183 List list = new ArrayList();
184 getSubElementsByTagText(tagPath, tagValue, list);
185 return new NodeListImpl(list);
186 }
187
188
189 /*
190 * Recursively fullfills the <code>list</code> with all the nodes in the given path.
191 */
192 private void getSubElementsByTagText(
193 String tagName,
194 String tagValue,
195 List list) {
196 String[] keys = tagName.split(this.TAG_SEPARATOR, 2);
197 if (keys.length == 1) {
198 List fList = (List) this.children.get(tagName);
199 if (fList != null) {
200 for (int i = 0; i < fList.size(); i++) {
201 HashMapElement elm = (HashMapElement) fList.get(i);
202 String val = (String) elm.getText();
203 if (val != null)
204 if (val.equals(tagValue))
205 list.add(elm);
206 }
207 }
208 return;
209 }
210 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
211 if (tagChildren != null) {
212 for (int i = 0; i < tagChildren.getLength(); i++)
213 ((SearchElement) tagChildren.item(i)).getSubElementsByTagText(
214 keys[1],
215 tagValue,
216 list);
217 }
218 }
219
220
221 /***
222 * Returns a list of <code>Element</code>s in the subtree of this node,
223 * that satisfy the given condition.
224 *
225 * @param condition condition.
226 *
227 * @return list of <code>Element</code>s in the subtree of this node,
228 * that satisfy the given condition.
229 */
230 public NodeList getSubElementsByCondition(String condition) {
231 if (!condition.matches("([^@=]*)(@?[^@=/]*=[^@=/]*)"))
232 throw new DOMException(
233 DOMException.INVALID_ACCESS_ERR,
234 "Parameter not supported");
235 String[] keys = condition.split(this.EQUAL_SEPARATOR, 2);
236 String namePath = keys[0];
237 if (namePath.indexOf(ATTR_SEPARATOR) != -1)
238 return getSubElementsByAttrValue(namePath, keys[1]);
239 else
240 return getSubElementsByTagText(namePath, keys[1]);
241 }
242
243
244 /***
245 * Returns the first <code>Element</code> in the subtree of this node,
246 * that satisfy the given condition.
247 *
248 * @param condition condition.
249 *
250 * @return the first <code>Element</code> in the subtree of this node,
251 * that satisfy the given condition.
252 */
253 public Element getFirstSubElementsByCondition(String condition) {
254 NodeList nodes = getSubElementsByCondition(condition);
255 if (nodes != null && nodes.getLength() > 0)
256 return (Element) nodes.item(0);
257 return null;
258 }
259
260
261 /***
262 * Returns the first <code>Element</code> in the subtree of this node,
263 * with the given tag name.
264 *
265 * @param namePath relative path to the <code>Element</code>.
266 *
267 * @return the first <code>Element</code> in the subtree of this node,
268 * with the given tag name.
269 */
270 public Element getFirstSubElementByTagName(String namePath) {
271 NodeList nodes = getSubElementsByTagName(namePath);
272 if (nodes != null && nodes.getLength() > 0)
273 return (Element) nodes.item(0);
274 return null;
275 }
276
277
278 /***
279 * Return the text of the <code>Element</code> found on the given path.
280 *
281 * @param namePath relative path to the <code>Element</code> node.
282 *
283 * @return text of the <code>Element</code> found on the given path.
284 */
285 public String getText(String namePath) {
286 NodeList nodes = this.getSubElementsByTagName(namePath);
287 if (nodes != null && nodes.getLength() > 0)
288 return ((SearchElement) nodes.item(0)).getText();
289 return null;
290 }
291
292
293 /***
294 * Sets the given text to the <code>Element</code> found on the given path.
295 *
296 * @param namePath relative path to the <code>Element</code> node.
297 * @param text new text.
298 */
299 public void setText(String namePath, String text) {
300 NodeList nodes = this.getSubElementsByTagName(namePath);
301 if (nodes != null && nodes.getLength() > 0)
302 ((SearchElement) nodes.item(0)).setText(text);
303 }
304
305
306 /***
307 * Sets the value of an attribute found on the given path.
308 *
309 * @param namePath relative path to the attribute.
310 * @param text new value.
311 */
312 public void setAttr(String namePath, String value) {
313 if (!namePath.matches("([^@]*)(@[^@/]*)"))
314 throw new DOMException(
315 DOMException.INVALID_ACCESS_ERR,
316 "Parameter not supported");
317 String[] keys = namePath.split(this.ATTR_SEPARATOR, 2);
318
319 NodeList nodes = this.getSubElementsByTagName(keys[0]);
320 if (nodes != null && nodes.getLength() > 0)
321 ((SearchElement) nodes.item(0)).setAttribute(keys[1], value);
322 }
323
324
325 }
This page automatically generated by Maven