KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > webharvest > definition > XmlNode


1 /* Copyright (c) 2006-2007, Vladimir Nikic
2     All rights reserved.
3
4     Redistribution and use of this software in source and binary forms,
5     with or without modification, are permitted provided that the following
6     conditions are met:
7
8     * Redistributions of source code must retain the above
9       copyright notice, this list of conditions and the
10       following disclaimer.
11
12     * Redistributions in binary form must reproduce the above
13       copyright notice, this list of conditions and the
14       following disclaimer in the documentation and/or other
15       materials provided with the distribution.
16
17     * The name of Web-Harvest may not be used to endorse or promote
18       products derived from this software without specific prior
19       written permission.
20
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31     POSSIBILITY OF SUCH DAMAGE.
32
33     You can contact Vladimir Nikic by sending e-mail to
34     nikic_vladimir@yahoo.com. Please include the word "Web-Harvest" in the
35     subject line.
36 */

37 package org.webharvest.definition;
38
39 import java.io.InputStream JavaDoc;
40 import java.util.*;
41
42 import org.apache.log4j.Logger;
43
44 public class XmlNode extends HashMap {
45
46     protected static final Logger log = Logger.getLogger(XmlNode.class);
47
48     private static final boolean IGNORE_NAMESPACE = true;
49     private static final boolean IGNORE_CASE = true;
50
51     // node name - correspondes to xml tag name
52
private String JavaDoc name;
53
54     // parent element
55
private XmlNode parent;
56
57     // map of attributes
58
private Map attributes = new HashMap();
59
60     // all subelements in the form of linear list
61
private List elementList = new ArrayList();
62
63     // text value
64
private String JavaDoc text;
65
66     /**
67      * Static method that creates node for specified input stream which
68      * contains XML data
69      * @param in
70      * @return XmlNode instance
71      */

72     public static XmlNode getInstance(InputStream JavaDoc in) {
73         return XmlParser.parse(in);
74     }
75
76     /**
77      * Constructor that defines name and connects to specified
78      * parent element.
79      * @param name
80      * @param parent
81      */

82     protected XmlNode(String JavaDoc name, XmlNode parent) {
83         super();
84
85         this.name = adaptName(name);
86         this.parent = parent;
87
88         if (parent != null) {
89             parent.addElement(this);
90         }
91     }
92
93     /**
94      * According to settings of this object changes element/attribute
95      * names to be namespace/case insensitive.
96      * @param s
97      * @return String
98      */

99     private String JavaDoc adaptName(String JavaDoc s) {
100         if (IGNORE_NAMESPACE) {
101             int index = s.indexOf(':');
102             if (index >= 0) {
103                 s = s.substring(index + 1);
104             }
105         }
106
107         if (IGNORE_CASE) {
108             s = s.toLowerCase();
109         }
110
111         return s;
112     }
113
114     /**
115      * @return Node name.
116      */

117     public String JavaDoc getName() {
118         return name;
119     }
120
121     /**
122      * @return Node text.
123      */

124     public String JavaDoc getText() {
125         return text;
126     }
127
128     /**
129      * @return Parent node or null if instance is root node.
130      */

131     public XmlNode getParent() {
132         return parent;
133     }
134
135     /**
136      * For specified serach path returns element/attribute if found,
137      * or null otherwise. Path is sequence of elements separated with
138      * some of characters: ./\[]
139      * For example: msg[0].response[0].id is trying to find in node
140      * first msg subelement and than first response subelement and then
141      * attribute id.
142      * @param key
143      * @return Resulting value which should be eather XmlNode instance or string.
144      */

145     private Object JavaDoc getSeq(String JavaDoc key) {
146         StringTokenizer strTkzr = new StringTokenizer(key, "./\\[]");
147         Object JavaDoc currValue = this;
148         while (strTkzr.hasMoreTokens()) {
149             String JavaDoc currKey = strTkzr.nextToken();
150             if (currValue instanceof Map) {
151                 currValue = ((Map)currValue).get(currKey);
152             } else if (currValue instanceof List) {
153                 try {
154                     List list = (List) currValue;
155                     int index = Integer.parseInt(currKey);
156
157                     if (index >= 0 && index < list.size()) {
158                         currValue = list.get(index);
159                     }
160                 } catch (NumberFormatException JavaDoc e) {
161                     return null;
162                 }
163             } else {
164                 return null;
165             }
166         }
167
168         return currValue;
169     }
170
171     /**
172      * Overriden get method - search both subelements and attributes
173      */

174     public Object JavaDoc get(Object JavaDoc key) {
175         if (key == null) {
176             return null;
177         }
178
179         if (IGNORE_CASE) {
180             key = ((String JavaDoc)key).toLowerCase();
181         }
182
183         String JavaDoc sKey = (String JavaDoc) key;
184
185         if ( sKey.indexOf('/') >= 0 || sKey.indexOf('.') >= 0 || sKey.indexOf('\\') >= 0 || sKey.indexOf('[') >= 0 ) {
186             return getSeq(sKey);
187         }
188
189         if (sKey.equalsIgnoreCase("_value")) {
190             return text;
191         } else if (this.containsKey(key)) {
192             return super.get(key);
193         } else {
194             return attributes.get(key);
195         }
196     }
197     
198     public String JavaDoc getString(Object JavaDoc key) {
199         return (String JavaDoc) get(key);
200     }
201
202     /**
203      * Adds new attribute with specified name and value.
204      * @param name
205      * @param value
206      */

207     public void addAttribute(String JavaDoc name, String JavaDoc value) {
208         attributes.put(adaptName(name), value);
209     }
210
211     public Map getAttributes() {
212         return this.attributes;
213     }
214     
215     public String JavaDoc getAttribute(String JavaDoc attName) {
216         return (String JavaDoc) this.attributes.get(attName);
217     }
218
219     /**
220      * Adds new subelement.
221      * @param elementNode
222      */

223     public void addElement(XmlNode elementNode) {
224         String JavaDoc elementName = elementNode.getName();
225
226         if (!this.containsKey(elementName)) {
227             this.put(elementName, new ArrayList());
228         }
229
230         ArrayList elementsForName = (ArrayList) this.get(elementName);
231         elementsForName.add(elementNode);
232
233         elementList.add(elementNode);
234     }
235
236     /**
237      * Adds new text to element list
238      * @param value
239      */

240     public void addElement(String JavaDoc value) {
241         elementList.add(value);
242     }
243
244
245     public Object JavaDoc getElement(String JavaDoc name) {
246         return super.get(name);
247     }
248
249     /**
250      * Sets node's text value.
251      * @param text
252      */

253     protected void setText(String JavaDoc text) {
254         this.text = text;
255     }
256
257     public List getElementList() {
258         return elementList;
259     }
260
261     /**
262      * Prints instance in treelike form to the default output.
263      * Useful for testing.
264      */

265     public void print() {
266         print(0);
267     }
268
269     private void print(int level) {
270         for (int i = 0; i < level; i++) {
271             System.out.print(" ");
272         }
273         System.out.print(name + ": " + attributes + ": TEXT = [" + text + "]\n");
274
275         Iterator it = elementList.iterator();
276         while (it.hasNext()) {
277             Object JavaDoc element = it.next();
278             if (element instanceof XmlNode) {
279                 XmlNode childNode = (XmlNode) element;
280                 childNode.print(level + 1);
281             } else {
282                 for (int i = 0; i <= level; i++) {
283                     System.out.print(" ");
284                 }
285                 System.out.println((String JavaDoc)element);
286             }
287         }
288     }
289
290 }
Popular Tags