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 }