View Javadoc

1   /*-------------------------------------------------------------------------
2    Copyright 2006 Olivier Berlanger
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  package net.sf.xolite;
17  
18  
19  import java.util.Iterator;
20  
21  import javax.xml.namespace.NamespaceContext;
22  
23  
24  /**
25   * Interface for parsing XML with simplified event handling. This class is like a SAX parser keeping itself its state (locator,
26   * started elements, prefix mapping, characters, ...) rather than pushing it to a client handler. The result is a simpler document
27   * handler with only two methods remaining (@link XMLSerializable).
28   * <p>
29   * Although this interface is based on SAX mechanism, it's quite independent from SAX implementation. It doesn't expose any SAX
30   * class or interface.
31   * </p>
32   */
33  public interface XMLEventParser extends NamespaceContext {
34  
35      /**
36       * Get <code>NamespacePrefixResolver</code> mapping the prefix to the namespace URI. A copy of the current mapping object of
37       * this parser at the moment of the call is returned.
38       */
39      public NamespaceContext getCurrentDefinedNamespaces();
40  
41  
42      /**
43       * Delegates the parsing of a XML fragment to an other <code>SaxHandler</code>. When this handler have finished to parse the
44       * data belonging to it, it will call the <code>endParsing(..)</code> method and the current parser will receive again the XML
45       * parsing events. <br>
46       * This method should be called from inside a <code>startElement(..)</code> method, the same startElement method (with same
47       * parameters) is called against the delegated (handlerOfSubElements) object by the parser.
48       * 
49       * @param handlerOfSubElements
50       *            the XMLSerializable that will receive the next 'simplified SAX' events from the XMLEventParser.
51       */
52      public void delegateParsingTo(XMLSerializable handlerOfSubElements) throws XMLParseException;
53  
54  
55      /**
56       * Create the XMLSerializable object corresponding to the given XML element, delegates the parsing to it and return the created
57       * object. <br>
58       * Note: when returned the created object has not yet finished it's parsing. Only the first startElement(..) method has been
59       * called on it. <br>
60       * This method will work only if there is a factory defined and this factory knows the given element. It is equivalent to:
61       * 
62       * <pre>
63       * XMLSerializable child = parser.getFactory().createObject(uri, localName, parser);
64       * parser.delegateParsingTo(child, uri, localName);
65       * return child;
66       * </pre>
67       */
68      public XMLSerializable parseElement(String uri, String localName) throws XMLParseException;
69  
70  
71      /**
72       * Get the last object that called <code>endParsing(..)</code> method on the parser.
73       * 
74       * @return the last object that called <code>endParsing(..)</code> method on the parser.
75       */
76      public XMLSerializable getLastParsedObject() throws XMLParseException;
77  
78  
79      /**
80       * Resolve a qualified name to it's namespace URI + local name. As the SAX parser does it automatically for elements tags or
81       * attributes, this method is useful only for elements/attributes values containing qualified names.
82       * <p>
83       * To map the prefix, this method will use the prefix mappings of the parsed document. If no prefix mapping is defined for a
84       * given prefix, an exception is thrown. When no prefix is defined, this method will try to find the default prefix mapping, but
85       * if no default mapping is defined, no exception is thrown (in this case, the URI of the returned <code>NamespacedName</code>
86       * is null).
87       * 
88       * @param qName
89       *            a qualified name (like: "xs:element").
90       * @return NamespacedName containing the namespace URI and the local name of the given qualified name. (the prefix is not kept).
91       * @throws XMLParseException
92       *             If the qualified name contains a prefix not mapped to a namespace.
93       */
94      public NamespacedName getQualifiedName(String qName) throws XMLParseException;
95  
96  
97      /**
98       * Get the content of the text buffer. Usually, this method is called when the end of the element (containing the text) is
99       * notified by a SAX event.
100      * <p>
101      * <b> Use the ElementText helper class to get, parse, validate and format easily the element text. </b>
102      * </p>
103      * <p>
104      * Calling this method from a <code>startElement</code> notification is useful only when parsing XML with mixed content. In this
105      * case you got the text just before the started element.
106      * </p>
107      * 
108      * @return the text data of the current XML element.
109      */
110     public String getElementText();
111 
112 
113     /**
114      * Get a factory able to instantiate objects corresponding to XML elements. This method never returns null, if the factory is
115      * not defined an exception is thrown.
116      * 
117      * @return a factory able to instantiate objects corresponding to XML elements.
118      * @throws XMLParseException
119      *             if the factory is not defined.
120      */
121     public XMLObjectFactory getFactory() throws XMLParseException;
122 
123 
124     /**
125      * Put a custom object in an internal Map. <br>
126      * It can be retrieved later with <code>getCustomObject(key)</code> method.
127      * 
128      * @param key
129      *            key of the custom object.
130      * @param value
131      *            custom object.
132      */
133     public void putCustomObject(Object key, Object value);
134 
135 
136     /**
137      * Get back any custom object that was put in with the <code>putCustomObject(key, value)</code> method.
138      * 
139      * @param key
140      *            key of the custom object.
141      * @return the custom object.
142      */
143     public Object getCustomObject(Object key);
144 
145 
146     /**
147      * Get the namespace URI and local name of the current element.
148      * 
149      * @return the namespace URI and local name of the current element.
150      */
151     public NamespacedName getCurrentElementName();
152 
153 
154     /**
155      * 'true' iff the <code>startElement</code> call is the first one called to the XMLSerializable currently receiving it. <br>
156      * This method can be useful for recursive XML when an object can contain itself. In this case, when <code>startElement</code>
157      * is called the parsed object can use this method to know if the notified event is the start of itself or the start of a direct
158      * sub-object. <br>
159      * Calling this method makes sense only from inside a <code>startElement</code> method implementation.
160      * 
161      * @return true iff it's the first time <code>startElement</code> is called against the XMLSerializable.
162      */
163     public boolean isFirstEvent();
164 
165 
166     /**
167      * 'true' iff the <code>endElement</code> call is the last one called to the XMLSerializable currently receiving it. <br>
168      * This method can be useful for recursive XML when an object can contain itself. In this case, when <code>endElement</code> is
169      * called, the parsed object can use this method to know if the notified event is the end of itself or the end of a direct
170      * sub-object. <br>
171      * Calling this method makes sense only from inside a <code>endElement</code> method implementation.
172      * 
173      * @return true iff it's the first time <code>startElement</code> is called against the XMLSerializable.
174      */
175     public boolean isLastEvent();
176 
177 
178     // --------------------------------- Exception management -----------------------------------
179 
180     /**
181      * Throw an exception telling that the namespace of the current element (the one that was just passed to a
182      * <code>startElement(..)</code> or <code>endElement(..)</code> method) is unexpected. If the expected namespace URI is passed
183      * as parameter, it is added in the message. <br>
184      * The current location of the parser (current element tag, current line, current column, file name) is added to the message if
185      * available.
186      * 
187      * @param expectedURI
188      *            the expected namespace URI. If null, no expected namespace URI is mentioned in the exception message.
189      */
190     public void throwUnexpectedNamespaceException(String expectedURI) throws XMLParseException;
191 
192 
193     /**
194      * Throw an exception telling that the current element (the one that was just passed to a <code>startElement(..)</code> or
195      * <code>endElement(..)</code> method) is unexpected. If the expected tags are passed as parameter, they are added in the
196      * message. <br>
197      * The current location of the parser (current element tag, current line, current column, file name) is added to the message if
198      * available.
199      * 
200      * @param expectedTags
201      *            the expected element tag(s). If you expect several different tags, you can enumerate them in this parameter (for
202      *            example by separating them with commas). It is simply added in the exception message. If null, no expected tags
203      *            are mentioned in the exception message.
204      */
205     public void throwUnexpectedElementException(String expectedTags) throws XMLParseException;
206 
207 
208     /**
209      * Throw an exception with given message and cause. <br>
210      * The current location of the parser (current element tag, current line, current column, file name) is added to the message if
211      * available.
212      * 
213      * @param message
214      *            the exception message (rem: parser location is added).
215      * @param cause
216      *            the exception cause
217      */
218     public void throwParseException(String message, Throwable cause) throws XMLParseException;
219 
220 
221     // --------------------------------- Attribute management -----------------------------------
222 
223     /**
224      * Get an attribute value. If the requested attribute is not defined (because it is optional), null is returned.
225      * 
226      * @param attrName
227      *            the name of the attribute.
228      * @return the requested attribute value.
229      */
230     public String getAttributeValue(String attrName) throws XMLParseException;
231 
232 
233     /**
234      * Get value of an attribute with namespace. If the requested attribute is not defined (because it is optional), the null is
235      * returned.
236      * <p>
237      * This method allows to specify the namespace of the attribute. In most of the case attributes are not associated to
238      * namespaces. It is not necessary because attributes definitions are, in most of the case, local to the definition of the
239      * element containing it. So this method should be rarely used (use the corresponding method without namespace parameter).
240      * Examples of attributes using namespaces are: 'xml:lang' or 'xmlns:prefix'. To get values of those attributes you must provide
241      * the namespace URI.
242      * </p>
243      * 
244      * @param attrNamespaceURI
245      *            the namespace URI of the attribute.
246      * @param attrName
247      *            the name of the attribute.
248      * @return the requested attribute value.
249      */
250     public String getAttributeValueNS(String attrNamespaceURI, String attrName) throws XMLParseException;
251 
252 
253     /**
254      * Get an iterator on namespaces of all the attributes present in the current element. <br>
255      * 
256      * @return Iterator on namespaces of all the attributes present in the current element.
257      */
258     public Iterator<String> getAttributeNamespaceIterator() throws XMLParseException;
259 
260 
261     /**
262      * Get an iterator on names of all the attributes present in the current element and belonging to the given namespace. <br>
263      * Use <code>null</code> as namespace for attributes not bound to a namespace (i.e. most of the attributes).
264      * 
265      * @param attrNamespaceURI
266      *            namespace of the attributes or <code>null</code> for attributes without namespaces.
267      * @return Iterator on names of all the attributes present in the current element and belonging to the given namespace.
268      */
269     public Iterator<String> getAttributeNameIterator(String attrNamespaceURI) throws XMLParseException;
270 
271 }