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