KickJava   Java API By Example, From Geeks To Geeks.

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


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  */

17 package org.apache.ws.jaxme.impl;
18
19 import java.io.IOException JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.io.OutputStreamWriter JavaDoc;
22 import java.io.UnsupportedEncodingException JavaDoc;
23 import java.io.Writer JavaDoc;
24
25 import javax.xml.bind.JAXBException;
26 import javax.xml.bind.MarshalException;
27 import javax.xml.bind.Marshaller;
28 import javax.xml.bind.PropertyException;
29 import javax.xml.namespace.QName JavaDoc;
30 import javax.xml.transform.Result JavaDoc;
31 import javax.xml.transform.dom.DOMResult JavaDoc;
32 import javax.xml.transform.sax.SAXResult JavaDoc;
33 import javax.xml.transform.stream.StreamResult JavaDoc;
34
35 import org.apache.ws.jaxme.*;
36 import org.apache.ws.jaxme.JMElement;
37 import org.apache.ws.jaxme.JMMarshaller;
38 import org.apache.ws.jaxme.util.DOMBuilder;
39 import org.w3c.dom.Node JavaDoc;
40 import org.xml.sax.ContentHandler JavaDoc;
41 import org.xml.sax.SAXException JavaDoc;
42
43
44 /**
45  * @author <a HREF="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
46  * @version $Id: JMMarshallerImpl.java,v 1.11 2005/03/10 10:14:03 jochen Exp $
47  */

