001 /*
002 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package javax.xml.bind.helpers;
026
027 import javax.xml.bind.JAXBException;
028 import javax.xml.bind.Marshaller;
029 import javax.xml.bind.PropertyException;
030 import javax.xml.bind.ValidationEventHandler;
031 import javax.xml.bind.annotation.adapters.XmlAdapter;
032 import javax.xml.bind.attachment.AttachmentMarshaller;
033 import javax.xml.stream.XMLEventWriter;
034 import javax.xml.stream.XMLStreamWriter;
035 import javax.xml.transform.dom.DOMResult;
036 import javax.xml.transform.sax.SAXResult;
037 import javax.xml.transform.stream.StreamResult;
038 import javax.xml.validation.Schema;
039 import java.io.UnsupportedEncodingException;
040
041 // J2SE1.4 feature
042 // import java.nio.charset.Charset;
043 // import java.nio.charset.UnsupportedCharsetException;
044
045 /**
046 * Partial default <tt>Marshaller</tt> implementation.
047 *
048 * <p>
049 * This class provides a partial default implementation for the
050 * {@link javax.xml.bind.Marshaller} interface.
051 *
052 * <p>
053 * The only methods that a JAXB Provider has to implement are
054 * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.transform.Result)},
055 * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.stream.XMLStreamWriter)}, and
056 * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.stream.XMLEventWriter)}.
057 *
058 * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul>
059 * @version $Revision: 1.6 $ $Date: 2005/07/28 22:18:12 $
060 * @see javax.xml.bind.Marshaller
061 * @since JAXB1.0
062 */
063 public abstract class AbstractMarshallerImpl implements Marshaller {
064 /** handler that will be used to process errors and warnings during marshal */
065 private ValidationEventHandler eventHandler = new DefaultValidationEventHandler();
066
067 //J2SE1.4 feature
068 //private Charset encoding = null;
069
070 /** store the value of the encoding property. */
071 private String encoding = "UTF-8";
072
073 /** store the value of the schemaLocation property. */
074 private String schemaLocation = null;
075
076 /** store the value of the noNamespaceSchemaLocation property. */
077 private String noNSSchemaLocation = null;
078
079 /** store the value of the formattedOutput property. */
080 private boolean formattedOutput = false;
081
082 /** store the value of the fragment property. */
083 private boolean fragment = false;
084
085 public final void marshal(Object obj, java.io.OutputStream os)
086 throws JAXBException {
087
088 checkNotNull(obj, "obj", os, "os");
089 marshal(obj, new StreamResult(os));
090 }
091
092 public final void marshal(Object obj, java.io.Writer w)
093 throws JAXBException {
094
095 checkNotNull(obj, "obj", w, "writer");
096 marshal(obj, new StreamResult(w));
097 }
098
099 public final void marshal(Object obj,
100 org.xml.sax.ContentHandler handler) throws JAXBException {
101
102 checkNotNull(obj, "obj", handler, "handler");
103 marshal(obj, new SAXResult(handler));
104 }
105
106 public final void marshal(Object obj, org.w3c.dom.Node node)
107 throws JAXBException {
108
109 checkNotNull(obj, "obj", node, "node");
110 marshal(obj, new DOMResult(node));
111 }
112
113 /**
114 * By default, the getNode method is unsupported and throw
115 * an {@link java.lang.UnsupportedOperationException}.
116 *
117 * Implementations that choose to support this method must
118 * override this method.
119 */
120 public org.w3c.dom.Node getNode(Object obj) throws JAXBException {
121
122 checkNotNull(obj, "obj", Boolean.TRUE, "foo");
123
124 throw new UnsupportedOperationException();
125 }
126
127 /**
128 * Convenience method for getting the current output encoding.
129 *
130 * @return the current encoding or "UTF-8" if it hasn't been set.
131 */
132 protected String getEncoding() {
133 return encoding;
134 }
135
136 /**
137 * Convenience method for setting the output encoding.
138 *
139 * @param encoding a valid encoding as specified in the Marshaller class
140 * documentation
141 */
142 protected void setEncoding(String encoding) {
143 this .encoding = encoding;
144 }
145
146 /**
147 * Convenience method for getting the current schemaLocation.
148 *
149 * @return the current schemaLocation or null if it hasn't been set
150 */
151 protected String getSchemaLocation() {
152 return schemaLocation;
153 }
154
155 /**
156 * Convenience method for setting the schemaLocation.
157 *
158 * @param location the schemaLocation value
159 */
160 protected void setSchemaLocation(String location) {
161 schemaLocation = location;
162 }
163
164 /**
165 * Convenience method for getting the current noNamespaceSchemaLocation.
166 *
167 * @return the current noNamespaceSchemaLocation or null if it hasn't
168 * been set
169 */
170 protected String getNoNSSchemaLocation() {
171 return noNSSchemaLocation;
172 }
173
174 /**
175 * Convenience method for setting the noNamespaceSchemaLocation.
176 *
177 * @param location the noNamespaceSchemaLocation value
178 */
179 protected void setNoNSSchemaLocation(String location) {
180 noNSSchemaLocation = location;
181 }
182
183 /**
184 * Convenience method for getting the formatted output flag.
185 *
186 * @return the current value of the formatted output flag or false if
187 * it hasn't been set.
188 */
189 protected boolean isFormattedOutput() {
190 return formattedOutput;
191 }
192
193 /**
194 * Convenience method for setting the formatted output flag.
195 *
196 * @param v value of the formatted output flag.
197 */
198 protected void setFormattedOutput(boolean v) {
199 formattedOutput = v;
200 }
201
202 /**
203 * Convenience method for getting the fragment flag.
204 *
205 * @return the current value of the fragment flag or false if
206 * it hasn't been set.
207 */
208 protected boolean isFragment() {
209 return fragment;
210 }
211
212 /**
213 * Convenience method for setting the fragment flag.
214 *
215 * @param v value of the fragment flag.
216 */
217 protected void setFragment(boolean v) {
218 fragment = v;
219 }
220
221 static String[] aliases = { "UTF-8", "UTF8", "UTF-16", "Unicode",
222 "UTF-16BE", "UnicodeBigUnmarked",
223 "UTF-16LE",
224 "UnicodeLittleUnmarked",
225 "US-ASCII",
226 "ASCII",
227 "TIS-620",
228 "TIS620",
229
230 // taken from the project-X parser
231 "ISO-10646-UCS-2", "Unicode",
232
233 "EBCDIC-CP-US", "cp037", "EBCDIC-CP-CA", "cp037",
234 "EBCDIC-CP-NL", "cp037", "EBCDIC-CP-WT", "cp037",
235
236 "EBCDIC-CP-DK", "cp277", "EBCDIC-CP-NO", "cp277",
237 "EBCDIC-CP-FI", "cp278", "EBCDIC-CP-SE", "cp278",
238
239 "EBCDIC-CP-IT", "cp280", "EBCDIC-CP-ES", "cp284",
240 "EBCDIC-CP-GB", "cp285", "EBCDIC-CP-FR", "cp297",
241
242 "EBCDIC-CP-AR1", "cp420", "EBCDIC-CP-HE", "cp424",
243 "EBCDIC-CP-BE", "cp500", "EBCDIC-CP-CH", "cp500",
244
245 "EBCDIC-CP-ROECE", "cp870", "EBCDIC-CP-YU", "cp870",
246 "EBCDIC-CP-IS", "cp871", "EBCDIC-CP-AR2", "cp918",
247
248 // IANA also defines two that JDK 1.2 doesn't handle:
249 // EBCDIC-CP-GR --> CP423
250 // EBCDIC-CP-TR --> CP905
251 };
252
253 /**
254 * Gets the corresponding Java encoding name from an IANA name.
255 *
256 * This method is a helper method for the derived class to convert
257 * encoding names.
258 *
259 * @exception UnsupportedEncodingException
260 * If this implementation couldn't find the Java encoding name.
261 */
262 protected String getJavaEncoding(String encoding)
263 throws UnsupportedEncodingException {
264 try {
265 "1".getBytes(encoding);
266 return encoding;
267 } catch (UnsupportedEncodingException e) {
268 // try known alias
269 for (int i = 0; i < aliases.length; i += 2) {
270 if (encoding.equals(aliases[i])) {
271 "1".getBytes(aliases[i + 1]);
272 return aliases[i + 1];
273 }
274 }
275
276 throw new UnsupportedEncodingException(encoding);
277 }
278 /* J2SE1.4 feature
279 try {
280 this.encoding = Charset.forName( _encoding );
281 } catch( UnsupportedCharsetException uce ) {
282 throw new JAXBException( uce );
283 }
284 */
285 }
286
287 /**
288 * Default implementation of the setProperty method handles
289 * the four defined properties in Marshaller. If a provider
290 * needs to handle additional properties, it should override
291 * this method in a derived class.
292 */
293 public void setProperty(String name, Object value)
294 throws PropertyException {
295
296 if (name == null) {
297 throw new IllegalArgumentException(Messages.format(
298 Messages.MUST_NOT_BE_NULL, "name"));
299 }
300
301 // recognize and handle four pre-defined properties.
302 if (JAXB_ENCODING.equals(name)) {
303 checkString(name, value);
304 setEncoding((String) value);
305 return;
306 }
307 if (JAXB_FORMATTED_OUTPUT.equals(name)) {
308 checkBoolean(name, value);
309 setFormattedOutput((Boolean) value);
310 return;
311 }
312 if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name)) {
313 checkString(name, value);
314 setNoNSSchemaLocation((String) value);
315 return;
316 }
317 if (JAXB_SCHEMA_LOCATION.equals(name)) {
318 checkString(name, value);
319 setSchemaLocation((String) value);
320 return;
321 }
322 if (JAXB_FRAGMENT.equals(name)) {
323 checkBoolean(name, value);
324 setFragment((Boolean) value);
325 return;
326 }
327
328 throw new PropertyException(name, value);
329 }
330
331 /**
332 * Default implementation of the getProperty method handles
333 * the four defined properties in Marshaller. If a provider
334 * needs to support additional provider specific properties,
335 * it should override this method in a derived class.
336 */
337 public Object getProperty(String name) throws PropertyException {
338
339 if (name == null) {
340 throw new IllegalArgumentException(Messages.format(
341 Messages.MUST_NOT_BE_NULL, "name"));
342 }
343
344 // recognize and handle four pre-defined properties.
345 if (JAXB_ENCODING.equals(name))
346 return getEncoding();
347 if (JAXB_FORMATTED_OUTPUT.equals(name))
348 return isFormattedOutput() ? Boolean.TRUE : Boolean.FALSE;
349 if (JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name))
350 return getNoNSSchemaLocation();
351 if (JAXB_SCHEMA_LOCATION.equals(name))
352 return getSchemaLocation();
353 if (JAXB_FRAGMENT.equals(name))
354 return isFragment() ? Boolean.TRUE : Boolean.FALSE;
355
356 throw new PropertyException(name);
357 }
358
359 /**
360 * @see javax.xml.bind.Marshaller#getEventHandler()
361 */
362 public ValidationEventHandler getEventHandler()
363 throws JAXBException {
364 return eventHandler;
365 }
366
367 /**
368 * @see javax.xml.bind.Marshaller#setEventHandler(ValidationEventHandler)
369 */
370 public void setEventHandler(ValidationEventHandler handler)
371 throws JAXBException {
372
373 if (handler == null) {
374 eventHandler = new DefaultValidationEventHandler();
375 } else {
376 eventHandler = handler;
377 }
378 }
379
380 /*
381 * assert that the given object is a Boolean
382 */
383 private void checkBoolean(String name, Object value)
384 throws PropertyException {
385 if (!(value instanceof Boolean))
386 throw new PropertyException(Messages.format(
387 Messages.MUST_BE_BOOLEAN, name));
388 }
389
390 /*
391 * assert that the given object is a String
392 */
393 private void checkString(String name, Object value)
394 throws PropertyException {
395 if (!(value instanceof String))
396 throw new PropertyException(Messages.format(
397 Messages.MUST_BE_STRING, name));
398 }
399
400 /*
401 * assert that the parameters are not null
402 */
403 private void checkNotNull(Object o1, String o1Name, Object o2,
404 String o2Name) {
405
406 if (o1 == null) {
407 throw new IllegalArgumentException(Messages.format(
408 Messages.MUST_NOT_BE_NULL, o1Name));
409 }
410 if (o2 == null) {
411 throw new IllegalArgumentException(Messages.format(
412 Messages.MUST_NOT_BE_NULL, o2Name));
413 }
414 }
415
416 /* (non-Javadoc)
417 * @see javax.xml.bind.Marshaller#marshal(java.lang.Object, javax.xml.stream.XMLEventWriter)
418 */
419 public void marshal(Object obj, XMLEventWriter writer)
420 throws JAXBException {
421
422 throw new UnsupportedOperationException();
423 }
424
425 /* (non-Javadoc)
426 * @see javax.xml.bind.Marshaller#marshal(java.lang.Object, javax.xml.stream.XMLStreamWriter)
427 */
428 public void marshal(Object obj, XMLStreamWriter writer)
429 throws JAXBException {
430
431 throw new UnsupportedOperationException();
432 }
433
434 public void setSchema(Schema schema) {
435 throw new UnsupportedOperationException();
436 }
437
438 public Schema getSchema() {
439 throw new UnsupportedOperationException();
440 }
441
442 public void setAdapter(XmlAdapter adapter) {
443 if (adapter == null)
444 throw new IllegalArgumentException();
445 setAdapter((Class) adapter.getClass(), adapter);
446 }
447
448 public <A extends XmlAdapter> void setAdapter(Class<A> type,
449 A adapter) {
450 throw new UnsupportedOperationException();
451 }
452
453 public <A extends XmlAdapter> A getAdapter(Class<A> type) {
454 throw new UnsupportedOperationException();
455 }
456
457 public void setAttachmentMarshaller(AttachmentMarshaller am) {
458 throw new UnsupportedOperationException();
459 }
460
461 public AttachmentMarshaller getAttachmentMarshaller() {
462 throw new UnsupportedOperationException();
463 }
464
465 public void setListener(Listener listener) {
466 throw new UnsupportedOperationException();
467 }
468
469 public Listener getListener() {
470 throw new UnsupportedOperationException();
471 }
472 }
|