1 16 19 20 21 package org.apache.xpath.domapi; 22 23 import javax.xml.transform.TransformerException ; 24 25 import org.apache.xalan.res.XSLMessages; 26 import org.apache.xpath.objects.XObject; 27 import org.apache.xpath.res.XPATHErrorResources; 28 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 public class XPathResultImpl implements XPathResult, EventListener { 60 61 64 private XObject m_resultObj; 65 66 70 private short m_resultType = ANY_TYPE; 71 72 private boolean m_isInvalidIteratorState = false; 73 74 78 private Node m_contextNode; 79 80 83 private NodeIterator m_iterator = null; 84 85 88 private NodeList m_list = null; 89 90 91 96 XPathResultImpl(short type, XObject result, Node contextNode) { 97 if (!isValidType(type)) { 99 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INVALID_XPATH_TYPE, new Object [] {new Integer (type)}); 100 throw new XPathException(XPathException.TYPE_ERR,fmsg); } 102 103 if (null == result) { 105 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_EMPTY_XPATH_RESULT, null); 106 throw new XPathException(XPathException.INVALID_EXPRESSION_ERR,fmsg); } 108 109 this.m_resultObj = result; 110 this.m_contextNode = contextNode; 111 112 if (type == ANY_TYPE) { 114 this.m_resultType = getTypeFromXObject(result); 115 } else { 116 this.m_resultType = type; 117 } 118 119 if (((m_resultType == XPathResult.ORDERED_NODE_ITERATOR_TYPE) || 122 (m_resultType == XPathResult.UNORDERED_NODE_ITERATOR_TYPE))&& 123 (contextNode instanceof EventTarget )) { 124 ((EventTarget )contextNode).addEventListener("MutationEvents",this,true); 125 } 127 if ((m_resultType == ORDERED_NODE_ITERATOR_TYPE) || 129 (m_resultType == UNORDERED_NODE_ITERATOR_TYPE) || 130 (m_resultType == ANY_UNORDERED_NODE_TYPE) || 131 (m_resultType == FIRST_ORDERED_NODE_TYPE)) { 132 133 try { 134 m_iterator = m_resultObj.nodeset(); 135 } catch (TransformerException te) { 136 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object [] {getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); 138 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 140 141 148 } else if ((m_resultType == UNORDERED_NODE_SNAPSHOT_TYPE) || 150 (m_resultType == ORDERED_NODE_SNAPSHOT_TYPE)) { 151 try { 152 m_list = m_resultObj.nodelist(); 153 } catch (TransformerException te) { 154 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object [] {getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); 156 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 158 } 159 } 160 161 164 public short getResultType() { 165 return m_resultType; 166 } 167 168 175 public double getNumberValue() throws XPathException { 176 if (getResultType() != NUMBER_TYPE) { 177 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_NUMBER, new Object [] {getTypeString(m_resultType)}); 178 throw new XPathException(XPathException.TYPE_ERR,fmsg); } else { 180 try { 181 return m_resultObj.num(); 182 } catch (Exception e) { 183 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 185 } 186 } 187 } 188 189 197 public String getStringValue() throws XPathException { 198 if (getResultType() != STRING_TYPE) { 199 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_STRING, new Object [] {m_resultObj.getTypeString()}); 200 throw new XPathException(XPathException.TYPE_ERR,fmsg); } else { 202 try { 203 return m_resultObj.str(); 204 } catch (Exception e) { 205 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 207 } 208 } 209 } 210 211 214 public boolean getBooleanValue() throws XPathException { 215 if (getResultType() != BOOLEAN_TYPE) { 216 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_BOOLEAN, new Object [] {getTypeString(m_resultType)}); 217 throw new XPathException(XPathException.TYPE_ERR,fmsg); } else { 219 try { 220 return m_resultObj.bool(); 221 } catch (TransformerException e) { 222 throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); 224 } 225 } 226 } 227 228 237 public Node getSingleNodeValue() throws XPathException { 238 239 if ((m_resultType != ANY_UNORDERED_NODE_TYPE) && 240 (m_resultType != FIRST_ORDERED_NODE_TYPE)) { 241 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_SINGLENODE, new Object [] {getTypeString(m_resultType)}); 242 throw new XPathException(XPathException.TYPE_ERR,fmsg); } 245 246 NodeIterator result = null; 247 try { 248 result = m_resultObj.nodeset(); 249 } catch (TransformerException te) { 250 throw new XPathException(XPathException.TYPE_ERR,te.getMessage()); 251 } 252 253 if (null == result) return null; 254 255 Node node = result.nextNode(); 256 257 if (isNamespaceNode(node)) { 259 return new XPathNamespaceImpl(node); 260 } else { 261 return node; 262 } 263 } 264 265 268 public boolean getInvalidIteratorState() { 269 return m_isInvalidIteratorState; 270 } 271 272 283 public int getSnapshotLength() throws XPathException { 284 285 if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && 286 (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { 287 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_GET_SNAPSHOT_LENGTH, new Object [] {getTypeString(m_resultType)}); 288 throw new XPathException(XPathException.TYPE_ERR,fmsg); } 291 292 return m_list.getLength(); 293 } 294 295 308 public Node iterateNext() throws XPathException, DOMException { 309 if ((m_resultType != UNORDERED_NODE_ITERATOR_TYPE) && 310 (m_resultType != ORDERED_NODE_ITERATOR_TYPE)) { 311 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NON_ITERATOR_TYPE, new Object [] {getTypeString(m_resultType)}); 312 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 314 315 if (getInvalidIteratorState()) { 316 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_DOC_MUTATED, null); 317 throw new DOMException (DOMException.INVALID_STATE_ERR,fmsg); } 319 320 Node node = m_iterator.nextNode(); 321 322 if (isNamespaceNode(node)) { 324 return new XPathNamespaceImpl(node); 325 } else { 326 return node; 327 } 328 } 329 330 347 public Node snapshotItem(int index) throws XPathException { 348 349 if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && 350 (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { 351 String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NON_SNAPSHOT_TYPE, new Object [] {getTypeString(m_resultType)}); 352 throw new XPathException(XPathException.TYPE_ERR, fmsg); } 355 356 Node node = m_list.item(index); 357 358 if (isNamespaceNode(node)) { 360 return new XPathNamespaceImpl(node); 361 } else { 362 return node; 363 } 364 } 365 366 367 373 public static boolean isValidType( short type ) { 374 switch (type) { 375 case ANY_TYPE: 376 case NUMBER_TYPE: 377 case STRING_TYPE: 378 case BOOLEAN_TYPE: 379 case UNORDERED_NODE_ITERATOR_TYPE: 380 case ORDERED_NODE_ITERATOR_TYPE: 381 case UNORDERED_NODE_SNAPSHOT_TYPE: 382 case ORDERED_NODE_SNAPSHOT_TYPE: 383 case ANY_UNORDERED_NODE_TYPE: 384 case FIRST_ORDERED_NODE_TYPE: return true; 385 default: return false; 386 } 387 } 388 389 392 public void handleEvent(Event event) { 393 394 if (event.getType().equals("MutationEvents")) { 395 m_isInvalidIteratorState = true; 397 398 ((EventTarget )m_contextNode).removeEventListener("MutationEvents",this,true); 400 401 } 402 } 403 404 410 public String getTypeString(int type) 411 { 412 switch (type) { 413 case ANY_TYPE: return "ANY_TYPE"; 414 case ANY_UNORDERED_NODE_TYPE: return "ANY_UNORDERED_NODE_TYPE"; 415 case BOOLEAN_TYPE: return "BOOLEAN"; 416 case FIRST_ORDERED_NODE_TYPE: return "FIRST_ORDERED_NODE_TYPE"; 417 case NUMBER_TYPE: return "NUMBER_TYPE"; 418 case ORDERED_NODE_ITERATOR_TYPE: return "ORDERED_NODE_ITERATOR_TYPE"; 419 case ORDERED_NODE_SNAPSHOT_TYPE: return "ORDERED_NODE_SNAPSHOT_TYPE"; 420 case STRING_TYPE: return "STRING_TYPE"; 421 case UNORDERED_NODE_ITERATOR_TYPE: return "UNORDERED_NODE_ITERATOR_TYPE"; 422 case UNORDERED_NODE_SNAPSHOT_TYPE: return "UNORDERED_NODE_SNAPSHOT_TYPE"; 423 default: return "#UNKNOWN"; 424 } 425 } 426 427 432 private short getTypeFromXObject(XObject object) { 433 switch (object.getType()) { 434 case XObject.CLASS_BOOLEAN: return BOOLEAN_TYPE; 435 case XObject.CLASS_NODESET: return UNORDERED_NODE_ITERATOR_TYPE; 436 case XObject.CLASS_NUMBER: return NUMBER_TYPE; 437 case XObject.CLASS_STRING: return STRING_TYPE; 438 450 case XObject.CLASS_RTREEFRAG: return UNORDERED_NODE_ITERATOR_TYPE; 451 case XObject.CLASS_NULL: return ANY_TYPE; default: return ANY_TYPE; } 454 455 } 456 457 464 private boolean isNamespaceNode(Node node) { 465 466 if ((null != node) && 467 (node.getNodeType() == Node.ATTRIBUTE_NODE) && 468 (node.getNodeName().startsWith("xmlns:") || node.getNodeName().equals("xmlns"))) { 469 return true; 470 } else { 471 return false; 472 } 473 } 474 475 } 476 | Popular Tags |