1 /*
2 Copyright (C) 2003 Together
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 package org.enhydra.xml;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 //import org.apache.xerces.parsers.DOMParser;
26 import org.w3c.dom.DOMException;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.NodeList;
30 import org.w3c.dom.Element;
31 import org.xml.sax.SAXException;
32
33 /***
34 * @author Tweety
35 *
36 * A class representing a node in a meta-data tree, which implements
37 * the <a href="../../../../api/org/w3c/dom/Element.html">
38 *
39 * <p> Namespaces are ignored in this implementation. The terms "tag
40 * name" and "node name" are always considered to be synonymous.
41 *
42 * @version 1.0
43 */
44 public class SearchElement extends HashMapElement {
45
46 public static String TAG_SEPARATOR = "/";
47 public static String ATTR_SEPARATOR = "@";
48 public static String EQUAL_SEPARATOR = "=";
49
50 /***
51 * Constructs an empty <code>SearchElement</code>.
52 */
53 public SearchElement() {
54 }
55
56 /***
57 * Constructs an <code>SearchElement</code> with a given document owner and node name.
58 *
59 * @param ownerDoc the document owner of the node, as a <code>Document</code>.
60 * @param name the name of the node, as a <code>String</code>.
61 */
62 public SearchElement(Document ownerDoc, String name) {
63 super(ownerDoc, name);
64 }
65
66 /***
67 * Constructs an <code>SearchElement</code> with a given <code>Node</code>.
68 *
69 * @param node <code>Node</code>.
70 */
71 public SearchElement(Node node) {
72 super(node);
73 }
74
75 /***
76 * Constructs an <code>SearchElement</code> with a given <code>SearchElement</code>.
77 *
78 * @param node <code>SearchElement</code>.
79 */
80 public SearchElement(SearchElement node) {
81 super((HashMapElement) node);
82 }
83
84 /***
85 * @return new <code>SearchElement</code> instance from a given <code>Node</code>.
86 *
87 * @param node <code>Node</code>.
88 */
89 protected Node newElementInstance(Node node) {
90 return new SearchElement(node);
91 }
92
93 /***
94 * Creates new instance of <code>SearchElement</code> from a given document
95 * as a <code>Document</code>.
96 *
97 * @param document document.
98 *
99 * @return new <code>SearchElement</code> node as a root of the <code>Document</code>.
100 */
101 public static Element newInstance(Document document) {
102 Node root = document.getDocumentElement();
103 return new SearchElement(root);
104 }
105
106 /***
107 * Returns a list of elements in the subtree of this node, with the given tag name.
108 *
109 * @param namePath relative path to the </code>Element</code> (through children).
110 *
111 * @return list of elements in the subtree of this node, with the given tag name.
112 */
113 public NodeList getSubElementsByTagName(String namePath) {
114 List list = new ArrayList();
115 getSubElementsByTagName(namePath, list);
116 return new NodeListImpl(list);
117 }
118
119 /*
120 * Recursively fullfills the <code>list</code> with all the nodes on the given path.
121 */
122 private void getSubElementsByTagName(String name, List list) {
123 // String[] keys = name.split(this.TAG_SEPARATOR, 2);
124 String[] keys = split(name, this.TAG_SEPARATOR);
125 if (keys.length == 1) {
126 List l = (List) this.children.get(name);
127 if (l != null)
128 list.addAll(l);
129 return;
130 }
131 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
132 if (tagChildren != null)
133 for (int i = 0; i < tagChildren.getLength(); i++)
134 ((SearchElement) tagChildren.item(i)).getSubElementsByTagName(
135 keys[1],
136 list);
137 }
138
139 /***
140 * Returns a list of <code>Element</code>s in the subtree of this node,
141 * which contain attribute with the given name and value.
142 *
143 * @param attrPath relative path to the attribute name.
144 * @param attrValue attribute value.
145 *
146 * @return list of <code>Element</code>s in the subtree of this node,
147 * which contain attribute with the given name and value.
148 */
149 public NodeList getSubElementsByAttrValue(String attrPath, String attrValue) {
150 // String[] keys = attrPath.split(this.ATTR_SEPARATOR, 2);
151 String[] keys = split(attrPath, this.ATTR_SEPARATOR);
152 if (keys.length != 2)
153 throw new DOMException(
154 DOMException.INVALID_ACCESS_ERR,
155 "Parameter not supported");
156 List list = new ArrayList();
157 getSubElementsByAttrValue(keys[0], keys[1], attrValue, list);
158 return new NodeListImpl(list);
159 }
160
161
162 /*
163 * Recursively fullfills the <code>list</code> with all the nodes in the given path.
164 */
165 private void getSubElementsByAttrValue(String tagName, String attrName, String attrValue, List list) {
166 // String[] keys = tagName.split(this.TAG_SEPARATOR, 2);
167 String[] keys = split(tagName, this.TAG_SEPARATOR);
168 if (keys.length == 1) {
169 List fList = (List) this.children.get(tagName);
170 if (fList != null) {
171 for (int i = 0; i < fList.size(); i++) {
172 Element elm = (Element) fList.get(i);
173 String val = (String) elm.getAttribute(attrName);
174 if (val != null)
175 if (val.equals(attrValue))
176 list.add(elm);
177 }
178 }
179 return;
180 }
181 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
182 if (tagChildren != null) {
183 for (int i = 0; i < tagChildren.getLength(); i++)
184 ((SearchElement) tagChildren.item(i)).getSubElementsByAttrValue(
185 keys[1],
186 attrName,
187 attrValue,
188 list);
189 }
190 }
191
192
193 /***
194 * Returns a list of <code>Element</code>s in the subtree of this node,
195 * with the given tag name and value.
196 *
197 * @param tagPath relative path to the tag name.
198 * @param tagValue <code>Element</code> value.
199 *
200 * @return list of <code>Element</code>s in the subtree of this node,
201 * with the given tag name and value.
202 */
203 public NodeList getSubElementsByTagText(String tagPath, String tagValue) {
204 List list = new ArrayList();
205 getSubElementsByTagText(tagPath, tagValue, list);
206 return new NodeListImpl(list);
207 }
208
209
210 /*
211 * Recursively fullfills the <code>list</code> with all the nodes in the given path.
212 * If there is no text node ( text node have value null , -e.g <tag></tag>), this can be matched if
213 * parameter tagValue have value "null".
214 */
215 private void getSubElementsByTagText(
216 String tagName,
217 String tagValue,
218 List list) {
219 // String[] keys = tagName.split(this.TAG_SEPARATOR, 2);
220 String[] keys = split(tagName, this.TAG_SEPARATOR);
221 if (keys.length == 1) {
222 List fList = (List) this.children.get(tagName);
223 if (fList != null) {
224 for (int i = 0; i < fList.size(); i++) {
225 HashMapElement elm = (HashMapElement) fList.get(i);
226 String val = (String) elm.getText();
227 if (val != null) {
228 if (val.equals(tagValue))
229 list.add(elm);
230 } else {
231 if ("null".equals(tagValue))
232 list.add(elm);
233 }
234 }
235 }
236 return;
237 }
238 NodeList tagChildren = this.getChildrenByTagName(keys[0]);
239 if (tagChildren != null) {
240 for (int i = 0; i < tagChildren.getLength(); i++)
241 ((SearchElement) tagChildren.item(i)).getSubElementsByTagText(
242 keys[1],
243 tagValue,
244 list);
245 }
246 }
247
248
249 /***
250 * Check that the node is either <code>null</code> or an
251 * <code>NodeImpl</code>.
252 *
253 * @exception DOMException if node is not an instance of <code>NodeImpl</code>.
254 */
255 // protected void checkNode(Node node) throws DOMException {
256 // if (node == null) {
257 // return;
258 // }
259 // if (!(node instanceof SearchElement))
260 // throw new NodeDOMException(DOMException.WRONG_DOCUMENT_ERR, "Node is not an instance of SearchElement!");
261 // }
262
263 /***
264 * Returns a list of <code>Element</code>s in the subtree of this node,
265 * that satisfy the given condition.
266 *
267 * @param condition condition.
268 *
269 * @return list of <code>Element</code>s in the subtree of this node,
270 * that satisfy the given condition.
271 */
272 public NodeList getSubElementsByCondition(String condition) {
273 //code below does not work with jdk1.3
274 // if (!condition.matches("([^@=]*)(@?[^@=/]*=[^@=/]*)"))
275 // throw new DOMException(
276 // DOMException.INVALID_ACCESS_ERR,
277 // "Parameter not supported");
278 // String[] keys = condition.split(this.EQUAL_SEPARATOR, 2);
279 String[] keys = split(condition, this.EQUAL_SEPARATOR);
280 String namePath = keys[0];
281 if (namePath.indexOf(ATTR_SEPARATOR) != -1)
282 return getSubElementsByAttrValue(namePath, keys[1]);
283 else
284 return getSubElementsByTagText(namePath, keys[1]);
285 }
286
287
288 /***
289 * Returns the first <code>Element</code> in the subtree of this node,
290 * that satisfy the given condition.
291 *
292 * @param condition condition.
293 *
294 * @return the first <code>Element</code> in the subtree of this node,
295 * that satisfy the given condition.
296 */
297 public Element getFirstSubElementsByCondition(String condition) {
298 NodeList nodes = getSubElementsByCondition(condition);
299 if (nodes != null && nodes.getLength() > 0)
300 return (Element) nodes.item(0);
301 return null;
302 }
303
304
305 /***
306 * Returns the first <code>Element</code> in the subtree of this node,
307 * with the given tag name.
308 *
309 * @param namePath relative path to the <code>Element</code>.
310 *
311 * @return the first <code>Element</code> in the subtree of this node,
312 * with the given tag name.
313 */
314 public Element getFirstSubElementByTagName(String namePath) {
315 NodeList nodes = getSubElementsByTagName(namePath);
316 if (nodes != null && nodes.getLength() > 0)
317 return (Element) nodes.item(0);
318 return null;
319 }
320
321
322 /***
323 * Return the text of the <code>Element</code> found on the given path.
324 *
325 * @param namePath relative path to the <code>Element</code> node.
326 *
327 * @return text of the <code>Element</code> found on the given path.
328 */
329 public String getText(String namePath) {
330 NodeList nodes = this.getSubElementsByTagName(namePath);
331 if (nodes != null && nodes.getLength() > 0)
332 return ((SearchElement) nodes.item(0)).getText();
333 return null;
334 }
335
336
337 /***
338 * Sets the given text to the <code>Element</code> found on the given path.
339 *
340 * @param namePath relative path to the <code>Element</code> node.
341 * @param text new text.
342 */
343 public void setText(String namePath, String text) {
344 NodeList nodes = this.getSubElementsByTagName(namePath);
345 if (nodes != null && nodes.getLength() > 0)
346 ((SearchElement) nodes.item(0)).setText(text);
347 }
348
349
350 /***
351 * Sets the value of an attribute found on the given path.
352 *
353 * @param namePath relative path to the attribute.
354 * @param value is new value.
355 */
356 public void setAttr(String namePath, String value) {
357 //code below does not work with jdk1.3
358 // if (!namePath.matches("([^@]*)(@[^@/]*)"))
359 // throw new DOMException(
360 // DOMException.INVALID_ACCESS_ERR,
361 // "Parameter not supported");
362 // String[] keys = namePath.split(this.ATTR_SEPARATOR, 2);
363 String[] keys = split(namePath, this.ATTR_SEPARATOR);
364
365 NodeList nodes = this.getSubElementsByTagName(keys[0]);
366 if (nodes != null && nodes.getLength() > 0)
367 ((SearchElement) nodes.item(0)).setAttribute(keys[1], value);
368 }
369
370 private String[] split(String toSeparate, String separator) {
371 String[] keys = new String[2];
372 int index = toSeparate.indexOf(separator);
373 if( index == -1 ) {
374 keys = new String[1];
375 keys[0] = toSeparate;
376 } else {
377 keys[0] = toSeparate.substring(0, index);
378 keys[1] = toSeparate.substring(index + 1, toSeparate.length());
379 }
380 return keys;
381 }
382
383 }
This page was automatically generated by Maven