KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > impl > XMLWriterImpl


1 /*
2  * Copyright 2003, 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.ws.jaxme.impl;
17
18 import org.apache.ws.jaxme.XMLWriter;
19 import org.xml.sax.Attributes JavaDoc;
20 import org.xml.sax.Locator JavaDoc;
21 import org.xml.sax.SAXException JavaDoc;
22
23 import java.io.IOException JavaDoc;
24 import java.io.Writer JavaDoc;
25
26 import javax.xml.XMLConstants JavaDoc;
27 import javax.xml.bind.JAXBException;
28
29
30 /** <p>A simple serializer for XML documents.</p>
31  *
32  * @author <a HREF="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
33  */

34 public class XMLWriterImpl implements XMLWriter {
35   private JMMarshallerImpl m;
36   private Writer w;
37   private Locator JavaDoc l;
38   private java.util.Map JavaDoc delayedPrefixes;
39   int curIndent = 0;
40
41   private static final int STATE_OUTSIDE = 0;
42   private static final int STATE_IN_START_ELEMENT = 1;
43   private static final int STATE_IN_ELEMENT = 2;
44   private int state;
45
46   /** Creates a new JaxbXmlSerializer */
47   public XMLWriterImpl() {}
48
49   /** <p>Sets the JaxbXMLSerializers Marshaller.</p>
50    */

51   public void init(JMMarshallerImpl pMarshaller) throws JAXBException {
52     m = pMarshaller;
53   }
54
55   /** <p>Returns the JaxbXMLSerializers Marshaller.</p>
56    */

57   public JMMarshallerImpl getMarshaller() {
58     return m;
59   }
60
61   /** <p>Sets the JaxbXMLSerializers Writer.</p>
62    */

63   public void setWriter(Writer pWriter) throws JAXBException {
64     w = pWriter;
65   }
66   /** <p>Returns the JaxbXMLSerializers Writer.</p>
67    */

68   public Writer getWriter() {
69     return w;
70   }
71
72   /** Sets the locator.
73    *
74    * @param pLocator A locator for use in case of errors
75    * @see #getDocumentLocator
76    */

77   public void setDocumentLocator(Locator JavaDoc pLocator) { l = pLocator; }
78
79   /** Returns the locator
80    * @return A locator previously set with setDocumentLocator or null.
81    * @see #setDocumentLocator
82    */

83   public Locator JavaDoc getDocumentLocator() { return l; }
84
85   /**
86    * <p>Starts use of a namespace prefix.</p>
87    *
88    * @param namespaceURI The namespace URI
89    * @param prefix The prefix
90    * @throws SAXException Not actually thrown, just for compliance to the interface specification.
91    */

92   public void startPrefixMapping(String JavaDoc prefix, String JavaDoc namespaceURI)
93       throws SAXException JavaDoc {
94     if (delayedPrefixes == null) {
95       delayedPrefixes = new java.util.HashMap JavaDoc();
96     }
97     if ("".equals(prefix)) {
98       if (namespaceURI.equals(prefix)) {
99         return;
100       }
101       prefix = XMLConstants.XMLNS_ATTRIBUTE;
102     } else {
103       prefix = XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix;
104     }
105     delayedPrefixes.put(prefix, namespaceURI);
106   }
107
108   /** <p>Terminates use of a namespace prefix.</p>
109    *
110    * @param prefix The prefix being abandoned.
111    * @throws SAXException Not actually thrown, just for compliance to the interface specification.
112    */

113   public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc {
114     if (delayedPrefixes != null) {
115       if ("".equals(prefix)) {
116         prefix = XMLConstants.XMLNS_ATTRIBUTE;
117       } else {
118         prefix = XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix;
119       }
120       delayedPrefixes.remove(prefix);
121     }
122   }
123
124   /** <p>Starts a document.</p>
125    * @throws SAXException Not actually thrown, just for compliance to the interface specification.
126    */

127   public void startDocument() throws SAXException JavaDoc {
128     if (delayedPrefixes != null) {
129       delayedPrefixes.clear();
130     }
131     state = STATE_OUTSIDE;
132     curIndent = 0;
133   }
134
135   /** <p>This method finishs the handlers action. After calling endDocument you
136    * may start a new action by calling startDocument again.</p>
137    *
138    * @throws SAXException Not actually thrown, just for compliance to the
139    * interface specification.
140    */

141   public void endDocument() throws SAXException JavaDoc {}
142
143   /** Calls the character method with the same arguments.
144    * @param ch A string of whitespace characters being inserted into the document.
145    * @param start The index of the first character.
146    * @param length The number of characters.
147    * @throws SAXException Thrown in case of an IOException.
148    */

149   public void ignorableWhitespace(char[] ch, int start, int length)
150       throws SAXException JavaDoc {
151     characters(ch, start, length);
152   }
153
154   private void stopTerminator() throws java.io.IOException JavaDoc {
155     if (state == STATE_IN_START_ELEMENT) {
156       if (w != null) {
157         w.write('>');
158       }
159       state = STATE_IN_ELEMENT;
160     }
161   }
162
163   /** Inserts a string of characters into the document.
164    * @param ch The characters being inserted. A substring, to be precise.
165    * @param start Index of the first character
166    * @param length Number of characters being inserted
167    * @throws SAXException Thrown in case of an IOException
168    */

169   public void characters(char[] ch, int start, int length) throws SAXException JavaDoc {
170     try {
171       stopTerminator();
172       if (w == null) return;
173       int end = start+length;
174       for (int i = start; i < end; i++) {
175         char c = ch[i];
176         switch (c) {
177           case '&': w.write("&amp;"); break;
178           case '<': w.write("&lt;"); break;
179           case '>': w.write("&gt;"); break;
180           case '\n':
181           case '\r':
182           case '\t':
183              w.write(c); break;
184           default:
185             if (canEncode(c)) {
186               w.write(c);
187             } else {
188               w.write("&#");
189               w.write(Integer.toString(c));
190               w.write(";");
191             }
192             break;
193         }
194       }
195     } catch (IOException JavaDoc e) {
196       throw new SAXException JavaDoc(e);
197     }
198   }
199
200   public boolean canEncode(char c) {
201     return c > 31 && c < 127;
202   }
203
204
205   /** <p>Terminates an element.</p>
206    *
207    * @param namespaceURI The namespace URI, if any, or null
208    * @param localName The local name, without prefix, or null
209    * @param qName The qualified name, including a prefix, or null
210    * @throws SAXException Thrown in case of an IOException.
211    */

212   public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
213       throws SAXException JavaDoc {
214     if (m != null && m. getIndentation()) {
215       --curIndent;
216     }
217     if (w != null) {
218       try {
219         if (state == STATE_IN_START_ELEMENT) {
220           w.write("/>");
221           state = STATE_OUTSIDE;
222         } else {
223           if (state == STATE_OUTSIDE) {
224             indentMe();
225           }
226           w.write("</");
227           w.write(qName);
228           w.write('>');
229         }
230         state = STATE_OUTSIDE;
231       } catch (java.io.IOException JavaDoc e) {
232         throw new SAXException JavaDoc(e);
233       }
234     }
235   }
236
237   private void indentMe() throws java.io.IOException JavaDoc {
238     if (w != null) {
239       if (m != null && m.getIndentation()) {
240         String JavaDoc s = m.getIndentationSeparator();
241         if (s != null) {
242           w.write(s);
243         }
244         s = m.getIndentationString();
245         for (int i = 0; i < curIndent; i++) {
246           w.write(s);
247         }
248       }
249     }
250   }
251
252   private void writeCData(String JavaDoc v) throws java.io.IOException JavaDoc {
253     int len = v.length();
254     for (int j = 0; j < len; j++) {
255       char c = v.charAt(j);
256       switch (c) {
257         case '&': w.write("&amp;"); break;
258         case '<': w.write("&lt;"); break;
259         case '>': w.write("&gt;"); break;
260         case '\'': w.write("&apos;"); break;
261         case '"': w.write("&quot;"); break;
262         default:
263           if (canEncode(c)) {
264             w.write(c);
265           } else {
266             w.write("&#");
267             w.write(Integer.toString(c));
268             w.write(';');
269           }
270           break;
271       }
272     }
273   }
274
275   /** Starts a new element.
276    *
277    * @param namespaceURI The namespace URI, if any, or null
278    * @param localName The local name, without prefix, or null
279    * @param qName The qualified name, including a prefix, or null
280    * @param attr The element attributes
281    * @throws SAXException Thrown in case of an IOException.
282    */

283   public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName,
284                            Attributes JavaDoc attr) throws SAXException JavaDoc {
285     try {
286       stopTerminator();
287       if (m != null && m.getIndentation()) {
288         if (curIndent > 0) {
289           indentMe();
290         }
291         curIndent++;
292       }
293
294       if (w != null) {
295         w.write('<');
296         w.write(qName);
297         if (attr != null) {
298           for (int i = attr.getLength(); i > 0;) {
299             w.write(' ');
300             String JavaDoc name = attr.getQName(--i);
301             w.write(name);
302             if (delayedPrefixes != null) {
303               delayedPrefixes.remove(name);
304             }
305             w.write("=\"");
306             writeCData(attr.getValue(i));
307             w.write('"');
308           }
309         }
310         if (delayedPrefixes != null && delayedPrefixes.size() > 0) {
311           for (java.util.Iterator JavaDoc iter = delayedPrefixes.entrySet().iterator();
312                iter.hasNext(); ) {
313             java.util.Map.Entry entry = (java.util.Map.Entry) iter.next();
314             w.write(' ');
315             w.write((String JavaDoc) entry.getKey());
316             w.write("=\"");
317             w.write((String JavaDoc) entry.getValue());
318             w.write('"');
319           }
320           delayedPrefixes.clear();
321         }
322       }
323       state = STATE_IN_START_ELEMENT;
324     } catch (java.io.IOException JavaDoc e) {
325       throw new SAXException JavaDoc(e);
326     }
327   }
328
329   /** Not actually implemented, because I don't know how to skip entities.
330    *
331    * @param ent The entity being skipped.
332    * @throws SAXException Not actually thrown, just for compliance to the interface specification.
333    */

334   public void skippedEntity(String JavaDoc ent) throws SAXException JavaDoc {
335     throw new SAXException JavaDoc("Don't know how to skip entities");
336   }
337     
338   /** Inserts a processing instruction.
339    *
340    * @param target The PI target
341    * @param data The PI data
342    * @throws SAXException Thrown in case of an IOException
343    */

344   public void processingInstruction(String JavaDoc target, String JavaDoc data)
345       throws SAXException JavaDoc {
346     try {
347       stopTerminator();
348       if (w != null) {
349         w.write("<?");
350         w.write(target);
351         w.write(' ');
352         w.write(data);
353         w.write("?>");
354       }
355     } catch (java.io.IOException JavaDoc e) {
356       throw new SAXException JavaDoc(e);
357     }
358   }
359 }
360
Popular Tags