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 <?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 * <!-- 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 *
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 >)
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