1 16 package com.ibatis.common.beans; 17 18 import org.w3c.dom.CharacterData ; 19 import org.w3c.dom.*; 20 21 import java.io.PrintWriter ; 22 import java.io.StringWriter ; 23 import java.util.*; 24 25 28 public class DomProbe extends BaseProbe { 29 30 public String [] getReadablePropertyNames(Object 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 []) props.toArray(new String [props.size()]); 38 } 39 40 public String [] getWriteablePropertyNames(Object 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 []) props.toArray(new String [props.size()]); 48 } 49 50 public Class getPropertyTypeForSetter(Object object, String name) { 51 Element e = findNestedNodeByName(resolveElement(object), name, false); 52 try { 54 return Class.forName(e.getAttribute("type")); 55 } catch (ClassNotFoundException e1) { 56 return Object .class; 57 } 58 } 59 60 public Class getPropertyTypeForGetter(Object object, String name) { 61 Element e = findNestedNodeByName(resolveElement(object), name, false); 62 try { 64 return Class.forName(e.getAttribute("type")); 65 } catch (ClassNotFoundException e1) { 66 return Object .class; 67 } 68 } 69 70 public boolean hasWritableProperty(Object object, String propertyName) { 71 return findNestedNodeByName(resolveElement(object), propertyName, false) != null; 72 } 73 74 public boolean hasReadableProperty(Object object, String propertyName) { 75 return findNestedNodeByName(resolveElement(object), propertyName, false) != null; 76 } 77 78 public Object getObject(Object object, String name) { 79 Object 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 object, String name, Object 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 object, String property, Object value) { 95 Element element = findNodeByName(resolveElement(object), property, 0, true); 96 if (element != null) { 97 setElementValue(element, value); 98 } 99 } 100 101 protected Object getProperty(Object object, String property) { 102 Object 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 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 value) { 123 CharacterData 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 NodeList texts = prop.getChildNodes(); 151 if (texts.getLength() == 1) { 152 Node child = texts.item(0); 153 if (child instanceof CharacterData ) { 154 data = (CharacterData ) child; 156 } else { 157 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 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 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 183 } 184 185 private Object getElementValue(Element element) { 186 StringBuffer value = null; 187 188 Element prop = element; 189 190 if (prop != null) { 191 NodeList texts = prop.getChildNodes(); 193 if (texts.getLength() > 0) { 194 value = new StringBuffer (); 195 for (int i = 0; i < texts.getLength(); i++) { 196 Node text = texts.item(i); 197 if (text instanceof CharacterData ) { 198 value.append(((CharacterData ) text).getData()); 199 } 200 } 201 } 202 } 203 204 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 name, boolean create) { 216 Element child = element; 217 218 StringTokenizer parser = new StringTokenizer(name, ".", false); 219 while (parser.hasMoreTokens()) { 220 String childName = parser.nextToken(); 221 if (childName.indexOf("[") > -1) { 222 String 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 name, int index, boolean create) { 237 Element prop = null; 238 239 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 260 public static String nodeToString(Node node, String indent) { 261 StringWriter stringWriter = new StringWriter (); 262 PrintWriter printWriter = new PrintWriter (stringWriter); 263 264 switch (node.getNodeType()) { 265 266 case Node.DOCUMENT_NODE: 267 printWriter.println("<xml version=\"1.0\">\n"); 268 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 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 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 result = stringWriter.getBuffer().toString(); 307 printWriter.close(); 308 309 return result; 310 } 311 312 } 313 | Popular Tags |