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.XMLStreamException;
21  
22  import org.springframework.xml.namespace.QNameUtils;
23  import org.springframework.xml.namespace.SimpleNamespaceContext;
24  import org.xml.sax.Attributes;
25  import org.xml.sax.ContentHandler;
26  import org.xml.sax.SAXException;
27  
28  /**
29   * Abstract base class for SAX <code>ContentHandler</code> implementations that use StAX as a basis. All methods
30   * delegate to internal template methods, capable of throwing a <code>XMLStreamException</code>. Additionally, an
31   * namespace context is used to keep track of declared namespaces.
32   *
33   * @author Arjen Poutsma
34   * @since 1.0.0
35   */
36  public abstract class AbstractStaxContentHandler implements ContentHandler {
37  
38      private SimpleNamespaceContext namespaceContext = new SimpleNamespaceContext();
39  
40      /**
41       * @throws SAXException
42       */
43      public final void startDocument() throws SAXException {
44          namespaceContext.clear();
45          try {
46              startDocumentInternal();
47          }
48          catch (XMLStreamException ex) {
49              throw new SAXException("Could not handle startDocument: " + ex.getMessage(), ex);
50          }
51      }
52  
53      protected abstract void startDocumentInternal() throws XMLStreamException;
54  
55      public final void endDocument() throws SAXException {
56          namespaceContext.clear();
57          try {
58              endDocumentInternal();
59          }
60          catch (XMLStreamException ex) {
61              throw new SAXException("Could not handle startDocument: " + ex.getMessage(), ex);
62          }
63      }
64  
65      protected abstract void endDocumentInternal() throws XMLStreamException;
66  
67      /**
68       * Binds the given prefix to the given namespaces.
69       *
70       * @see SimpleNamespaceContext#bindNamespaceUri(String,String)
71       */
72      public final void startPrefixMapping(String prefix, String uri) {
73          namespaceContext.bindNamespaceUri(prefix, uri);
74      }
75  
76      /**
77       * Removes the binding for the given prefix.
78       *
79       * @see SimpleNamespaceContext#removeBinding(String)
80       */
81      public final void endPrefixMapping(String prefix) {
82          namespaceContext.removeBinding(prefix);
83      }
84  
85      public final void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
86          try {
87              startElementInternal(QNameUtils.toQName(uri, qName), atts, namespaceContext);
88          }
89          catch (XMLStreamException ex) {
90              throw new SAXException("Could not handle startElement: " + ex.getMessage(), ex);
91          }
92      }
93  
94      protected abstract void startElementInternal(QName name, Attributes atts, SimpleNamespaceContext namespaceContext)
95              throws XMLStreamException;
96  
97      public final void endElement(String uri, String localName, String qName) throws SAXException {
98          try {
99              endElementInternal(QNameUtils.toQName(uri, qName), namespaceContext);
100         }
101         catch (XMLStreamException ex) {
102             throw new SAXException("Could not handle endElement: " + ex.getMessage(), ex);
103         }
104     }
105 
106     protected abstract void endElementInternal(QName name, SimpleNamespaceContext namespaceContext)
107             throws XMLStreamException;
108 
109     public final void characters(char ch[], int start, int length) throws SAXException {
110         try {
111             charactersInternal(ch, start, length);
112         }
113         catch (XMLStreamException ex) {
114             throw new SAXException("Could not handle characters: " + ex.getMessage(), ex);
115         }
116     }
117 
118     protected abstract void charactersInternal(char[] ch, int start, int length) throws XMLStreamException;
119 
120     public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
121         try {
122             ignorableWhitespaceInternal(ch, start, length);
123         }
124         catch (XMLStreamException ex) {
125             throw new SAXException("Could not handle ignorableWhitespace:" + ex.getMessage(), ex);
126         }
127     }
128 
129     protected abstract void ignorableWhitespaceInternal(char[] ch, int start, int length) throws XMLStreamException;
130 
131     public final void processingInstruction(String target, String data) throws SAXException {
132         try {
133             processingInstructionInternal(target, data);
134         }
135         catch (XMLStreamException ex) {
136             throw new SAXException("Could not handle processingInstruction: " + ex.getMessage(), ex);
137         }
138     }
139 
140     protected abstract void processingInstructionInternal(String target, String data) throws XMLStreamException;
141 
142     public final void skippedEntity(String name) throws SAXException {
143         try {
144             skippedEntityInternal(name);
145         }
146         catch (XMLStreamException ex) {
147             throw new SAXException("Could not handle skippedEntity: " + ex.getMessage(), ex);
148         }
149     }
150 
151     protected abstract void skippedEntityInternal(String name) throws XMLStreamException;
152 }