1 /* 2 * Copyright (c) 2014, 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 public Object getProperty(String name) throws IllegalArgumentException { 63 if (usePayloadReaderDelegate) return payloadReader.getProperty(name); 64 return super.getProperty(name); 65 } 66 67 public int next() throws XMLStreamException { 68 // boolean previouslyUsingPayloadReader = usePayloadReaderDelegate; 69 //call checkReaderStatus to advance to payloadReader if needed 70 checkReaderStatus(true); 71 72 if (usePayloadReaderDelegate) return payloadReader.getEventType(); 73 74 //if we just moved to payload reader, don't advance the pointer 75 // if (usePayloadReaderDelegate && !previouslyUsingPayloadReader) return payloadReader.getEventType(); 76 77 // if (usePayloadReaderDelegate) return payloadReader.next(); 78 return getEventType(); 79 } 80 81 public void require(int type, String namespaceURI, String localName) 82 throws XMLStreamException { 83 if (usePayloadReaderDelegate) payloadReader.require(type, namespaceURI, localName); 84 else super.require(type, namespaceURI, localName); 85 } 86 87 public String getElementText() throws XMLStreamException { 88 if (usePayloadReaderDelegate) return payloadReader.getElementText(); 89 return super.getElementText(); 90 } 91 92 public int nextTag() throws XMLStreamException { 93 if (usePayloadReaderDelegate) return payloadReader.nextTag(); 94 return super.nextTag(); 95 } 96 97 public boolean hasNext() throws XMLStreamException { 98 checkReaderStatus(false); 99 boolean hasNext; 100 if (usePayloadReaderDelegate) { 101 hasNext = payloadReader.hasNext(); 102 } else { 103 hasNext = super.hasNext(); 104 } 105 106 /*if (!hasNext && payloadReader != null) { 107 usePayloadReaderDelegate = true; 108 hasNext = payloadReader.hasNext(); 109 }*/ 110 return hasNext; 111 } 112 113 private void checkReaderStatus(boolean advanceToNext) throws XMLStreamException { 114 //if we are using payloadReader, make sure it is not exhausted 115 //if it is, return to DOM based reader for remaining end elements (body and envelope) 116 if (usePayloadReaderDelegate) { 117 if (!payloadReader.hasNext()) { 118 usePayloadReaderDelegate = false; 119 } 120 } else if (START_ELEMENT == getEventType()) { 121 //if not on payload reader, check if we need to switch to payload reader 122 123 //if the current event is the SOAP body element start, 124 //and the body is lazy, switch to the payload reader 125 if (bodyQName.equals(getName())) { 126 //if we are just switching to payload reader, don't advance...payload reader 127 //will already be on the first payload element 128 usePayloadReaderDelegate = true; 129 advanceToNext = false; 130 } 131 } 132 133 if (advanceToNext) { 134 if (usePayloadReaderDelegate) { 135 payloadReader.next(); 136 } else { 137 super.next(); 138 } 139 } 140 } 141 142 public void close() throws XMLStreamException { 143 if (usePayloadReaderDelegate) payloadReader.close(); 144 else super.close(); 145 } 146 147 public String getNamespaceURI(String prefix) { 148 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(prefix); 149 return super.getNamespaceURI(prefix); 150 } 151 152 public boolean isStartElement() { 153 if (usePayloadReaderDelegate) return payloadReader.isStartElement(); 154 return super.isStartElement(); 155 } 156 157 public boolean isEndElement() { 158 if (usePayloadReaderDelegate) return payloadReader.isEndElement(); 159 return super.isEndElement(); 160 } 161 162 public boolean isCharacters() { 163 if (usePayloadReaderDelegate) return payloadReader.isCharacters(); 164 return super.isEndElement(); 165 } 166 167 public boolean isWhiteSpace() { 168 if (usePayloadReaderDelegate) return payloadReader.isWhiteSpace(); 169 return super.isWhiteSpace(); 170 } 171 172 public String getAttributeValue(String namespaceURI, String localName) { 173 if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(namespaceURI, localName); 174 return super.getAttributeValue(namespaceURI, localName); 175 } 176 177 public int getAttributeCount() { 178 if (usePayloadReaderDelegate) return payloadReader.getAttributeCount(); 179 return super.getAttributeCount(); 180 } 181 182 public QName getAttributeName(int index) { 183 if (usePayloadReaderDelegate) return payloadReader.getAttributeName(index); 184 return super.getAttributeName(index); 185 } 186 187 public String getAttributeNamespace(int index) { 188 if (usePayloadReaderDelegate) return payloadReader.getAttributeNamespace(index); 189 return super.getAttributeNamespace(index); 190 } 191 192 public String getAttributeLocalName(int index) { 193 if (usePayloadReaderDelegate) return payloadReader.getAttributeLocalName(index); 194 return super.getAttributeLocalName(index); 195 } 196 197 public String getAttributePrefix(int index) { 198 if (usePayloadReaderDelegate) return payloadReader.getAttributePrefix(index); 199 return super.getAttributePrefix(index); 200 } 201 202 public String getAttributeType(int index) { 203 if (usePayloadReaderDelegate) return payloadReader.getAttributeType(index); 204 return super.getAttributeType(index); 205 } 206 207 public String getAttributeValue(int index) { 208 if (usePayloadReaderDelegate) return payloadReader.getAttributeValue(index); 209 return super.getAttributeValue(index); 210 } 211 212 public boolean isAttributeSpecified(int index) { 213 if (usePayloadReaderDelegate) return payloadReader.isAttributeSpecified(index); 214 return super.isAttributeSpecified(index); 215 } 216 217 public int getNamespaceCount() { 218 if (usePayloadReaderDelegate) return payloadReader.getNamespaceCount(); 219 return super.getNamespaceCount(); 220 } 221 222 public String getNamespacePrefix(int index) { 223 if (usePayloadReaderDelegate) return payloadReader.getNamespacePrefix(index); 224 return super.getNamespacePrefix(index); 225 } 226 227 public String getNamespaceURI(int index) { 228 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(index); 229 return super.getNamespaceURI(index); 230 } 231 232 public NamespaceContext getNamespaceContext() { 233 if (usePayloadReaderDelegate) return payloadReader.getNamespaceContext(); 234 return super.getNamespaceContext(); 235 } 236 237 public int getEventType() { 238 if (usePayloadReaderDelegate) return payloadReader.getEventType(); 239 return super.getEventType(); 240 } 241 242 public String getText() { 243 if (usePayloadReaderDelegate) return payloadReader.getText(); 244 return super.getText(); 245 } 246 247 public char[] getTextCharacters() { 248 if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(); 249 return super.getTextCharacters(); 250 } 251 252 public int getTextCharacters(int sourceStart, char[] target, 253 int targetStart, int length) throws XMLStreamException { 254 if (usePayloadReaderDelegate) return payloadReader.getTextCharacters(sourceStart, target, targetStart, 255 length); 256 return super.getTextCharacters(sourceStart, target, targetStart, length); 257 } 258 259 public int getTextStart() { 260 if (usePayloadReaderDelegate) return payloadReader.getTextStart(); 261 return super.getTextStart(); 262 } 263 264 public int getTextLength() { 265 if (usePayloadReaderDelegate) return payloadReader.getTextLength(); 266 return super.getTextLength(); 267 } 268 269 public String getEncoding() { 270 if (usePayloadReaderDelegate) return payloadReader.getEncoding(); 271 return super.getEncoding(); 272 } 273 274 public boolean hasText() { 275 if (usePayloadReaderDelegate) return payloadReader.hasText(); 276 return super.hasText(); 277 } 278 279 public Location getLocation() { 280 if (usePayloadReaderDelegate) return payloadReader.getLocation(); 281 return super.getLocation(); 282 } 283 284 public QName getName() { 285 if (usePayloadReaderDelegate) return payloadReader.getName(); 286 return super.getName(); 287 } 288 289 public String getLocalName() { 290 if (usePayloadReaderDelegate) return payloadReader.getLocalName(); 291 return super.getLocalName(); 292 } 293 294 public boolean hasName() { 295 if (usePayloadReaderDelegate) return payloadReader.hasName(); 296 return super.hasName(); 297 } 298 299 public String getNamespaceURI() { 300 if (usePayloadReaderDelegate) return payloadReader.getNamespaceURI(); 301 return super.getNamespaceURI(); 302 } 303 304 public String getPrefix() { 305 if (usePayloadReaderDelegate) return payloadReader.getPrefix(); 306 return super.getPrefix(); 307 } 308 309 public String getVersion() { 310 if (usePayloadReaderDelegate) return payloadReader.getVersion(); 311 return super.getVersion(); 312 } 313 314 public boolean isStandalone() { 315 if (usePayloadReaderDelegate) return payloadReader.isStandalone(); 316 return super.isStandalone(); 317 } 318 319 public boolean standaloneSet() { 320 if (usePayloadReaderDelegate) return payloadReader.standaloneSet(); 321 return super.standaloneSet(); 322 } 323 324 public String getCharacterEncodingScheme() { 325 if (usePayloadReaderDelegate) return payloadReader.getCharacterEncodingScheme(); 326 return super.getCharacterEncodingScheme(); 327 } 328 329 public String getPITarget() { 330 if (usePayloadReaderDelegate) return payloadReader.getPITarget(); 331 return super.getPITarget(); 332 } 333 334 public String getPIData() { 335 if (usePayloadReaderDelegate) return payloadReader.getPIData(); 336 return super.getPIData(); 337 } 338 339 //make sure that message is not realized as a result of call 340 //to getFirstChild 341 protected Node getFirstChild(Node node) { 342 if (node instanceof BodyImpl) { 343 return ((BodyImpl) node).getFirstChildNoMaterialize(); 344 } else { 345 return node.getFirstChild(); 346 } 347 } 348 349 protected Node getNextSibling(Node node) { 350 if (node instanceof BodyImpl) { 351 //body is not expected to have a next sibling - even if it does 352 //we would have to materialize the node to retrieve it. 353 //Since we don't want to materialize it right now, just return null 354 return null; 355 } 356 return node.getNextSibling(); 357 } 358 359 }