1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/ 2 // for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/) 3 4 package org.codehaus.plexus.util.xml.pull; 5 6 import java.io.IOException; 7 import java.io.OutputStream; 8 import java.io.Writer; 9 10 /** 11 * Define an interface to serialization of XML Infoset. This interface abstracts away if serialized XML is XML 1.0 12 * compatible text or other formats of XML 1.0 serializations (such as binary XML for example with WBXML). 13 * <p> 14 * <b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API. It is included as basis for discussion. It may 15 * change in any way. 16 * <p> 17 * Exceptions that may be thrown are: IOException or runtime exception (more runtime exceptions can be thrown but are 18 * not declared and as such have no semantics defined for this interface): 19 * <ul> 20 * <li><em>IllegalArgumentException</em> - for almost all methods to signal that argument is illegal 21 * <li><em>IllegalStateException</em> - to signal that call has good arguments but is not expected here (violation of 22 * contract) and for features/properties when requesting setting unimplemented feature/property 23 * (UnsupportedOperationException would be better but it is not in MIDP) 24 * </ul> 25 * <p> 26 * <b>NOTE:</b> writing CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE, PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some 27 * implementations may not be supported (for example when serializing to WBXML). In such case IllegalStateException will 28 * be thrown and it is recommended to use an optional feature to signal that implementation is not supporting this kind 29 * of output. 30 */ 31 public interface XmlSerializer { 32 33 /** 34 * Set feature identified by name (recommended to be URI for uniqueness). Some well known optional features are 35 * defined in <a href="http://www.xmlpull.org/v1/doc/features.html"> 36 * http://www.xmlpull.org/v1/doc/features.html</a>. If feature is not recognized or can not be set then 37 * IllegalStateException MUST be thrown. 38 * @param name feature name 39 * @param state feature state 40 * @exception IllegalStateException If the feature is not supported or can not be set 41 */ 42 void setFeature(String name, boolean state) throws IllegalArgumentException, IllegalStateException; 43 44 /** 45 * Return the current value of the feature with given name. 46 * <p> 47 * <strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null 48 * 49 * @param name The name of feature to be retrieved. 50 * @return The value of named feature. 51 * @exception IllegalArgumentException if feature string is null 52 */ 53 boolean getFeature(String name); 54 55 /** 56 * Set the value of a property. (the property name is recommended to be URI for uniqueness). Some well known 57 * optional properties are defined in <a href="http://www.xmlpull.org/v1/doc/properties.html"> 58 * http://www.xmlpull.org/v1/doc/properties.html</a>. If property is not recognized or can not be set then 59 * IllegalStateException MUST be thrown. 60 * @param name property name 61 * @param value property value 62 * @exception IllegalStateException if the property is not supported or can not be set 63 */ 64 void setProperty(String name, Object value) throws IllegalArgumentException, IllegalStateException; 65 66 /** 67 * Look up the value of a property. The property name is any fully-qualified URI. I 68 * <p> 69 * <strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null 70 * 71 * @param name The name of property to be retrieved. 72 * @return The value of named property. 73 */ 74 Object getProperty(String name); 75 76 /** 77 * Set to use binary output stream with given encoding. 78 * @param os out 79 * @param encoding encoding 80 * @throws IOException io 81 * @throws IllegalArgumentException if null 82 * @throws IllegalStateException illegal use 83 */ 84 void setOutput(OutputStream os, String encoding) 85 throws IOException, IllegalArgumentException, IllegalStateException; 86 87 /** 88 * @param writer Set the output to the given writer. 89 * <p> 90 * <b>WARNING</b> no information about encoding is available! 91 * @throws IOException io 92 * @throws IllegalArgumentException if null 93 * @throws IllegalStateException illegal use 94 */ 95 void setOutput(Writer writer) throws IOException, IllegalArgumentException, IllegalStateException; 96 97 /** 98 * Write <?xml declaration with encoding (if encoding not null) and standalone flag (if standalone not null) 99 * This method can only be called just after setOutput. 100 * @param encoding document encoding 101 * @param standalone standalone flag value 102 * @throws IOException io 103 * @throws IllegalArgumentException if null 104 * @throws IllegalStateException illegal use 105 */ 106 void startDocument(String encoding, Boolean standalone) 107 throws IOException, IllegalArgumentException, IllegalStateException; 108 109 /** 110 * Finish writing. All unclosed start tags will be closed and output will be flushed. After calling this method no 111 * more output can be serialized until next call to setOutput() 112 * @throws IOException io 113 * @throws IllegalArgumentException if null 114 * @throws IllegalStateException illegal use 115 */ 116 void endDocument() throws IOException, IllegalArgumentException, IllegalStateException; 117 118 /** 119 * Binds the given prefix to the given namespace. This call is valid for the next element including child elements. 120 * The prefix and namespace MUST be always declared even if prefix is not used in element (startTag() or 121 * attribute()) - for XML 1.0 it must result in declaring <code>xmlns:prefix='namespace'</code> (or 122 * <code>xmlns:prefix="namespace"</code> depending what character is used to quote attribute value). 123 * <p> 124 * <b>NOTE:</b> this method MUST be called directly before startTag() and if anything but startTag() or setPrefix() 125 * is called next there will be exception. 126 * <p> 127 * <b>NOTE:</b> prefixes "xml" and "xmlns" are already bound and can not be redefined see: 128 * <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>. 129 * <p> 130 * <b>NOTE:</b> to set default namespace use as prefix empty string. 131 * 132 * @param prefix must be not null (or IllegalArgumentException is thrown) 133 * @param namespace must be not null 134 * @throws IOException io 135 * @throws IllegalArgumentException if null 136 * @throws IllegalStateException illegal use 137 */ 138 void setPrefix(String prefix, String namespace) throws IOException, IllegalArgumentException, IllegalStateException; 139 140 /** 141 * @return namespace that corresponds to given prefix If there is no prefix bound to this namespace return null but 142 * if generatePrefix is false then return generated prefix. 143 * <p> 144 * <b>NOTE:</b> if the prefix is empty string "" and default namespace is bound to this prefix then empty string 145 * ("") is returned. 146 * <p> 147 * <b>NOTE:</b> prefixes "xml" and "xmlns" are already bound will have values as defined 148 * <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a> 149 * @param namespace the namespace 150 * @param generatePrefix to generate the missing prefix 151 * @throws IllegalArgumentException if null 152 */ 153 String getPrefix(String namespace, boolean generatePrefix) throws IllegalArgumentException; 154 155 /** 156 * @return the current depth of the element. Outside the root element, the depth is 0. The depth is incremented by 1 157 * when startTag() is called. The depth is decremented after the call to endTag() event was observed. 158 * 159 * <pre> 160 * <!-- outside --> 0 161 * <root> 1 162 * sometext 1 163 * <foobar> 2 164 * </foobar> 2 165 * </root> 1 166 * <!-- outside --> 0 167 * </pre> 168 */ 169 int getDepth(); 170 171 /** 172 * Returns the namespace URI of the current element as set by startTag(). 173 * <p> 174 * <b>NOTE:</b> that means in particular that: 175 * <ul> 176 * <li>if there was startTag("", ...) then getNamespace() returns "" 177 * <li>if there was startTag(null, ...) then getNamespace() returns null 178 * </ul> 179 * 180 * @return namespace set by startTag() that is currently in scope 181 */ 182 String getNamespace(); 183 184 /** 185 * Returns the name of the current element as set by startTag(). It can only be null before first call to startTag() 186 * or when last endTag() is called to close first startTag(). 187 * 188 * @return namespace set by startTag() that is currently in scope 189 */ 190 String getName(); 191 192 /** 193 * Writes a start tag with the given namespace and name. If there is no prefix defined for the given namespace, a 194 * prefix will be defined automatically. The explicit prefixes for namespaces can be established by calling 195 * setPrefix() immediately before this method. If namespace is null no namespace prefix is printed but just name. If 196 * namespace is empty string then serializer will make sure that default empty namespace is declared (in XML 1.0 197 * xmlns='') or throw IllegalStateException if default namespace is already bound to non-empty string. 198 * @param namespace ns 199 * @param name tag name 200 * @return XmlSerializer 201 * @throws IOException io 202 * @throws IllegalArgumentException if null 203 * @throws IllegalStateException illegal use 204 */ 205 XmlSerializer startTag(String namespace, String name) 206 throws IOException, IllegalArgumentException, IllegalStateException; 207 208 /** 209 * Write an attribute. Calls to attribute() MUST follow a call to startTag() immediately. If there is no prefix 210 * defined for the given namespace, a prefix will be defined automatically. If namespace is null or empty string no 211 * namespace prefix is printed but just name. 212 * @param name attribute name 213 * @param value attribute value 214 * @param namespace namespace to use 215 * @return XmlSerializer 216 * @throws IOException io 217 * @throws IllegalArgumentException if null 218 * @throws IllegalStateException illegal use 219 */ 220 XmlSerializer attribute(String namespace, String name, String value) 221 throws IOException, IllegalArgumentException, IllegalStateException; 222 223 /** 224 * Write end tag. Repetition of namespace and name is just for avoiding errors. 225 * <b>Background:</b> in kXML endTag had no arguments, and non matching tags were very difficult to find... If 226 * namespace is null no namespace prefix is printed but just name. If namespace is empty string then serializer will 227 * make sure that default empty namespace is declared (in XML 1.0 xmlns=''). 228 * @param namespace ns 229 * @param name tag name 230 * @return XmlSerializer 231 * @throws IOException io 232 * @throws IllegalArgumentException if null 233 * @throws IllegalStateException illegal use 234 */ 235 XmlSerializer endTag(String namespace, String name) 236 throws IOException, IllegalArgumentException, IllegalStateException; 237 238 // /** 239 // * Writes a start tag with the given namespace and name. 240 // * <br />If there is no prefix defined (prefix == null) for the given namespace, 241 // * a prefix will be defined automatically. 242 // * <br />If explicit prefixes is passed (prefix != null) then it will be used 243 // *and namespace declared if not already declared or 244 // * throw IllegalStateException the same prefix was already set on this 245 // * element (setPrefix()) and was bound to different namespace. 246 // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown. 247 // * <br />If namespace is null then no namespace prefix is printed but just name. 248 // * <br />If namespace is empty string then serializer will make sure that 249 // * default empty namespace is declared (in XML 1.0 xmlns='') 250 // * or throw IllegalStateException if default namespace is already bound 251 // * to non-empty string. 252 // */ 253 // XmlSerializer startTag (String prefix, String namespace, String name) 254 // throws IOException, IllegalArgumentException, IllegalStateException; 255 // 256 // /** 257 // * Write an attribute. Calls to attribute() MUST follow a call to 258 // * startTag() immediately. 259 // * <br />If there is no prefix defined (prefix == null) for the given namespace, 260 // * a prefix will be defined automatically. 261 // * <br />If explicit prefixes is passed (prefix != null) then it will be used 262 // * and namespace declared if not already declared or 263 // * throw IllegalStateException the same prefix was already set on this 264 // * element (setPrefix()) and was bound to different namespace. 265 // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown. 266 // * <br />If namespace is null then no namespace prefix is printed but just name. 267 // * <br />If namespace is empty string then serializer will make sure that 268 // * default empty namespace is declared (in XML 1.0 xmlns='') 269 // * or throw IllegalStateException if default namespace is already bound 270 // * to non-empty string. 271 // */ 272 // XmlSerializer attribute (String prefix, String namespace, String name, String value) 273 // throws IOException, IllegalArgumentException, IllegalStateException; 274 // 275 // /** 276 // * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors. 277 // * <br />If namespace or name arguments are different from corresponding startTag call 278 // * then IllegalArgumentException is thrown, if prefix argument is not null and is different 279 // * from corresponding starTag then IllegalArgumentException is thrown. 280 // * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown. 281 // * <br />If namespace is null then no namespace prefix is printed but just name. 282 // * <br />If namespace is empty string then serializer will make sure that 283 // * default empty namespace is declared (in XML 1.0 xmlns=''). 284 // * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were 285 // * very difficult to find...</p> 286 // */ 287 // ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking 288 // XmlSerializer endTag (String prefix, String namespace, String name) 289 // throws IOException, IllegalArgumentException, IllegalStateException; 290 291 /** 292 * @param text Writes text, where special XML chars are escaped automatically 293 * @return XmlSerializer 294 * @throws IOException io 295 * @throws IllegalArgumentException if null 296 * @throws IllegalStateException illegal use 297 */ 298 XmlSerializer text(String text) throws IOException, IllegalArgumentException, IllegalStateException; 299 300 /** 301 * Writes text, where special XML chars are escaped automatically 302 * @param buf characters 303 * @param len lenght 304 * @param start start 305 * @return XmlSerializer 306 * @throws IOException io 307 * @throws IllegalArgumentException if null 308 * @throws IllegalStateException illegal use 309 */ 310 XmlSerializer text(char[] buf, int start, int len) 311 throws IOException, IllegalArgumentException, IllegalStateException; 312 313 void cdsect(String text) throws IOException, IllegalArgumentException, IllegalStateException; 314 315 void entityRef(String text) throws IOException, IllegalArgumentException, IllegalStateException; 316 317 void processingInstruction(String text) throws IOException, IllegalArgumentException, IllegalStateException; 318 319 void comment(String text) throws IOException, IllegalArgumentException, IllegalStateException; 320 321 void docdecl(String text) throws IOException, IllegalArgumentException, IllegalStateException; 322 323 void ignorableWhitespace(String text) throws IOException, IllegalArgumentException, IllegalStateException; 324 325 /** 326 * Write all pending output to the stream. If method startTag() or attribute() was called then start tag is closed 327 * (final >) before flush() is called on underlying output stream. 328 * <p> 329 * <b>NOTE:</b> if there is need to close start tag (so no more attribute() calls are allowed) but without flushing 330 * output call method text() with empty string (text("")). 331 * @throws IOException io 332 */ 333 void flush() throws IOException; 334 }