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 }