001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 **/
018 package org.codehaus.activesoap.util;
019
020 import javax.xml.namespace.QName;
021 import javax.xml.stream.XMLStreamConstants;
022 import javax.xml.stream.XMLStreamException;
023 import javax.xml.stream.XMLStreamReader;
024 import javax.xml.stream.util.StreamReaderDelegate;
025
026 /**
027 * An {@link StreamReaderDelegate} which creates a logical sub-document
028 * from a stream until a certain close element is discovered - such as for making
029 * the contents of a SOAP body appear as a logical XML document.
030 *
031 * @version $Revision: 1.6 $
032 */
033 public class DocumentFilterXMLStreamReader extends StreamReaderDelegate implements XMLStreamConstants {
034 boolean first = true;
035 boolean finished = false;
036 private final QName name;
037 private boolean second;
038
039
040 public DocumentFilterXMLStreamReader(XMLStreamReader in) {
041 this(in.getName(), in);
042 }
043
044
045 public DocumentFilterXMLStreamReader(QName name, XMLStreamReader in) {
046 super(in);
047 this.name = name;
048 }
049
050 public void disableStartDocumentEvent() {
051 first = false;
052 }
053
054 public boolean hasNext() throws XMLStreamException {
055 if (first) {
056 return true;
057 }
058 else if (finished) {
059 return false;
060 }
061 return super.hasNext();
062 }
063
064 public int next() throws XMLStreamException {
065 if (first) {
066 first = false;
067 second = true;
068 return START_DOCUMENT;
069 }
070 else if (second) {
071 second = false;
072 return super.getEventType();
073 }
074 else if (finished) {
075 return END_DOCUMENT;
076 }
077 else {
078 int answer = super.next();
079 // TODO : to avoid bug in RI disable this line
080 //if (answer == END_ELEMENT && name.equals(getName())) {
081 if (answer == END_ELEMENT && name.getLocalPart().equals(getLocalName()) && name.getNamespaceURI().equals(getNamespaceURI())) {
082 finished = true;
083 }
084 return answer;
085 }
086 }
087
088 public int nextTag() throws XMLStreamException {
089 int eventType = next();
090 if (eventType == START_DOCUMENT) {
091 eventType = next();
092 }
093 while ((eventType == CHARACTERS && isWhiteSpace()) // skip whitespace
094 || (eventType == CDATA && isWhiteSpace())
095 // skip whitespace
096 || eventType == SPACE
097 || eventType == PROCESSING_INSTRUCTION
098 || eventType == COMMENT
099 ) {
100 eventType = next();
101 }
102 if (eventType != START_ELEMENT && eventType != END_ELEMENT) {
103 throw new XMLStreamException("expected start or end tag but got type: " + eventType, getLocation());
104 }
105 return eventType;
106 }
107
108 public int getEventType() {
109 if (first) {
110 return START_DOCUMENT;
111 }
112 else if (finished) {
113 return END_DOCUMENT;
114 }
115 return super.getEventType();
116 }
117 }
118