View Javadoc

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