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