KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibatis > common > beans > DomProbe


1 /*
2  * Copyright 2004 Clinton Begin
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.ibatis.common.beans;
17
18 import org.w3c.dom.CharacterData JavaDoc;
19 import org.w3c.dom.*;
20
21 import java.io.PrintWriter JavaDoc;
22 import java.io.StringWriter JavaDoc;
23 import java.util.*;
24
25 /**
26  * A Probe implementation for working with DOM objects
27  */

28 public class DomProbe extends BaseProbe {
29
30   public String JavaDoc[] getReadablePropertyNames(Object JavaDoc object) {
31     List props = new ArrayList();
32     Element e = resolveElement(object);
33     NodeList nodes = e.getChildNodes();
34     for (int i = 0; i < nodes.getLength(); i++) {
35       props.add(nodes.item(i).getNodeName());
36     }
37     return (String JavaDoc[]) props.toArray(new String JavaDoc[props.size()]);
38   }
39
40   public String JavaDoc[] getWriteablePropertyNames(Object JavaDoc object) {
41     List props = new ArrayList();
42     Element e = resolveElement(object);
43     NodeList nodes = e.getChildNodes();
44     for (int i = 0; i < nodes.getLength(); i++) {
45       props.add(nodes.item(i).getNodeName());
46     }
47     return (String JavaDoc[]) props.toArray(new String JavaDoc[props.size()]);
48   }
49
50   public Class JavaDoc getPropertyTypeForSetter(Object JavaDoc object, String JavaDoc name) {
51     Element e = findNestedNodeByName(resolveElement(object), name, false);
52     //todo alias types, don't use exceptions like this
53
try {
54       return Class.forName(e.getAttribute("type"));
55     } catch (ClassNotFoundException JavaDoc e1) {
56       return Object JavaDoc.class;
57     }
58   }
59
60   public Class JavaDoc getPropertyTypeForGetter(Object JavaDoc object, String JavaDoc name) {
61     Element e = findNestedNodeByName(resolveElement(object), name, false);
62     //todo alias types, don't use exceptions like this
63
try {
64       return Class.forName(e.getAttribute("type"));
65     } catch (ClassNotFoundException JavaDoc e1) {
66       return Object JavaDoc.class;
67     }
68   }
69
70   public boolean hasWritableProperty(Object JavaDoc object, String JavaDoc propertyName) {
71     return findNestedNodeByName(resolveElement(object), propertyName, false) != null;
72   }
73
74   public boolean hasReadableProperty(Object JavaDoc object, String JavaDoc propertyName) {
75     return findNestedNodeByName(resolveElement(object), propertyName, false) != null;
76   }
77
78   public Object JavaDoc getObject(Object JavaDoc object, String JavaDoc name) {
79     Object JavaDoc value = null;
80     Element element = findNestedNodeByName(resolveElement(object), name, false);
81     if (element != null) {
82       value = getElementValue(element);
83     }
84     return value;
85   }
86
87   public void setObject(Object JavaDoc object, String JavaDoc name, Object JavaDoc value) {
88     Element element = findNestedNodeByName(resolveElement(object), name, true);
89     if (element != null) {
90       setElementValue(element, value);
91     }
92   }
93
94   protected void setProperty(Object JavaDoc object, String JavaDoc property, Object JavaDoc value) {
95     Element element = findNodeByName(resolveElement(object), property, 0, true);
96     if (element != null) {
97       setElementValue(element, value);
98     }
99   }
100
101   protected Object JavaDoc getProperty(Object JavaDoc object, String JavaDoc property) {
102     Object JavaDoc value = null;
103     Element element = findNodeByName(resolveElement(object), property, 0, false);
104     if (element != null) {
105       value = getElementValue(element);
106     }
107     return value;
108   }
109
110   private Element resolveElement(Object JavaDoc object) {
111     Element element = null;
112     if (object instanceof Document) {
113       element = (Element) ((Document) object).getLastChild();
114     } else if (object instanceof Element) {
115       element = (Element) object;
116     } else {
117       throw new ProbeException("An unknown object type was passed to DomProbe. Must be a Document.");
118     }
119     return element;
120   }
121
122   private void setElementValue(Element element, Object JavaDoc value) {
123     CharacterData JavaDoc data = null;
124
125     Element prop = element;
126
127     if (value instanceof Collection) {
128       Iterator items = ((Collection) value).iterator();
129       while (items.hasNext()) {
130         Document valdoc = (Document) items.next();
131         NodeList list = valdoc.getChildNodes();
132         for (int i = 0; i < list.getLength(); i++) {
133           Node newNode = element.getOwnerDocument().importNode(list.item(i), true);
134           element.appendChild(newNode);
135         }
136       }
137     } else if (value instanceof Document) {
138       Document valdoc = (Document) value;
139       Node lastChild = valdoc.getLastChild();
140       NodeList list = lastChild.getChildNodes();
141       for (int i = 0; i < list.getLength(); i++) {
142         Node newNode = element.getOwnerDocument().importNode(list.item(i), true);
143         element.appendChild(newNode);
144       }
145     } else if (value instanceof Element) {
146       Node newNode = element.getOwnerDocument().importNode((Element) value, true);
147       element.appendChild(newNode);
148     } else {
149       // Find text child element
150
NodeList texts = prop.getChildNodes();
151       if (texts.getLength() == 1) {
152         Node child = texts.item(0);
153         if (child instanceof CharacterData JavaDoc) {
154           // Use existing text.
155
data = (CharacterData JavaDoc) child;
156         } else {
157           // Remove non-text, add text.
158
prop.removeChild(child);
159           Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
160           prop.appendChild(text);
161           data = text;
162         }
163       } else if (texts.getLength() > 1) {
164         // Remove all, add text.
165
for (int i = texts.getLength() - 1; i >= 0; i--) {
166           prop.removeChild(texts.item(i));
167         }
168         Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
169         prop.appendChild(text);
170         data = text;
171       } else {
172         // Add text.
173
Text text = prop.getOwnerDocument().createTextNode(String.valueOf(value));
174         prop.appendChild(text);
175         data = text;
176       }
177       data.setData(String.valueOf(value));
178     }
179
180     // Set type attribute
181
//prop.setAttribute("type", value == null ? "null" : value.getClass().getName());
182

183   }
184
185   private Object JavaDoc getElementValue(Element element) {
186     StringBuffer JavaDoc value = null;
187
188     Element prop = element;
189
190     if (prop != null) {
191       // Find text child elements
192
NodeList texts = prop.getChildNodes();
193       if (texts.getLength() > 0) {
194         value = new StringBuffer JavaDoc();
195         for (int i = 0; i < texts.getLength(); i++) {
196           Node text = texts.item(i);
197           if (text instanceof CharacterData JavaDoc) {
198             value.append(((CharacterData JavaDoc) text).getData());
199           }
200         }
201       }
202     }
203
204     //convert to proper type
205
//value = convert(value.toString());
206

207     if (value == null) {
208       return null;
209     } else {
210       return String.valueOf(value);
211     }
212   }
213
214
215   private Element findNestedNodeByName(Element element, String JavaDoc name, boolean create) {
216     Element child = element;
217
218     StringTokenizer parser = new StringTokenizer(name, ".", false);
219     while (parser.hasMoreTokens()) {
220       String JavaDoc childName = parser.nextToken();
221       if (childName.indexOf("[") > -1) {
222         String JavaDoc propName = childName.substring(0, childName.indexOf("["));
223         int i = Integer.parseInt(childName.substring(childName.indexOf("[") + 1, childName.indexOf("]")));
224         child = findNodeByName(child, propName, i, create);
225       } else {
226         child = findNodeByName(child, childName, 0, create);
227       }
228       if (child == null) {
229         break;
230       }
231     }
232
233     return child;
234   }
235
236   private Element findNodeByName(Element element, String JavaDoc name, int index, boolean create) {
237     Element prop = null;
238
239     // Find named property element
240
NodeList propNodes = element.getElementsByTagName(name);
241     if (propNodes.getLength() > index) {
242       prop = (Element) propNodes.item(index);
243     } else {
244       if (create) {
245         for (int i = 0; i < index + 1; i++) {
246           prop = element.getOwnerDocument().createElement(name);
247           element.appendChild(prop);
248         }
249       }
250     }
251     return prop;
252   }
253
254   /**
255    * Converts a DOM node to a complete xml string
256    * @param node - the node to process
257    * @param indent - how to indent the children of the node
258    * @return The node as a String
259    */

260   public static String JavaDoc nodeToString(Node node, String JavaDoc indent) {
261     StringWriter JavaDoc stringWriter = new StringWriter JavaDoc();
262     PrintWriter JavaDoc printWriter = new PrintWriter JavaDoc(stringWriter);
263
264     switch (node.getNodeType()) {
265
266       case Node.DOCUMENT_NODE:
267         printWriter.println("<xml version=\"1.0\">\n");
268         // recurse on each child
269
NodeList nodes = node.getChildNodes();
270         if (nodes != null) {
271           for (int i = 0; i < nodes.getLength(); i++) {
272             printWriter.print(nodeToString(nodes.item(i), ""));
273           }
274         }
275         break;
276
277       case Node.ELEMENT_NODE:
278         String JavaDoc name = node.getNodeName();
279         printWriter.print(indent + "<" + name);
280         NamedNodeMap attributes = node.getAttributes();
281         for (int i = 0; i < attributes.getLength(); i++) {
282           Node current = attributes.item(i);
283           printWriter.print(" " + current.getNodeName() +
284               "=\"" + current.getNodeValue() +
285               "\"");
286         }
287         printWriter.print(">");
288
289         // recurse on each child
290
NodeList children = node.getChildNodes();
291         if (children != null) {
292           for (int i = 0; i < children.getLength(); i++) {
293             printWriter.print(nodeToString(children.item(i), indent + indent));
294           }
295         }
296
297         printWriter.print("</" + name + ">");
298         break;
299
300       case Node.TEXT_NODE:
301         printWriter.print(node.getNodeValue());
302         break;
303     }
304
305     printWriter.flush();
306     String JavaDoc result = stringWriter.getBuffer().toString();
307     printWriter.close();
308
309     return result;
310   }
311
312 }
313
Popular Tags