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