1 16 19 20 21 package com.sun.org.apache.xpath.internal.domapi; 22 23 import javax.xml.transform.TransformerException ; 24 25 import com.sun.org.apache.xpath.internal.XPath; 26 import com.sun.org.apache.xpath.internal.objects.XObject; 27 import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; 28 import com.sun.org.apache.xpath.internal.res.XPATHMessages; 29 import org.w3c.dom.DOMException ; 30 import org.w3c.dom.Node ; 31 import org.w3c.dom.NodeList ; 32 import org.w3c.dom.events.Event ; 33 import org.w3c.dom.events.EventListener ; 34 import org.w3c.dom.events.EventTarget ; 35 import org.w3c.dom.traversal.NodeIterator; 36 import org.w3c.dom.xpath.XPathException; 37 import org.w3c.dom.xpath.XPathResult; 38 39 59 class XPathResultImpl implements XPathResult, EventListener { 60 61 64 final private XObject m_resultObj; 65 66 69 final private XPath m_xpath; 70 71 75 final private short m_resultType; 76 77 private boolean m_isInvalidIteratorState = false; 78 79 83 final private Node m_contextNode; 84 85 88 private NodeIterator m_iterator = null;; 89 90 93 private NodeList m_list = null; 94 95 96 101 XPathResultImpl(short type, XObject result, Node contextNode, XPath xpath) { 102 if (!isValidType(type)) { 104 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_INVALID_XPATH_TYPE, new Object [] {new Integer (type)}); 105 throw new XPathException(XPathException.TYPE_ERR,fmsg); } 107 108 if (null == result) { 110 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_EMPTY_XPATH_RESULT, null); 111 throw new XPathException(XPathException.INVALID_EXPRESSION_ERR,fmsg); } 113 114 this.m_resultObj = result; 115 this.m_contextNode = contextNode; 116 this.m_xpath = xpath; 117 118 if (type == ANY_TYPE) { 120 this.m_resultType = getTypeFromXObject(result); 121 } else { 122 this.m_resultType = type; 123 } 124 125 if (((m_resultType == XPathResult.ORDERED_NODE_ITERATOR_TYPE) || 128 (m_resultType == XPathResult.UNORDERED_NODE_ITERATOR_TYPE))) { 129 addEventListener(); 130 131 } 133 if ((m_resultType == ORDERED_NODE_ITERATOR_TYPE) || 135 (m_resultType == UNORDERED_NODE_ITERATOR_TYPE) || 136 (m_resultType == ANY_UNORDERED_NODE_TYPE) || 137 (m_resultType == FIRST_ORDERED_NODE_TYPE)) { 138 139 try { 140 m_iterator = m_resultObj.nodeset(); 141 } catch (TransformerException te) { 142 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object [] {m_xpath.getPatternString(), getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); 144 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 146 147 154 } else if ((m_resultType == UNORDERED_NODE_SNAPSHOT_TYPE) || 156 (m_resultType == ORDERED_NODE_SNAPSHOT_TYPE)) { 157 try { 158 m_list = m_resultObj.nodelist(); 159 } catch (TransformerException te) { 160 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object [] {m_xpath.getPatternString(), getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); 162 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 164 } 165 } 166 167 170 public short getResultType() { 171 return m_resultType; 172 } 173 174 181 public double getNumberValue() throws XPathException { 182 if (getResultType() != NUMBER_TYPE) { 183 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_XPATHRESULTTYPE_TO_NUMBER, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 184 throw new XPathException(XPathException.TYPE_ERR,fmsg); 185 } else { 187 try { 188 return m_resultObj.num(); 189 } catch (Exception e) { 190 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 192 } 193 } 194 } 195 196 204 public String getStringValue() throws XPathException { 205 if (getResultType() != STRING_TYPE) { 206 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_STRING, new Object [] {m_xpath.getPatternString(), m_resultObj.getTypeString()}); 207 throw new XPathException(XPathException.TYPE_ERR,fmsg); 208 } else { 210 try { 211 return m_resultObj.str(); 212 } catch (Exception e) { 213 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 215 } 216 } 217 } 218 219 222 public boolean getBooleanValue() throws XPathException { 223 if (getResultType() != BOOLEAN_TYPE) { 224 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_BOOLEAN, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 225 throw new XPathException(XPathException.TYPE_ERR,fmsg); 226 } else { 228 try { 229 return m_resultObj.bool(); 230 } catch (TransformerException e) { 231 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 233 } 234 } 235 } 236 237 246 public Node getSingleNodeValue() throws XPathException { 247 248 if ((m_resultType != ANY_UNORDERED_NODE_TYPE) && 249 (m_resultType != FIRST_ORDERED_NODE_TYPE)) { 250 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_SINGLENODE, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 251 throw new XPathException(XPathException.TYPE_ERR,fmsg); 252 } 255 256 NodeIterator result = null; 257 try { 258 result = m_resultObj.nodeset(); 259 } catch (TransformerException te) { 260 throw new XPathException(XPathException.TYPE_ERR,te.getMessage()); 261 } 262 263 if (null == result) return null; 264 265 Node node = result.nextNode(); 266 267 if (isNamespaceNode(node)) { 269 return new XPathNamespaceImpl(node); 270 } else { 271 return node; 272 } 273 } 274 275 278 public boolean getInvalidIteratorState() { 279 return m_isInvalidIteratorState; 280 } 281 282 293 public int getSnapshotLength() throws XPathException { 294 295 if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && 296 (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { 297 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_GET_SNAPSHOT_LENGTH, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 298 throw new XPathException(XPathException.TYPE_ERR,fmsg); 299 } 301 302 return m_list.getLength(); 303 } 304 305 318 public Node iterateNext() throws XPathException, DOMException { 319 if ((m_resultType != UNORDERED_NODE_ITERATOR_TYPE) && 320 (m_resultType != ORDERED_NODE_ITERATOR_TYPE)) { 321 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_NON_ITERATOR_TYPE, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 322 throw new XPathException(XPathException.TYPE_ERR, fmsg); 323 } 326 327 if (getInvalidIteratorState()) { 328 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_DOC_MUTATED, null); 329 throw new DOMException (DOMException.INVALID_STATE_ERR,fmsg); } 331 332 Node node = m_iterator.nextNode(); 333 if(null == node) 334 removeEventListener(); if (isNamespaceNode(node)) { 337 return new XPathNamespaceImpl(node); 338 } else { 339 return node; 340 } 341 } 342 343 360 public Node snapshotItem(int index) throws XPathException { 361 362 if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && 363 (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { 364 String fmsg = XPATHMessages.createXPATHMessage(XPATHErrorResources.ER_NON_SNAPSHOT_TYPE, new Object [] {m_xpath.getPatternString(), getTypeString(m_resultType)}); 365 throw new XPathException(XPathException.TYPE_ERR, fmsg); 366 } 369 370 Node node = m_list.item(index); 371 372 if (isNamespaceNode(node)) { 374 return new XPathNamespaceImpl(node); 375 } else { 376 return node; 377 } 378 } 379 380 381 387 static boolean isValidType( short type ) { 388 switch (type) { 389 case ANY_TYPE: 390 case NUMBER_TYPE: 391 case STRING_TYPE: 392 case BOOLEAN_TYPE: 393 case UNORDERED_NODE_ITERATOR_TYPE: 394 case ORDERED_NODE_ITERATOR_TYPE: 395 case UNORDERED_NODE_SNAPSHOT_TYPE: 396 case ORDERED_NODE_SNAPSHOT_TYPE: 397 case ANY_UNORDERED_NODE_TYPE: 398 case FIRST_ORDERED_NODE_TYPE: return true; 399 default: return false; 400 } 401 } 402 403 406 public void handleEvent(Event event) { 407 408 if (event.getType().equals("DOMSubtreeModified")) { 409 m_isInvalidIteratorState = true; 411 412 removeEventListener(); 414 } 415 } 416 417 423 private String getTypeString(int type) 424 { 425 switch (type) { 426 case ANY_TYPE: return "ANY_TYPE"; 427 case ANY_UNORDERED_NODE_TYPE: return "ANY_UNORDERED_NODE_TYPE"; 428 case BOOLEAN_TYPE: return "BOOLEAN"; 429 case FIRST_ORDERED_NODE_TYPE: return "FIRST_ORDERED_NODE_TYPE"; 430 case NUMBER_TYPE: return "NUMBER_TYPE"; 431 case ORDERED_NODE_ITERATOR_TYPE: return "ORDERED_NODE_ITERATOR_TYPE"; 432 case ORDERED_NODE_SNAPSHOT_TYPE: return "ORDERED_NODE_SNAPSHOT_TYPE"; 433 case STRING_TYPE: return "STRING_TYPE"; 434 case UNORDERED_NODE_ITERATOR_TYPE: return "UNORDERED_NODE_ITERATOR_TYPE"; 435 case UNORDERED_NODE_SNAPSHOT_TYPE: return "UNORDERED_NODE_SNAPSHOT_TYPE"; 436 default: return "#UNKNOWN"; 437 } 438 } 439 440 445 private short getTypeFromXObject(XObject object) { 446 switch (object.getType()) { 447 case XObject.CLASS_BOOLEAN: return BOOLEAN_TYPE; 448 case XObject.CLASS_NODESET: return UNORDERED_NODE_ITERATOR_TYPE; 449 case XObject.CLASS_NUMBER: return NUMBER_TYPE; 450 case XObject.CLASS_STRING: return STRING_TYPE; 451 463 case XObject.CLASS_RTREEFRAG: return UNORDERED_NODE_ITERATOR_TYPE; 464 case XObject.CLASS_NULL: return ANY_TYPE; default: return ANY_TYPE; } 467 468 } 469 470 477 private boolean isNamespaceNode(Node node) { 478 479 if ((null != node) && 480 (node.getNodeType() == Node.ATTRIBUTE_NODE) && 481 (node.getNodeName().startsWith("xmlns:") || node.getNodeName().equals("xmlns"))) { 482 return true; 483 } else { 484 return false; 485 } 486 } 487 488 492 private void addEventListener(){ 493 if(m_contextNode instanceof EventTarget ) 494 ((EventTarget )m_contextNode).addEventListener("DOMSubtreeModified",this,true); 495 496 } 497 498 499 503 private void removeEventListener(){ 504 if(m_contextNode instanceof EventTarget ) 505 ((EventTarget )m_contextNode).removeEventListener("DOMSubtreeModified",this,true); 506 } 507 508 } 509 | Popular Tags |