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 }