001 /*
002 * @(#)$Id: AbstractMarshallerImpl.java,v 1.21 2003/02/13 23:41:06 kk122374 Exp $
003 *
004 * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
005 *
006 * This software is the proprietary information of Sun Microsystems, Inc.
007 * Use is subject to license terms.
008 *
009 */
010 package javax.xml.bind.helpers;
011
012 import javax.xml.bind.Marshaller;
013 import javax.xml.bind.JAXBException;
014 import javax.xml.bind.PropertyException;
015 import javax.xml.bind.ValidationEventHandler;
016 import javax.xml.transform.stream.StreamResult;
017 import javax.xml.transform.sax.SAXResult;
018 import javax.xml.transform.dom.DOMResult;
019
020 import java.io.UnsupportedEncodingException;
021 // J2SE1.4 feature
022 // import java.nio.charset.Charset;
023 // import java.nio.charset.UnsupportedCharsetException;
024
025 /**
026 * Partial default <tt>Marshaller</tt> implementation.
027 *
028 * <p>
029 * This class provides a partial default implementation for the
030 * {@link javax.xml.bind.Marshaller} interface.
031 *
032 * <p>
033 * The only method that a JAXB Provider has to implement is
034 * {@link Marshaller#marshal(Object, Result) marshal(Object, javax.xml.transform.Result)}.
035 *
036 * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul>
037 * @version $Revision: 1.21 $ $Date: 2003/02/13 23:41:06 $
038 * @see javax.xml.bind.Marshaller
039 * @since JAXB1.0
040 */
041 public abstract class AbstractMarshallerImpl implements Marshaller
042 {
043 /** handler that will be used to process errors and warnings during marshal */
044 private ValidationEventHandler eventHandler =
045 new DefaultValidationEventHandler();
046
047 //J2SE1.4 feature
048 //private Charset encoding = null;
049
050 /** store the value of the encoding property. */
051 private String encoding = "UTF-8";
052
053 /** store the value of the schemaLocation property. */
054 private String schemaLocation = null;
055
056 /** store the value of the noNamespaceSchemaLocation property. */
057 private String noNSSchemaLocation = null;
058
059 /** store the value of the formattedOutput property. */
060 private boolean formattedOutput = false;
061
062 public final void marshal( Object obj, java.io.OutputStream os )
063 throws JAXBException {
064
065 checkNotNull( obj, "obj", os, "os" );
066 marshal( obj, new StreamResult(os) );
067 }
068
069 public final void marshal( Object obj, java.io.Writer w )
070 throws JAXBException {
071
072 checkNotNull( obj, "obj", w, "writer" );
073 marshal( obj, new StreamResult(w) );
074 }
075
076 public final void marshal( Object obj, org.xml.sax.ContentHandler handler )
077 throws JAXBException {
078
079 checkNotNull( obj, "obj", handler, "handler" );
080 marshal( obj, new SAXResult(handler) );
081 }
082
083 public final void marshal( Object obj, org.w3c.dom.Node node )
084 throws JAXBException {
085
086 checkNotNull( obj, "obj", node, "node" );
087 marshal( obj, new DOMResult(node) );
088 }
089
090 /**
091 * By default, the getNode method is unsupported and throw
092 * an {@link java.lang.UnsupportedOperationException}.
093 *
094 * Implementations that choose to support this method must
095 * override this method.
096 */
097 public org.w3c.dom.Node getNode( Object obj ) throws JAXBException {
098
099 checkNotNull( obj, "obj", Boolean.TRUE, "foo" );
100
101 throw new UnsupportedOperationException();
102 }
103
104 /**
105 * Convenience method for getting the current output encoding.
106 *
107 * @return the current encoding or "UTF-8" if it hasn't been set.
108 */
109 protected String getEncoding() {
110 return encoding;
111 }
112
113 /**
114 * Convenience method for setting the output encoding.
115 *
116 * @param encoding a valid encoding as specified in the Marshaller class
117 * documentation
118 */
119 protected void setEncoding( String encoding ) {
120 this.encoding = encoding;
121 }
122
123 /**
124 * Convenience method for getting the current schemaLocation.
125 *
126 * @return the current schemaLocation or null if it hasn't been set
127 */
128 protected String getSchemaLocation() {
129 return schemaLocation;
130 }
131
132 /**
133 * Convenience method for setting the schemaLocation.
134 *
135 * @param location the schemaLocation value
136 */
137 protected void setSchemaLocation( String location ) {
138 schemaLocation = location;
139 }
140
141 /**
142 * Convenience method for getting the current noNamespaceSchemaLocation.
143 *
144 * @return the current noNamespaceSchemaLocation or null if it hasn't
145 * been set
146 */
147 protected String getNoNSSchemaLocation() {
148 return noNSSchemaLocation;
149 }
150
151 /**
152 * Convenience method for setting the noNamespaceSchemaLocation.
153 *
154 * @param location the noNamespaceSchemaLocation value
155 */
156 protected void setNoNSSchemaLocation( String location ) {
157 noNSSchemaLocation = location;
158 }
159
160 /**
161 * Convenience method for getting the formatted output flag.
162 *
163 * @return the current value of the formatted output flag or false if
164 * it hasn't been set.
165 */
166 protected boolean isFormattedOutput() {
167 return formattedOutput;
168 }
169
170 /**
171 * Convenience method for setting the formatted output flag.
172 *
173 * @param v value of the formatted output flag.
174 */
175 protected void setFormattedOutput( boolean v ) {
176 formattedOutput = v;
177 }
178
179
180 static String[] aliases = {
181 "UTF-8", "UTF8",
182 "UTF-16", "Unicode",
183 "UTF-16BE", "UnicodeBigUnmarked",
184 "UTF-16LE", "UnicodeLittleUnmarked",
185 "US-ASCII", "ASCII",
186 "TIS-620", "TIS620",
187
188 // taken from the project-X parser
189 "ISO-10646-UCS-2", "Unicode",
190
191 "EBCDIC-CP-US", "cp037",
192 "EBCDIC-CP-CA", "cp037",
193 "EBCDIC-CP-NL", "cp037",
194 "EBCDIC-CP-WT", "cp037",
195
196 "EBCDIC-CP-DK", "cp277",
197 "EBCDIC-CP-NO", "cp277",
198 "EBCDIC-CP-FI", "cp278",
199 "EBCDIC-CP-SE", "cp278",
200
201 "EBCDIC-CP-IT", "cp280",
202 "EBCDIC-CP-ES", "cp284",
203 "EBCDIC-CP-GB", "cp285",
204 "EBCDIC-CP-FR", "cp297",
205
206 "EBCDIC-CP-AR1", "cp420",
207 "EBCDIC-CP-HE", "cp424",
208 "EBCDIC-CP-BE", "cp500",
209 "EBCDIC-CP-CH", "cp500",
210
211 "EBCDIC-CP-ROECE", "cp870",
212 "EBCDIC-CP-YU", "cp870",
213 "EBCDIC-CP-IS", "cp871",
214 "EBCDIC-CP-AR2", "cp918",
215
216 // IANA also defines two that JDK 1.2 doesn't handle:
217 // EBCDIC-CP-GR --> CP423
218 // EBCDIC-CP-TR --> CP905
219 };
220
221 /**
222 * Gets the corresponding Java encoding name from an IANA name.
223 *
224 * This method is a helper method for the derived class to convert
225 * encoding names.
226 *
227 * @exception UnsupportedEncodingException
228 * If this implementation couldn't find the Java encoding name.
229 */
230 protected String getJavaEncoding( String encoding ) throws UnsupportedEncodingException {
231 try {
232 "1".getBytes(encoding);
233 return encoding;
234 } catch( UnsupportedEncodingException e ) {
235 // try known alias
236 for( int i=0; i<aliases.length; i+=2 ) {
237 if(encoding.equals(aliases[i])) {
238 "1".getBytes(aliases[i+1]);
239 return aliases[i+1];
240 }
241 }
242
243 throw new UnsupportedEncodingException(encoding);
244 }
245 /* J2SE1.4 feature
246 try {
247 this.encoding = Charset.forName( _encoding );
248 } catch( UnsupportedCharsetException uce ) {
249 throw new JAXBException( uce );
250 }
251 */
252 }
253
254 /**
255 * Default implementation of the setProperty method handles
256 * the four defined properties in Marshaller. If a provider
257 * needs to handle additional properties, it should override
258 * this method in a derived class.
259 */
260 public void setProperty( String name, Object value )
261 throws PropertyException {
262
263 if( name == null ) {
264 throw new IllegalArgumentException(
265 Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) );
266 }
267
268 // recognize and handle four pre-defined properties.
269 if( JAXB_ENCODING.equals(name) ) {
270 checkString( name, value );
271 setEncoding( (String)value );
272 return;
273 }
274 if( JAXB_FORMATTED_OUTPUT.equals(name) ) {
275 checkBoolean( name, value );
276 setFormattedOutput( ((Boolean)value).booleanValue() );
277 return;
278 }
279 if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) ) {
280 checkString( name, value );
281 setNoNSSchemaLocation( (String)value );
282 return;
283 }
284 if( JAXB_SCHEMA_LOCATION.equals(name) ) {
285 checkString( name, value );
286 setSchemaLocation( (String)value );
287 return;
288 }
289
290 throw new PropertyException(name, value);
291 }
292
293 /**
294 * Default implementation of the getProperty method handles
295 * the four defined properties in Marshaller. If a provider
296 * needs to support additional provider specific properties,
297 * it should override this method in a derived class.
298 */
299 public Object getProperty( String name )
300 throws PropertyException {
301
302 if( name == null ) {
303 throw new IllegalArgumentException(
304 Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) );
305 }
306
307 // recognize and handle four pre-defined properties.
308 if( JAXB_ENCODING.equals(name) )
309 return getEncoding();
310 if( JAXB_FORMATTED_OUTPUT.equals(name) )
311 return isFormattedOutput()?Boolean.TRUE:Boolean.FALSE;
312 if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) )
313 return getNoNSSchemaLocation();
314 if( JAXB_SCHEMA_LOCATION.equals(name) )
315 return getSchemaLocation();
316
317 throw new PropertyException(name);
318 }
319 /**
320 * @see javax.xml.bind.Marshaller#getEventHandler()
321 */
322 public ValidationEventHandler getEventHandler() throws JAXBException {
323 return eventHandler;
324 }
325
326 /**
327 * @see javax.xml.bind.Marshaller#setEventHandler(ValidationEventHandler)
328 */
329 public void setEventHandler(ValidationEventHandler handler)
330 throws JAXBException {
331
332 if( handler == null ) {
333 eventHandler = new DefaultValidationEventHandler();
334 } else {
335 eventHandler = handler;
336 }
337 }
338
339
340
341
342 /*
343 * assert that the given object is a Boolean
344 */
345 private void checkBoolean( String name, Object value ) throws PropertyException {
346 if(!(value instanceof Boolean))
347 throw new PropertyException(
348 Messages.format( Messages.MUST_BE_BOOLEAN, name ) );
349 }
350
351 /*
352 * assert that the given object is a String
353 */
354 private void checkString( String name, Object value ) throws PropertyException {
355 if(!(value instanceof String))
356 throw new PropertyException(
357 Messages.format( Messages.MUST_BE_STRING, name ) );
358 }
359
360 /*
361 * assert that the parameters are not null
362 */
363 private void checkNotNull( Object o1, String o1Name,
364 Object o2, String o2Name ) {
365
366 if( o1 == null ) {
367 throw new IllegalArgumentException(
368 Messages.format( Messages.MUST_NOT_BE_NULL, o1Name ) );
369 }
370 if( o2 == null ) {
371 throw new IllegalArgumentException(
372 Messages.format( Messages.MUST_NOT_BE_NULL, o2Name ) );
373 }
374 }
375 }