48 public class JMMarshallerImpl extends JMControllerImpl implements JMMarshaller {
49   /** Default value for {@link Marshaller#JAXB_ENCODING}.
50    * (UTF-8 encoding)
51    */

52   public static final String JavaDoc DEFAULT_JAXB_ENCODING = "UTF-8";
53
54   /** Default value for {@link #JAXME_INDENTATION_STRING}: Two blanks.
55    */

56   public static final String JavaDoc DEFAULT_JAXME_INDENTATION_STRING = " ";
57
58   /** Default value for {@link #JAXME_INDENTATION_SEPARATOR}.
59    * ("\n", Line Feed)
60    */

61   public static final String JavaDoc DEFAULT_JAXME_INDENTATION_SEPARATOR = "\n";
62
63   /** Property name for setting the String used to indent
64    * the formatted output by one level.
65    * ("jaxme.indentation.string")
66    * Defaults to {@link #DEFAULT_JAXME_INDENTATION_STRING}.
67    *
68    * @see #setIndentationString
69    * @see #getIndentationString
70    */

71   public static final String JavaDoc JAXME_INDENTATION_STRING = "jaxme.indentation.string";
72
73   /** Property name for setting the String used as a
74    * line separator in the formatted output.
75    * ("jaxme.indentation.separator")
76    *
77    * @see #setIndentationSeparator
78    * @see #getIndentationSeparator
79    */

80   public static final String JavaDoc JAXME_INDENTATION_SEPARATOR = "jaxme.indentation.separator";
81
82   /** Property name for choosing whether the marshalled
83    * output should contain an XML declaration. The methods
84    * {@link #marshal(Object, OutputStream)} and
85    * {@link #marshal(Object, Writer)} recognize
86    * requests for XML declarations.
87    *
88    * @see #setXmlDeclaration(boolean)
89    * @see #getXmlDeclaration
90    */

91   public static final String JavaDoc JAXME_XML_DECLARATION = "jaxme.xml.declaration";
92
93   /** Property name for a SAX {@link ContentHandler} which is able to
94    * marshal a SAX stream into a character stream. The property value is
95    * an instance of {@link Class} implementing {@link XMLWriter}.
96    */

97   public static final String JavaDoc JAXME_XML_WRITER = "jaxme.xml.writer";
98
99   private static final Class JavaDoc xmlWriterClassDefault;
100
101   static {
102     Class JavaDoc c;
103     try {
104         c = Class.forName("org.apache.ws.jaxme.impl.CharSetXMLWriter");
105     } catch (Exception JavaDoc e) {
106         c = XMLWriterImpl.class;
107     }
108     xmlWriterClassDefault = c;
109   }
110
111   private String JavaDoc encoding = DEFAULT_JAXB_ENCODING;
112   private boolean indentation = true;
113   private String JavaDoc indentationString = DEFAULT_JAXME_INDENTATION_STRING;
114   private String JavaDoc indentationSeparator = DEFAULT_JAXME_INDENTATION_SEPARATOR;
115   private boolean xmlDeclaration = true;
116   private Class JavaDoc xmlWriterClass;
117   private String JavaDoc noNamespaceSchemaLocation, schemaLocation;
118
119   /** Sets the controllers encoding; to be used in
120    * marshalling. Defaults to {@link #DEFAULT_JAXB_ENCODING}.
121    *
122    * @param pEncoding Suggested encoding or null to restore
123    * the default
124    */

125   public void setEncoding(String JavaDoc pEncoding) throws PropertyException {
126     if (pEncoding == null) {
127       pEncoding = DEFAULT_JAXB_ENCODING;
128     }
129     encoding = pEncoding;
130   }
131
132   /** Returns the controllers encoding; to be used in
133    * marshalling. Defaults to {@link #DEFAULT_JAXB_ENCODING}.
134    */

135   public String JavaDoc getEncoding() { return encoding; }
136
137   /** Sets the controllers class implementing {@link XMLWriter}.
138    * Defaults to {@link XMLWriterImpl}.
139    *
140    * @param pClass A class implementing {@link XMLWriterImpl} or
141    * null to restore the default.
142    */

143   public void setXMLWriterClass(Class JavaDoc pClass) throws PropertyException {
144     if (pClass == null) {
145       // Restore
146
xmlWriterClass = null;
147     } else if (XMLWriter.class.isAssignableFrom(pClass) && !pClass.isInterface()) {
148       xmlWriterClass = pClass;
149     } else {
150       throw new PropertyException("The class " + pClass.getName() + " is not implementing " + XMLWriter.class.getName());
151     }
152   }
153
154   /** <p>Returns the controllers class implementing {@link XMLWriter}.
155    * Defaults to {@link XMLWriterImpl}.</p>
156    */

157   public Class JavaDoc getXMLWriterClass() {
158     return xmlWriterClass == null ? xmlWriterClassDefault : xmlWriterClass;
159   }
160
161   /** <p>Sets whether XML documents generated by the controller
162    * ought to be formatted. Defaults to true.</p>
163    */

164   public void setIndentation(boolean pIndentation) {
165     indentation = pIndentation;
166   }
167
168   /** <p>Returns whether XML documents generated by the controller
169    * ought to be formatted. Defaults to true.</p>
170    */

171   public boolean getIndentation() {
172     return indentation;
173   }
174
175   /** <p>Sets whether the methods <code>marshal(Object, Writer)</code>
176    * and <code>marshal(Object, OutputStream)</code> ought to emit an
177    * XML declaration.</p>
178    */

179   public void setXmlDeclaration(boolean pDeclaration) {
180     xmlDeclaration = pDeclaration;
181   }
182
183   /** <p>Returns whether the methods <code>marshal(Object, Writer)</code>
184    * and <code>marshal(Object, OutputStream)</code> ought to emit an
185    * XML declaration.</p>
186    */

187   public boolean getXmlDeclaration() { return xmlDeclaration; }
188
189   /** <p>Sets the string used to indent one level. Defaults to
190    * {@link #DEFAULT_JAXME_INDENTATION_STRING}. Equivalent to
191    * <code>setProperty(JAXME_INDENTATION_STRING, pStr)</code>.</p>
192    *
193    * @see #DEFAULT_JAXME_INDENTATION_STRING
194    * @see #setProperty
195    * @see #getProperty
196    */

197   public void setIndentationString(String JavaDoc pStr) { indentationString = pStr; }
198
199   /** <p>Returns the string used to indent one level. Defaults to
200    * {@link #DEFAULT_JAXME_INDENTATION_STRING}. Equivalent to
201    * <code>getProperty(JAXME_INDENTATION_STRING)</code>.</p>
202    *
203    * @see #DEFAULT_JAXME_INDENTATION_STRING
204    * @see #setProperty
205    * @see #getProperty
206    */

207   public String JavaDoc getIndentationString() { return indentationString; }
208
209   /** <p>Sets the string used as a line separator. Defaults to
210    * {@link #DEFAULT_JAXME_INDENTATION_SEPARATOR}. Equivalent to
211    * <code>setProperty(JAXME_INDENTATION_SEPARATOR, pStr)</code>.</p>
212    *
213    * @see #DEFAULT_JAXME_INDENTATION_SEPARATOR
214    * @see #setProperty
215    * @see #getProperty
216    */

217   public void setIndentationSeparator(String JavaDoc pStr) { indentationSeparator = pStr; }
218
219   /** <p>Returns the string used as a line separator. Defaults to
220    * {@link #DEFAULT_JAXME_INDENTATION_SEPARATOR}. Equivalent to
221    * <code>getProperty(JAXME_INDENTATION_SEPARATOR)</code>.</p>
222    *
223    * @see #DEFAULT_JAXME_INDENTATION_SEPARATOR
224    * @see #setProperty
225    * @see #getProperty
226    */

227   public String JavaDoc getIndentationSeparator() { return indentationSeparator; }
228
229   /** <p>Sets the schema location. The marshaller will use this to
230    * create an attribute <code>xsi:schemaLocation</code>. Equivalent
231    * to <code>setProperty(JAXB_SCHEMA_LOCATION, pValue)</code>.
232    * Defaults to null, in which case the attribute isn't created.</p>
233    * @see Marshaller#JAXB_SCHEMA_LOCATION
234    * @see #setProperty(String, Object)
235    * @see #getSchemaLocation()
236    */

237   public void setSchemaLocation(String JavaDoc pValue) throws PropertyException {
238     if (pValue != null && noNamespaceSchemaLocation != null) {
239       throw new PropertyException("The properties schemaLocation and noNamespaceSchemaLocation are mutually exclusive.");
240     }
241     schemaLocation = pValue;
242   }
243
244   /** <p>Returns the schema location. The marshaller will use this to
245    * create an attribute <code>xsi:schemaLocation</code>. Equivalent
246    * to <code>setProperty(JAXB_SCHEMA_LOCATION, pValue)</code>.
247    * Defaults to null, in which case the attribute isn't created.</p>
248    * @see Marshaller#JAXB_SCHEMA_LOCATION
249    * @see #setProperty(String, Object)
250    * @see #setSchemaLocation(String)
251    */

252   public String JavaDoc getSchemaLocation() {
253     return schemaLocation;
254   }
255
256   /** <p>Sets the schema location without namespace. The marshaller
257    * will use this to create an attribute <code>xsi:noNamespaceSchemaLocation</code>.
258    * Equivalent to <code>setProperty(JAXB_NO_NAMESPACE_SCHEMA_LOCATION,
259    * pValue)</code>. Defaults to null, in which case the attribute isn't
260    * created.</p>
261    * @see Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
262    * @see #setProperty(String, Object)
263    * @see #getNoNamespaceSchemaLocation()
264    */

265   public void setNoNamespaceSchemaLocation(String JavaDoc pValue) throws PropertyException {
266     if (pValue != null && noNamespaceSchemaLocation != null) {
267       throw new PropertyException("The properties schemaLocation and noNamespaceSchemaLocation are mutually exclusive.");
268     }
269     noNamespaceSchemaLocation = pValue;
270   }
271
272   /** <p>Returns the schema location. The marshaller will use this to
273    * create an attribute <code>xsi:noNamespaceSchemaLocation</code>. Equivalent
274    * to <code>setProperty(JAXB_SCHEMA_LOCATION, pValue)</code>.
275    * Defaults to null, in which case the attribute isn't created.</p>
276    * @see Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
277    * @see #setProperty(String, Object)
278    * @see #setNoNamespaceSchemaLocation(String)
279    */

280   public String JavaDoc getNoNamespaceSchemaLocation() {
281     return noNamespaceSchemaLocation;
282   }
283
284   public void setProperty(String JavaDoc pProperty, Object JavaDoc pValue)
285       throws PropertyException {
286     if (pProperty.startsWith("jaxb.")) {
287       if (Marshaller.JAXB_ENCODING.equals(pProperty)) {
288         setEncoding((String JavaDoc) pValue);
289         return;
290       } else if (Marshaller.JAXB_FORMATTED_OUTPUT.equals(pProperty)) {
291         setIndentation(((Boolean JavaDoc) pValue).booleanValue());
292         return;
293       } else if (Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(pProperty)) {
294         setNoNamespaceSchemaLocation((String JavaDoc) pValue);
295         return;
296       } else if (Marshaller.JAXB_SCHEMA_LOCATION.equals(pProperty)) {
297         setSchemaLocation((String JavaDoc) pValue);
298         return;
299       }
300     } else if (pProperty.startsWith("jaxme.")) {
301       if (JAXME_XML_WRITER.equals(pProperty)) {
302         setXMLWriterClass((Class JavaDoc) pValue);
303         return;
304       } else if (JAXME_XML_DECLARATION.equals(pProperty)) {
305         setXmlDeclaration(((Boolean JavaDoc) pValue).booleanValue());
306         return;
307       } else if (JAXME_INDENTATION_SEPARATOR.equals(pProperty)) {
308         setIndentationSeparator((String JavaDoc) pValue);
309         return;
310       } else if (JAXME_INDENTATION_STRING.equals(pProperty)) {
311         setIndentationString((String JavaDoc) pValue);
312         return;
313       }
314     }
315     super.setProperty(pProperty, pValue);
316   }
317
318   public Object JavaDoc getProperty(String JavaDoc pProperty) throws PropertyException {
319     if (pProperty.startsWith("jaxb.")) {
320       if (Marshaller.JAXB_ENCODING.equals(pProperty)) {
321         return getEncoding();
322       } else if (Marshaller.JAXB_FORMATTED_OUTPUT.equals(pProperty)) {
323         return new Boolean JavaDoc(getIndentation());
324       }
325     } else if (pProperty.startsWith("jaxme.")) {
326       if (JAXME_INDENTATION_STRING.equals(pProperty)) {
327         return getIndentationString();
328       } else if (JAXME_XML_WRITER.equals(pProperty)) {
329         return getXMLWriterClass();
330       } else if (JAXME_XML_DECLARATION.equals(pProperty)) {
331         return getEncoding();
332       } else if (JAXME_INDENTATION_SEPARATOR.equals(pProperty)) {
333         return getIndentationSeparator();
334       }
335     }
336     return super.getProperty(pProperty);
337   }
338
339
340   /* Marshaller methods
341    */

342   public void marshal(Object JavaDoc pObject, OutputStream JavaDoc pStream) throws JAXBException {
343     Writer JavaDoc writer;
344     try {
345       writer = new OutputStreamWriter JavaDoc(pStream, getEncoding());
346     } catch(UnsupportedEncodingException JavaDoc e) {
347       throw new MarshalException("Unsupported encoding: " + getEncoding(), e);
348     }
349     marshal(pObject, writer);
350     try {
351       writer.close();
352     } catch (IOException JavaDoc e) {
353       throw new MarshalException(e);
354     }
355   }
356
357   public void marshal(Object JavaDoc pObject, ContentHandler JavaDoc pHandler) throws JAXBException {
358     JMElement element = (JMElement) pObject;
359     QName JavaDoc qName = element.getQName();
360     try {
361         JMManager manager = getJAXBContextImpl().getManager(qName);
362         JMSAXDriver driver = manager.getDriver();
363         JMSAXDriverController controller = new JMSAXDriverController(this, pHandler);
364         controller.marshal(driver, qName.getPrefix(), qName.getNamespaceURI(), qName.getLocalPart(), element);
365     } catch (SAXException JavaDoc e) {
366       throw new MarshalException(e);
367     }
368   }
369
370   public void marshal(Object JavaDoc pObject, Writer JavaDoc pWriter) throws JAXBException {
371     if (getXmlDeclaration()) {
372       try {
373         pWriter.write("<?xml version='1.0' encoding='" + getEncoding() + "'?>");
374         if (getIndentation()) {
375           pWriter.write(getIndentationSeparator());
376         }
377       } catch (IOException JavaDoc e) {
378         throw new MarshalException(e);
379       }
380     }
381     XMLWriter w;
382     Class JavaDoc c = getXMLWriterClass();
383     try {
384       w = (XMLWriter) c.newInstance();
385     } catch (Exception JavaDoc e) {
386       throw new JAXBException("Failed to instantiate XMLWriter class " + c.getName(), e);
387     }
388     w.init(this);
389     w.setWriter(pWriter);
390     marshal(pObject, w);
391   }
392
393   public void marshal(Object JavaDoc pObject, Node JavaDoc pNode) throws JAXBException {
394     DOMBuilder db = new DOMBuilder();
395     db.setTarget(pNode);
396     marshal(pObject, db);
397   }
398
399   public void marshal(Object JavaDoc pObject, Result JavaDoc pResult) throws JAXBException {
400     if (pResult instanceof SAXResult JavaDoc) {
401       ContentHandler JavaDoc ch = ((SAXResult JavaDoc) pResult).getHandler();
402       if (ch == null) {
403         throw new MarshalException("The SAXResult doesn't have its ContentHandler set.");
404       }
405       marshal(pObject, ch);
406     } else if (pResult instanceof StreamResult JavaDoc) {
407       StreamResult JavaDoc sr = (StreamResult JavaDoc) pResult;
408       Writer JavaDoc w = sr.getWriter();
409       if (w == null) {
410         OutputStream JavaDoc s = sr.getOutputStream();
411         if (s == null) {
412           throw new MarshalException("The StreamResult doesn't have its Writer or OutputStream set.");
413         }
414         marshal(pObject, s);
415       } else {
416         marshal(pObject, w);
417       }
418     } else if (pResult instanceof DOMResult JavaDoc) {
419       Node JavaDoc node = ((DOMResult JavaDoc) pResult).getNode();
420       if (node == null) {
421         throw new MarshalException("The DOMResult doesn't have its Node set.");
422       }
423       marshal(pObject, node);
424     } else {
425       throw new MarshalException("Unknown type of Result: " + pResult.getClass().getName() +
426                                   ", only SAXResult, StreamResult and DOMResult are supported.");
427     }
428   }
429
430   public Node JavaDoc getNode(java.lang.Object JavaDoc contentTree) throws JAXBException {
431     throw new UnsupportedOperationException JavaDoc("JaxMe doesn't support live DOM views");
432   }
433 }
434
Popular Tags