/*
* Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package jakarta.xml.bind;
import jakarta.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
Class that defines convenience methods for common, simple use of Jakarta XML Binding.
Methods defined in this class are convenience methods that combine several basic operations in the JAXBContext
, Unmarshaller
, and Marshaller
. They are designed to be the prefered methods for developers new to Jakarta XML Binding. They have the following characterstics:
- Generally speaking, the performance is not necessarily optimal.
It is expected that people who need to write performance
critical code will use the rest of the Jakarta XML Binding API directly.
- Errors that happen during the processing is wrapped into
DataBindingException
(which will have JAXBException
as its cause
. It is expected that people who prefer the checked exception would use the rest of the Jakarta XML Binding API directly.
In addition, the unmarshal
methods have the following characteristic:
- Schema validation is not performed on the input XML. The processing will try to continue even if there are errors in the XML, as much as possible. Only as the last resort, this method fails with
DataBindingException
.
Similarly, the marshal
methods have the following characteristic:
- The processing will try to continue even if the Java object tree does not meet the validity requirement. Only as the last resort, this method fails with
DataBindingException
.
All the methods on this class require non-null arguments to all parameters. The unmarshal
methods either fail with an exception or return a non-null value.
Author: Kohsuke Kawaguchi Since: 1.6, JAXB 2.1
/**
* Class that defines convenience methods for common, simple use of Jakarta XML Binding.
*
* <p>
* Methods defined in this class are convenience methods that combine several basic operations
* in the {@link JAXBContext}, {@link Unmarshaller}, and {@link Marshaller}.
*
* They are designed
* to be the prefered methods for developers new to Jakarta XML Binding. They have
* the following characterstics:
*
* <ol>
* <li>Generally speaking, the performance is not necessarily optimal.
* It is expected that people who need to write performance
* critical code will use the rest of the Jakarta XML Binding API directly.
* <li>Errors that happen during the processing is wrapped into
* {@link DataBindingException} (which will have {@link JAXBException}
* as its {@link Throwable#getCause() cause}. It is expected that
* people who prefer the checked exception would use
* the rest of the Jakarta XML Binding API directly.
* </ol>
*
* <p>
* In addition, the {@code unmarshal} methods have the following characteristic:
*
* <ol>
* <li>Schema validation is not performed on the input XML.
* The processing will try to continue even if there
* are errors in the XML, as much as possible. Only as
* the last resort, this method fails with {@link DataBindingException}.
* </ol>
*
* <p>
* Similarly, the {@code marshal} methods have the following characteristic:
* <ol>
* <li>The processing will try to continue even if the Java object tree
* does not meet the validity requirement. Only as
* the last resort, this method fails with {@link DataBindingException}.
* </ol>
*
*
* <p>
* All the methods on this class require non-null arguments to all parameters.
* The {@code unmarshal} methods either fail with an exception or return
* a non-null value.
*
* @author Kohsuke Kawaguchi
* @since 1.6, JAXB 2.1
*/
public final class JAXB {
No instanciation is allowed.
/**
* No instanciation is allowed.
*/
private JAXB() {}
To improve the performance, we'll cache the last JAXBContext
used. /**
* To improve the performance, we'll cache the last {@link JAXBContext} used.
*/
private static final class Cache {
final Class type;
final JAXBContext context;
public Cache(Class type) throws JAXBException {
this.type = type;
this.context = JAXBContext.newInstance(type);
}
}
Cache. We don't want to prevent the Cache.type
from GC-ed, hence WeakReference
. /**
* Cache. We don't want to prevent the {@link Cache#type} from GC-ed,
* hence {@link WeakReference}.
*/
private static volatile WeakReference<Cache> cache;
Obtains the JAXBContext
from the given type, by using the cache if possible. We don't use locks to control access to cache
, but this code should be thread-safe thanks to the immutable Cache
and volatile
.
/**
* Obtains the {@link JAXBContext} from the given type,
* by using the cache if possible.
*
* <p>
* We don't use locks to control access to {@link #cache}, but this code
* should be thread-safe thanks to the immutable {@link Cache} and {@code volatile}.
*/
private static <T> JAXBContext getContext(Class<T> type) throws JAXBException {
WeakReference<Cache> c = cache;
if(c!=null) {
Cache d = c.get();
if(d!=null && d.type==type)
return d.context;
}
// overwrite the cache
Cache d = new Cache(type);
cache = new WeakReference<Cache>(d);
return d.context;
}
Reads in a Java object tree from the given XML input.
Params: - xml –
Reads the entire file as XML.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* Reads the entire file as XML.
*/
public static <T> T unmarshal( File xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(new StreamSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml –
The resource pointed by the URL is read in its entirety.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The resource pointed by the URL is read in its entirety.
*/
public static <T> T unmarshal( URL xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml – The URI is
turned into URL
and then follows the handling of URL
.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The URI is {@link URI#toURL() turned into URL} and then
* follows the handling of {@code URL}.
*/
public static <T> T unmarshal( URI xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml – The string is first interpreted as an absolute
URI
. If it's not a valid absolute URI
, then it's interpreted as a File
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The string is first interpreted as an absolute {@code URI}.
* If it's not {@link URI#isAbsolute() a valid absolute URI},
* then it's interpreted as a {@code File}
*/
public static <T> T unmarshal( String xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml –
The entire stream is read as an XML infoset.
Upon a successful completion, the stream will be closed by this method.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The entire stream is read as an XML infoset.
* Upon a successful completion, the stream will be closed by this method.
*/
public static <T> T unmarshal( InputStream xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml –
The character stream is read as an XML infoset.
The encoding declaration in the XML will be ignored.
Upon a successful completion, the stream will be closed by this method.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The character stream is read as an XML infoset.
* The encoding declaration in the XML will be ignored.
* Upon a successful completion, the stream will be closed by this method.
*/
public static <T> T unmarshal( Reader xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
Reads in a Java object tree from the given XML input.
Params: - xml – The XML infoset that the
Source
represents is read.
/**
* Reads in a Java object tree from the given XML input.
*
* @param xml
* The XML infoset that the {@link Source} represents is read.
*/
public static <T> T unmarshal( Source xml, Class<T> type ) {
try {
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
return item.getValue();
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
/**
* Creates {@link Source} from various XML representation.
* See {@link #unmarshal} for the conversion rules.
*/
private static Source toSource(Object xml) throws IOException {
if(xml==null)
throw new IllegalArgumentException("no XML is given");
if (xml instanceof String) {
try {
xml=new URI((String)xml);
} catch (URISyntaxException e) {
xml=new File((String)xml);
}
}
if (xml instanceof File) {
File file = (File) xml;
return new StreamSource(file);
}
if (xml instanceof URI) {
URI uri = (URI) xml;
xml=uri.toURL();
}
if (xml instanceof URL) {
URL url = (URL) xml;
return new StreamSource(url.toExternalForm());
}
if (xml instanceof InputStream) {
InputStream in = (InputStream) xml;
return new StreamSource(in);
}
if (xml instanceof Reader) {
Reader r = (Reader) xml;
return new StreamSource(r);
}
if (xml instanceof Source) {
return (Source) xml;
}
throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass());
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml –
XML will be written to this file. If it already exists,
it will be overwritten.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* XML will be written to this file. If it already exists,
* it will be overwritten.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, File xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The XML will be
sent
to the resource pointed by this URL. Note that not all URL
s support such operation, and exact semantics depends on the URL
implementations. In case of HTTP URLs
, this will perform HTTP POST.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The XML will be {@link URLConnection#getOutputStream() sent} to the
* resource pointed by this URL. Note that not all {@code URL}s support
* such operation, and exact semantics depends on the {@code URL}
* implementations. In case of {@link HttpURLConnection HTTP URLs},
* this will perform HTTP POST.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, URL xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The URI is
turned into URL
and then follows the handling of URL
. See above.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The URI is {@link URI#toURL() turned into URL} and then
* follows the handling of {@code URL}. See above.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, URI xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The string is first interpreted as an absolute
URI
. If it's not a valid absolute URI
, then it's interpreted as a File
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The string is first interpreted as an absolute {@code URI}.
* If it's not {@link URI#isAbsolute() a valid absolute URI},
* then it's interpreted as a {@code File}
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, String xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The XML will be sent to the given
OutputStream
. Upon a successful completion, the stream will be closed by this method.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The XML will be sent to the given {@link OutputStream}.
* Upon a successful completion, the stream will be closed by this method.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, OutputStream xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The XML will be sent as a character stream to the given
Writer
. Upon a successful completion, the stream will be closed by this method.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The XML will be sent as a character stream to the given {@link Writer}.
* Upon a successful completion, the stream will be closed by this method.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, Writer xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml – The XML will be sent to the
Result
object.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* The XML will be sent to the {@link Result} object.
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
public static void marshal( Object jaxbObject, Result xml ) {
_marshal(jaxbObject,xml);
}
Writes a Java object tree to XML and store it to the specified location.
This method is a convenience method that combines several basic operations in the JAXBContext
and Marshaller
. This method is designed to be the prefered method for developers new to Jakarta XML Binding. This method has the following characterstics:
- Generally speaking, the performance is not necessarily optimal.
It is expected that those people who need to write performance
critical code will use the rest of the Jakarta XML Binding API directly.
- Errors that happen during the processing is wrapped into
DataBindingException
(which will have JAXBException
as its cause
. It is expected that those people who prefer the checked exception would use the rest of the Jakarta XML Binding API directly.
Params: - jaxbObject – The Java object to be marshalled into XML. If this object is a
JAXBElement
, it will provide the root tag name and the body. If this object has XmlRootElement
on its class definition, that will be used as the root tag name and the given object will provide the body. Otherwise, the root tag name is infered
from the short class name
. This parameter must not be null. - xml –
Represents the receiver of XML. Objects of the following types are allowed.
Type
Operation
File
XML will be written to this file. If it already exists,
it will be overwritten.
URL
The XML will be sent
to the resource pointed by this URL. Note that not all URL
s support such operation, and exact semantics depends on the URL
implementations. In case of HTTP URLs
, this will perform HTTP POST.
URI
The URI is turned into URL
and then follows the handling of URL
. See above.
String
The string is first interpreted as an absolute URI
. If it's not a valid absolute URI
, then it's interpreted as a File
OutputStream
The XML will be sent to the given OutputStream
. Upon a successful completion, the stream will be closed by this method.
Writer
The XML will be sent as a character stream to the given Writer
. Upon a successful completion, the stream will be closed by this method.
Result
The XML will be sent to the Result
object.
Throws: - DataBindingException –
If the operation fails, such as due to I/O error, unbindable classes.
/**
* Writes a Java object tree to XML and store it to the specified location.
*
* <p>
* This method is a convenience method that combines several basic operations
* in the {@link JAXBContext} and {@link Marshaller}. This method is designed
* to be the prefered method for developers new to Jakarta XML Binding. This method
* has the following characterstics:
*
* <ol>
* <li>Generally speaking, the performance is not necessarily optimal.
* It is expected that those people who need to write performance
* critical code will use the rest of the Jakarta XML Binding API directly.
* <li>Errors that happen during the processing is wrapped into
* {@link DataBindingException} (which will have {@link JAXBException}
* as its {@link Throwable#getCause() cause}. It is expected that
* those people who prefer the checked exception would use
* the rest of the Jakarta XML Binding API directly.
* </ol>
*
* @param jaxbObject
* The Java object to be marshalled into XML. If this object is
* a {@link JAXBElement}, it will provide the root tag name and
* the body. If this object has {@link XmlRootElement}
* on its class definition, that will be used as the root tag name
* and the given object will provide the body. Otherwise,
* the root tag name is {@link java.beans.Introspector#decapitalize(String) infered} from
* {@link Class#getSimpleName() the short class name}.
* This parameter must not be null.
*
* @param xml
* Represents the receiver of XML. Objects of the following types are allowed.
*
* <table><tr>
* <th>Type</th>
* <th>Operation</th>
* </tr><tr>
* <td>{@link File}</td>
* <td>XML will be written to this file. If it already exists,
* it will be overwritten.</td>
* </tr><tr>
* <td>{@link URL}</td>
* <td>The XML will be {@link URLConnection#getOutputStream() sent} to the
* resource pointed by this URL. Note that not all {@code URL}s support
* such operation, and exact semantics depends on the {@code URL}
* implementations. In case of {@link HttpURLConnection HTTP URLs},
* this will perform HTTP POST.</td>
* </tr><tr>
* <td>{@link URI}</td>
* <td>The URI is {@link URI#toURL() turned into URL} and then
* follows the handling of {@code URL}. See above.</td>
* </tr><tr>
* <td>{@link String}</td>
* <td>The string is first interpreted as an absolute {@code URI}.
* If it's not {@link URI#isAbsolute() a valid absolute URI},
* then it's interpreted as a {@code File}</td>
* </tr><tr>
* <td>{@link OutputStream}</td>
* <td>The XML will be sent to the given {@link OutputStream}.
* Upon a successful completion, the stream will be closed by this method.</td>
* </tr><tr>
* <td>{@link Writer}</td>
* <td>The XML will be sent as a character stream to the given {@link Writer}.
* Upon a successful completion, the stream will be closed by this method.</td>
* </tr><tr>
* <td>{@link Result}</td>
* <td>The XML will be sent to the {@link Result} object.</td>
* </tr></table>
*
* @throws DataBindingException
* If the operation fails, such as due to I/O error, unbindable classes.
*/
private static void _marshal( Object jaxbObject, Object xml ) {
try {
JAXBContext context;
if(jaxbObject instanceof JAXBElement) {
context = getContext(((JAXBElement<?>)jaxbObject).getDeclaredType());
} else {
Class<?> clazz = jaxbObject.getClass();
XmlRootElement r = clazz.getAnnotation(XmlRootElement.class);
context = getContext(clazz);
if(r==null) {
// we need to infer the name
jaxbObject = new JAXBElement(new QName(inferName(clazz)),clazz,jaxbObject);
}
}
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
m.marshal(jaxbObject, toResult(xml));
} catch (JAXBException e) {
throw new DataBindingException(e);
} catch (IOException e) {
throw new DataBindingException(e);
}
}
private static String inferName(Class clazz) {
// XXX - behaviour of this method must be same as of Introspector.decapitalize
// which is not used to avoid dependency on java.desktop
String simpleName = clazz.getSimpleName();
if (simpleName == null || simpleName.isEmpty()) {
return simpleName;
}
if (simpleName.length() > 1 && Character.isUpperCase(simpleName.charAt(1))
&& Character.isUpperCase(simpleName.charAt(0))) {
return simpleName;
}
char chars[] = simpleName.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
Creates Result
from various XML representation. See _marshal(Object, Object)
for the conversion rules. /**
* Creates {@link Result} from various XML representation.
* See {@link #_marshal(Object,Object)} for the conversion rules.
*/
private static Result toResult(Object xml) throws IOException {
if(xml==null)
throw new IllegalArgumentException("no XML is given");
if (xml instanceof String) {
try {
xml=new URI((String)xml);
} catch (URISyntaxException e) {
xml=new File((String)xml);
}
}
if (xml instanceof File) {
File file = (File) xml;
return new StreamResult(file);
}
if (xml instanceof URI) {
URI uri = (URI) xml;
xml=uri.toURL();
}
if (xml instanceof URL) {
URL url = (URL) xml;
URLConnection con = url.openConnection();
con.setDoOutput(true);
con.setDoInput(false);
con.connect();
return new StreamResult(con.getOutputStream());
}
if (xml instanceof OutputStream) {
OutputStream os = (OutputStream) xml;
return new StreamResult(os);
}
if (xml instanceof Writer) {
Writer w = (Writer)xml;
return new StreamResult(w);
}
if (xml instanceof Result) {
return (Result) xml;
}
throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass());
}
}