View Javadoc

1   /*
2    * Copyright 2006 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.xml.stream;
18  
19  import javax.xml.namespace.QName;
20  import javax.xml.stream.XMLStreamConstants;
21  import javax.xml.stream.XMLStreamException;
22  import javax.xml.stream.XMLStreamReader;
23  
24  import org.springframework.util.Assert;
25  
26  /**
27   * Abstract base class for <code>XMLStreamReader</code>s.
28   *
29   * @author Arjen Poutsma
30   * @since 1.0.0
31   */
32  public abstract class AbstractXmlStreamReader implements XMLStreamReader {
33  
34      public String getElementText() throws XMLStreamException {
35          if (getEventType() != XMLStreamConstants.START_ELEMENT) {
36              throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation());
37          }
38          int eventType = next();
39          StringBuffer buffer = new StringBuffer();
40          while (eventType != XMLStreamConstants.END_ELEMENT) {
41              if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA ||
42                      eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
43                  buffer.append(getText());
44              }
45              else
46              if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) {
47                  // skipping
48              }
49              else if (eventType == XMLStreamConstants.END_DOCUMENT) {
50                  throw new XMLStreamException("unexpected end of document when reading element text content",
51                          getLocation());
52              }
53              else if (eventType == XMLStreamConstants.START_ELEMENT) {
54                  throw new XMLStreamException("element text content may not contain START_ELEMENT", getLocation());
55              }
56              else {
57                  throw new XMLStreamException("Unexpected event type " + eventType, getLocation());
58              }
59              eventType = next();
60          }
61          return buffer.toString();
62      }
63  
64      public String getAttributeLocalName(int index) {
65          return getAttributeName(index).getLocalPart();
66      }
67  
68      public String getAttributeNamespace(int index) {
69          return getAttributeName(index).getNamespaceURI();
70      }
71  
72      public String getAttributePrefix(int index) {
73          return getAttributeName(index).getPrefix();
74      }
75  
76      public String getNamespaceURI() {
77          int eventType = getEventType();
78          if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) {
79              return getName().getNamespaceURI();
80          }
81          else {
82              throw new IllegalStateException("parser must be on START_ELEMENT or END_ELEMENT state");
83          }
84      }
85  
86      public String getNamespaceURI(String prefix) {
87          Assert.notNull(prefix, "No prefix given");
88          return getNamespaceContext().getNamespaceURI(prefix);
89      }
90  
91      public boolean hasText() {
92          int eventType = getEventType();
93          return eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.CHARACTERS ||
94                  eventType == XMLStreamConstants.COMMENT || eventType == XMLStreamConstants.CDATA ||
95                  eventType == XMLStreamConstants.ENTITY_REFERENCE;
96      }
97  
98      public String getPrefix() {
99          int eventType = getEventType();
100         if (eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT) {
101             return getName().getPrefix();
102         }
103         else {
104             throw new IllegalStateException("parser must be on START_ELEMENT or END_ELEMENT state");
105         }
106     }
107 
108     public boolean hasName() {
109         int eventType = getEventType();
110         return eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT;
111     }
112 
113     public boolean isWhiteSpace() {
114         return getEventType() == XMLStreamConstants.SPACE;
115     }
116 
117     public boolean isStartElement() {
118         return getEventType() == XMLStreamConstants.START_ELEMENT;
119     }
120 
121     public boolean isEndElement() {
122         return getEventType() == XMLStreamConstants.END_ELEMENT;
123     }
124 
125     public boolean isCharacters() {
126         return getEventType() == XMLStreamConstants.CHARACTERS;
127     }
128 
129     public int nextTag() throws XMLStreamException {
130         int eventType = next();
131         while (eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace() ||
132                 eventType == XMLStreamConstants.CDATA && isWhiteSpace() || eventType == XMLStreamConstants.SPACE ||
133                 eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) {
134             eventType = next();
135         }
136         if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
137             throw new XMLStreamException("expected start or end tag", getLocation());
138         }
139         return eventType;
140     }
141 
142     public void require(int expectedType, String namespaceURI, String localName) throws XMLStreamException {
143         int eventType = getEventType();
144         if (eventType != expectedType) {
145             throw new XMLStreamException("Expected [" + expectedType + "] but read [" + eventType + "]");
146         }
147     }
148 
149     public String getAttributeValue(String namespaceURI, String localName) {
150         for (int i = 0; i < getAttributeCount(); i++) {
151             QName name = getAttributeName(i);
152             if (name.getNamespaceURI().equals(namespaceURI) && name.getLocalPart().equals(localName)) {
153                 return getAttributeValue(i);
154             }
155         }
156         return null;
157     }
158 
159     public boolean hasNext() throws XMLStreamException {
160         return getEventType() != END_DOCUMENT;
161     }
162 
163     public String getLocalName() {
164         return getName().getLocalPart();
165     }
166 
167     public char[] getTextCharacters() {
168         return getText().toCharArray();
169     }
170 
171     public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
172             throws XMLStreamException {
173         char[] source = getTextCharacters();
174         length = Math.min(length, source.length);
175         System.arraycopy(source, sourceStart, target, targetStart, length);
176         return length;
177     }
178 
179     public int getTextLength() {
180         return getText().length();
181     }
182 }