1 /* 2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.messaging.saaj.util.stax; 27 28 import javax.xml.namespace.NamespaceContext; 29 import javax.xml.namespace.QName; 30 import javax.xml.soap.SOAPException; 31 import javax.xml.stream.Location; 32 import javax.xml.stream.XMLStreamException; 33 import javax.xml.stream.XMLStreamReader; 34 35 import org.w3c.dom.Node; 36 37 import com.sun.xml.internal.messaging.saaj.soap.impl.BodyImpl; 38 import com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl; 39 40 /** 41 * "Hybrid" reader which 42 * @author desagar 43 * 44 */ 45 public class LazyEnvelopeStaxReader extends com.sun.xml.internal.org.jvnet.staxex.util.DOMStreamReader { 46 // EnvelopeImpl env; 47 XMLStreamReader payloadReader = null; 48 boolean usePayloadReaderDelegate = false; 49 private QName bodyQName; 50 51 public LazyEnvelopeStaxReader(EnvelopeImpl env) throws SOAPException, XMLStreamException { 52 super(env); 53 // this.env = env; 54 bodyQName = new QName(env.getNamespaceURI(), "Body"); 55 payloadReader = env.getStaxBridge().getPayloadReader(); 56 int eventType = getEventType(); 57 while (eventType != START_ELEMENT) { 58 eventType = nextTag(); 59 } 60 } 61 62 @Override 63 public Object getProperty(String name) throws IllegalArgumentException { 64 if (usePayloadReaderDelegate) return payloadReader.getProperty(name); 65 return super.getProperty(name); 66 } 67 68 @Override 69 public int next() throws XMLStreamException { 70 // boolean previouslyUsingPayloadReader = usePayloadReaderDelegate; 71 //call checkReaderStatus to advance to payloadReader if needed 72 checkReaderStatus(true); 73 74 if (usePayloadReaderDelegate) return payloadReader.getEventType(); 75 76 //if we just moved to payload reader, don't advance the pointer 77 // if (usePayloadReaderDelegate && !previouslyUsingPayloadReader) return payloadReader.getEventType(); 78 79 // if (usePayloadReaderDelegate) return payloadReader.next(); 80 return getEventType(); 81 } 82 83 @Override 84 public void require(int type, String namespaceURI, String localName) 85 throws XMLStreamException { 86 if (usePayloadReaderDelegate) payloadReader.require(type, namespaceURI, localName); 87 else super.require(type, namespaceURI, localName); 88 } 89 90 @Override 91 public String getElementText() throws XMLStreamException { 92 if (usePayloadReaderDelegate) return payloadReader.getElementText(); 93 return super.getElementText(); 94 } 95 96 @Override 97 public int nextTag() throws XMLStreamException { 98 if (usePayloadReaderDelegate) return payloadReader.nextTag(); 99 return super.nextTag(); 100 } 101 102 @Override 103 public boolean hasNext() throws XMLStreamException { 104 checkReaderStatus(false); 105 boolean hasNext; 106 if (usePayloadReaderDelegate) { 107 hasNext = payloadReader.hasNext(); 108 } else { 109 hasNext = super.hasNext(); 110 } 111 112 /*if (!hasNext && payloadReader != null) { 113 usePayloadReaderDelegate = true; 114 hasNext = payloadReader.hasNext(); 115 }*/ 116 return hasNext; 117 } 118 119 private void checkReaderStatus(boolean advanceToNext) throws XMLStreamException { 120 //if we are using payloadReader, make sure it is not exhausted 121 //if it is, return to DOM based reader for remaining end elements (body and envelope) 122 if (usePayloadReaderDelegate) { 123 if (!payloadReader.hasNext()) { 124 usePayloadReaderDelegate = false; 125 } 126 } else if (START_ELEMENT == getEventType()) { 127 //if not on payload reader, check if we need to switch to payload reader 128 129 //if the current event is the SOAP body element start, 130 //and the body is lazy, switch to the payload reader 131 if (bodyQName.equals(getName())) { 132 //if we are just switching to payload reader, don't advance...payload reader 133 //will already be on the first payload element 134 usePayloadReaderDelegate = true; 135 advanceToNext = false; 136 } 137 } 138 139 if (advanceToNext) { 140 if (usePayloadReaderDelegate) { 141 payloadReader.next(); 142 } else { 143 super.next(); 144 } 145 } 146 } 147 148 @Override 149 public void close() throws XMLStreamException { 150 if (usePayloadReaderDelegate) payloadReader.close(); 151 else super.close(); 152 } 153 154 @Override 155 public String getNamespaceURI(String prefix) { 156 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(prefix); 157 return super.getNamespaceURI(prefix); 158 } 159 160 @Override 161 public boolean isStartElement() { 162 if (usePayloadReaderDelegate) return payloadReader.isStartElement(); 163 return super.isStartElement(); 164 } 165 166 @Override 167 public boolean isEndElement() { 168 if (usePayloadReaderDelegate) return payloadReader.isEndElement(); 169 return super.isEndElement(); 170 } 171 172 @Override 173 public boolean isCharacters() { 174 if (usePayloadReaderDelegate) return payloadReader.isCharacters(); 175 return super.isEndElement(); 176 } 177 178 @Override 179 public boolean isWhiteSpace() { 180 if (usePayloadReaderDelegate) return payloadReader.isWhiteSpace(); 181 return super.isWhiteSpace(); 182 } 183 184 @Override 185 public String getAttributeValue(String namespaceURI, String localName) { 186 if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(namespaceURI, localName); 187 return super.getAttributeValue(namespaceURI, localName); 188 } 189 190 @Override 191 public int getAttributeCount() { 192 if (usePayloadReaderDelegate) return payloadReader.getAttributeCount(); 193 return super.getAttributeCount(); 194 } 195 196 @Override 197 public QName getAttributeName(int index) { 198 if (usePayloadReaderDelegate) return payloadReader.getAttributeName(index); 199 return super.getAttributeName(index); 200 } 201 202 @Override 203 public String getAttributeNamespace(int index) { 204 if (usePayloadReaderDelegate) return payloadReader.getAttributeNamespace(index); 205 return super.getAttributeNamespace(index); 206 } 207 208 @Override 209 public String getAttributeLocalName(int index) { 210 if (usePayloadReaderDelegate) return payloadReader.getAttributeLocalName(index); 211 return super.getAttributeLocalName(index); 212 } 213 214 @Override 215 public String getAttributePrefix(int index) { 216 if (usePayloadReaderDelegate) return payloadReader.getAttributePrefix(index); 217 return super.getAttributePrefix(index); 218 } 219 220 @Override 221 public String getAttributeType(int index) { 222 if (usePayloadReaderDelegate) return payloadReader.getAttributeType(index); 223 return super.getAttributeType(index); 224 } 225 226 @Override 227 public String getAttributeValue(int index) { 228 if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(index); 229 return super.getAttributeValue(index); 230 } 231 232 @Override 233 public boolean isAttributeSpecified(int index) { 234 if (usePayloadReaderDelegate) return payloadReader.isAttributeSpecified(index); 235 return super.isAttributeSpecified(index); 236 } 237 238 @Override 239 public int getNamespaceCount() { 240 if (usePayloadReaderDelegate) return payloadReader.getNamespaceCount(); 241 return super.getNamespaceCount(); 242 } 243 244 @Override 245 public String getNamespacePrefix(int index) { 246 if (usePayloadReaderDelegate) return payloadReader.getNamespacePrefix(index); 247 return super.getNamespacePrefix(index); 248 } 249 250 @Override 251 public String getNamespaceURI(int index) { 252 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(index); 253 return super.getNamespaceURI(index); 254 } 255 256 @Override 257 public NamespaceContext getNamespaceContext() { 258 if (usePayloadReaderDelegate) return payloadReader.getNamespaceContext(); 259 return super.getNamespaceContext(); 260 } 261 262 @Override 263 public int getEventType() { 264 if (usePayloadReaderDelegate) return payloadReader.getEventType(); 265 return super.getEventType(); 266 } 267 268 @Override 269 public String getText() { 270 if (usePayloadReaderDelegate) return payloadReader.getText(); 271 return super.getText(); 272 } 273 274 @Override 275 public char[] getTextCharacters() { 276 if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(); 277 return super.getTextCharacters(); 278 } 279 280 @Override 281 public int getTextCharacters(int sourceStart, char[] target, 282 int targetStart, int length) throws XMLStreamException { 283 if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(sourceStart, target, targetStart, 284 length); 285 return super.getTextCharacters(sourceStart, target, targetStart, length); 286 } 287 288 @Override 289 public int getTextStart() { 290 if (usePayloadReaderDelegate) return payloadReader.getTextStart(); 291 return super.getTextStart(); 292 } 293 294 @Override 295 public int getTextLength() { 296 if (usePayloadReaderDelegate) return payloadReader.getTextLength(); 297 return super.getTextLength(); 298 } 299 300 @Override 301 public String getEncoding() { 302 if (usePayloadReaderDelegate) return payloadReader.getEncoding(); 303 return super.getEncoding(); 304 } 305 306 @Override 307 public boolean hasText() { 308 if (usePayloadReaderDelegate) return payloadReader.hasText(); 309 return super.hasText(); 310 } 311 312 @Override 313 public Location getLocation() { 314 if (usePayloadReaderDelegate) return payloadReader.getLocation(); 315 return super.getLocation(); 316 } 317 318 @Override 319 public QName getName() { 320 if (usePayloadReaderDelegate) return payloadReader.getName(); 321 return super.getName(); 322 } 323 324 @Override 325 public String getLocalName() { 326 if (usePayloadReaderDelegate) return payloadReader.getLocalName(); 327 return super.getLocalName(); 328 } 329 330 @Override 331 public boolean hasName() { 332 if (usePayloadReaderDelegate) return payloadReader.hasName(); 333 return super.hasName(); 334 } 335 336 @Override 337 public String getNamespaceURI() { 338 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(); 339 return super.getNamespaceURI(); 340 } 341 342 @Override 343 public String getPrefix() { 344 if (usePayloadReaderDelegate) return payloadReader.getPrefix(); 345 return super.getPrefix(); 346 } 347 348 @Override 349 public String getVersion() { 350 if (usePayloadReaderDelegate) return payloadReader.getVersion(); 351 return super.getVersion(); 352 } 353 354 @Override 355 public boolean isStandalone() { 356 if (usePayloadReaderDelegate) return payloadReader.isStandalone(); 357 return super.isStandalone(); 358 } 359 360 @Override 361 public boolean standaloneSet() { 362 if (usePayloadReaderDelegate) return payloadReader.standaloneSet(); 363 return super.standaloneSet(); 364 } 365 366 @Override 367 public String getCharacterEncodingScheme() { 368 if (usePayloadReaderDelegate) return payloadReader.getCharacterEncodingScheme(); 369 return super.getCharacterEncodingScheme(); 370 } 371 372 @Override 373 public String getPITarget() { 374 if (usePayloadReaderDelegate) return payloadReader.getPITarget(); 375 return super.getPITarget(); 376 } 377 378 @Override 379 public String getPIData() { 380 if (usePayloadReaderDelegate) return payloadReader.getPIData(); 381 return super.getPIData(); 382 } 383 384 //make sure that message is not realized as a result of call 385 //to getFirstChild 386 protected Node getFirstChild(Node node) { 387 if (node instanceof BodyImpl) { 388 return ((BodyImpl) node).getFirstChildNoMaterialize(); 389 } else { 390 return node.getFirstChild(); 391 } 392 } 393 394 protected Node getNextSibling(Node node) { 395 if (node instanceof BodyImpl) { 396 //body is not expected to have a next sibling - even if it does 397 //we would have to materialize the node to retrieve it. 398 //Since we don't want to materialize it right now, just return null 399 return null; 400 } 401 return node.getNextSibling(); 402 } 403 404 }