
uk.org.retep.util.xml.JAXBUtil Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2010, Peter T Mount
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the retep.org.uk nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.org.retep.util.xml;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.annotation.concurrent.ThreadSafe;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import uk.org.retep.annotations.ReadLock;
import uk.org.retep.annotations.Unsafe;
import uk.org.retep.annotations.WriteLock;
import uk.org.retep.util.concurrent.ConcurrencySupport;
import uk.org.retep.util.collections.queue.BoundedLinkedList;
import uk.org.retep.util.xml.jaxb.MarshallerFacade;
import uk.org.retep.util.xml.jaxb.UnmarshallerFacade;
/**
*
* A suite of utility methods that make using JAXB a lot easier.
*
*
*
* After creating an instance it allows you to add either the packages or a single
* class from each package that has been generated by xjc. This allows you to
* select what you want JAXB to be able to marshall/unmarshall.
*
*
*
* Once you have selected everything you want, you can then use the getMashaller()
* and getUnmarshaller() methods to obtain the Marshaller/Unmarshaller's that operate
* over those packages.
*
*
*
* In addition, due to the creation of the Marshaller/Unmarshaller's are an expensive
* operation, the class provides a concurrent pool of each, so you can return them
* back into the pool once you have finished them - really useful in a high load
* environment.
*
*
*
* The MarshallerCallBack and UnmarshallerCallBack interfaces allow you to do
* additional configuration on Marshaller/Unmarshaller's when they are created.
*
*
*
* Finally if you are using just the marshall/unmarshall methods, the class also
* provides those methods which will use the pool, removing the need to handle
* the get/release process from your code.
*
*
* @author peter
*/
@ThreadSafe
public class JAXBUtil
extends ConcurrencySupport
{
private static final AtomicLong PACKAGE_SERIAL_ID = new AtomicLong();
private final Set packages;
private JAXBContext context;
private MarshallerCallback marshallerCallback;
private UnmarshallerCallback unmarshallerCallback;
private Queue unmarshallerQueue;
private Queue marshallerQueue;
private int poolSize = 0;
private ClassLoader classLoader;
private long packageSerialId;
/**
* Creates a new instance of JAXBUtil with no initial packages
*/
public JAXBUtil()
{
packages = new LinkedHashSet();
marshallerQueue = new LinkedList();
unmarshallerQueue = new LinkedList();
clear();
}
/**
* Creates a new instance of JAXBUtil with packages added
*
* @param packages packages to use
*/
public JAXBUtil( final String... packages )
{
this();
for( String pkg : packages )
{
addPackage( pkg );
}
}
/**
* Creates a new instance of JAXBUtil with packages added
*
* @param packages packages to use
*/
public JAXBUtil( final ArrayList packages )
{
this();
for( String pkg : packages )
{
addPackage( pkg );
}
}
/**
* Set the ClassLoader that JAXB will use. By default the caller's ClassLoader
* will be used but this method allows a specific ClassLoader to be used
* by JAXB, for example inside a J2EE environment or in an AnnotationProcessor.
*
* @param classLoader ClassLoader to use instead of the caller's ClassLoader
*/
public void setClassLoader( final ClassLoader classLoader )
{
this.classLoader = classLoader;
}
/**
* Releases the JAXBContext and clears both the Marshaller and Unmarshaller
* pools. Any Marshaller or Unmarshaller that was created by original
* JAXBContext will not be accepted by the release methods and any further
* requests for new Marshaller or Unmarshaller instances will be created
* from a new JAXBContext.
*
*
* The various add and remove package methods call this method internally.
* It is public to enable the the pool's to be reset at any moment
*
* @since 9.3
*/
@WriteLock
public void clear()
{
context = null;
marshallerQueue.clear();
unmarshallerQueue.clear();
packageSerialId = PACKAGE_SERIAL_ID.incrementAndGet();
}
/**
* Add one or more packages to this instance
* @param pkg One or more package names
*/
@WriteLock
public void addPackage( final String... pkg )
{
try
{
for( String p : pkg )
{
packages.add( p );
}
}
finally
{
clear();
}
}
/**
* Add one or more ':' delimited package names to this instance
* @param pkg list of packages delimited by ':'
*/
@WriteLock
public void addPackage( final String pkg )
{
try
{
if( pkg.contains( ":" ) )
{
for( String p : pkg.split( ":" ) )
{
packages.add( p );
}
}
else
{
packages.add( pkg );
}
}
finally
{
clear();
}
}
/**
* Add the Package to this instance
* @param packages Package(s) to add
*/
public void addPackage( final Package... packages )
{
for( Package pkg : packages )
{
addPackage( pkg.getName() );
}
}
/**
* Add the package containing the given class to this instance
* @param clazz Class who's package is to be added
*/
public void addPackage( final Class> clazz )
{
addPackage( clazz.getPackage() );
}
/**
* Add all packages below this one to this instance
* @param clazz Class who's package and subpackages are to be added
*/
public void addPackages( final Class> clazz )
{
addPackages( clazz.getPackage() );
}
/**
* Add all packages below this one to this instance
* @param pkg Package and it's subpackages are to be added
*/
@WriteLock
public void addPackages( final Package pkg )
{
if( pkg == null )
{
throw new IllegalArgumentException( "Package may not be null" );
}
try
{
final String name = pkg.getName();
for( Package p : Package.getPackages() )
{
if( p.getName().startsWith( name ) )
{
packages.add( p.getName() );
}
}
}
finally
{
clear();
}
}
/**
* Add all subpackages to this instance
* @param name Package and subpackages are to be added
*/
public void addSubPackages( final String name )
{
addPackages( findPackage( name ) );
}
private static Package findPackage( final String name )
{
String pkgName = name;
Package pkg = Package.getPackage( pkgName );
while( pkgName.length() > 0 && pkg == null )
{
int i = pkgName.lastIndexOf( '.' );
pkgName = i > -1 ? pkgName.substring( 0, i ) : "";
if( pkgName.length() > 0 )
{
pkg = Package.getPackage( pkgName );
}
}
return pkg;
}
/**
* Remove packages
* @param pkg
*/
@WriteLock
public void removePackage( final String... pkg )
{
try
{
for( String p : pkg )
{
packages.remove( p );
}
}
finally
{
clear();
}
}
/**
* Remove package
* @param pkg
*/
@WriteLock
public void removePackage( final String pkg )
{
try
{
if( pkg.contains( ":" ) )
{
for( String p : pkg.split( ":" ) )
{
packages.remove( p );
}
}
else
{
packages.remove( pkg );
}
}
finally
{
clear();
}
}
/**
* Remove package
* @param pkg Package to remove
*/
public void removePackage( final Package pkg )
{
removePackage( pkg.getName() );
}
/**
* Remove the package containing this class
* @param clazz Class who's package to remove
*/
public void removePackage( final Class> clazz )
{
removePackage( clazz.getPackage() );
}
/**
* Remove the package containing this class and all sub-packages
* @param clazz Class who's package and subpackages are to be removed
*/
public void removePackages( final Class> clazz )
{
removeSubPackages( clazz.getPackage() );
}
/**
* Remove the package and all packages within it
* @param pkg Package to remove
*/
@WriteLock
public void removeSubPackages( final Package pkg )
{
if( pkg == null )
{
throw new IllegalArgumentException( "Package may not be null" );
}
try
{
final String name = pkg.getName();
for( Package p : Package.getPackages() )
{
if( p.getName().startsWith( name ) )
{
packages.remove( p.getName() );
}
}
}
finally
{
clear();
}
}
/**
* Remove the package and all packages within it
* @param name Package to remove and all subpackages
*/
public void removePackages( final String name )
{
removeSubPackages( findPackage( name ) );
}
/**
* The current JAXBContext in use.
*
*
* Unless specifically necessary it is advised you do not use this method
* as the returned value can change during the lifetime of the JAXBUtil
* instance.
*
* @return
* @throws javax.xml.bind.JAXBException
*/
@WriteLock
@Unsafe
public JAXBContext getJAXBContext()
throws JAXBException
{
if( context == null )
{
getLog().debug( "Creating JAXBContext" );
boolean notFirst = false;
StringBuilder path = new StringBuilder();
for( String pkg : packages )
{
if( notFirst )
{
path.append( ':' );
}
else
{
notFirst = true;
}
path.append( pkg );
}
getLog().debug( "Creating JAXBContext %s", path );
if( classLoader == null )
{
context = JAXBContext.newInstance( path.toString() );
}
else
{
context = JAXBContext.newInstance( path.toString(),
classLoader );
}
}
return context;
}
/**
* Ensure that the Marshaller pool contains this number of entries.
*
* @param size The number of entries required
* @throws javax.xml.bind.JAXBException
* @throws java.lang.IllegalArgumentException if size < 1
*/
public void ensureMarshallerPoolSize( final int size )
throws JAXBException
{
if( size < 1 )
{
throw new IllegalArgumentException( "Size must be > 0" );
}
int remaining = 0;
do
{
release( createMarshaller() );
readLock().lock();
try
{
remaining = poolSize == 0 ? size : Math.min( poolSize, size );
remaining = remaining - marshallerQueue.size();
}
finally
{
readLock().unlock();
}
} while( remaining > 0 );
}
/**
* Ensure that the Unmarshaller pool contains this number of entries.
*
* @param size The number of entries required
* @throws javax.xml.bind.JAXBException
* @throws java.lang.IllegalArgumentException if size < 1
*/
public void ensureUnmarshallerPoolSize( final int size )
throws JAXBException
{
if( size < 1 )
{
throw new IllegalArgumentException( "Size must be > 0" );
}
int remaining = 0;
do
{
release( createUnmarshaller() );
readLock().lock();
try
{
remaining = poolSize == 0 ? size : Math.min( poolSize, size );
remaining = remaining - unmarshallerQueue.size();
}
finally
{
readLock().unlock();
}
} while( remaining > 0 );
}
/**
* Sets the size of the marshaller and unmarshaller pools.
*
*
* By default, this is set to 0 (unlimited), but if this is set with a value
* > 0, then the pool's are limited to that number of free entries.
*
*
*
* When release() is called and the pool is full, then that Marshaller
* or Unmarshaller is made available to the garbage collector.
*
*
*
* When called, this will lock the pools for the duration of the call, as
* it resizes the existing pools. If the value is less than the current size
* but not 0, then the excess entries are made available to the garbage collector.
*
*
* @param poolSize The size of each pool, 0 for unlimited.
*/
@WriteLock
public void setPoolSize( final int poolSize )
{
if( this.poolSize == poolSize )
{
return;
}
Queue newUnmarshallerQueue = null;
Queue newMarshallerQueue = null;
if( poolSize < 1 )
{
this.poolSize = 0;
newUnmarshallerQueue = new LinkedList();
newMarshallerQueue = new LinkedList();
}
else
{
this.poolSize = poolSize;
newUnmarshallerQueue = new BoundedLinkedList(
poolSize );
newMarshallerQueue = new BoundedLinkedList(
poolSize );
}
for( UnmarshallerWrapper unmarshaller : unmarshallerQueue )
{
newUnmarshallerQueue.offer( unmarshaller );
}
for( MarshallerWrapper marshaller : marshallerQueue )
{
newMarshallerQueue.offer( marshaller );
}
unmarshallerQueue = newUnmarshallerQueue;
marshallerQueue = newMarshallerQueue;
}
@WriteLock
private Marshaller pollMarshaller()
{
return marshallerQueue.poll();
}
/**
* Get a Marshaller from the pool, creating one as necessary. If the pool
* is being used you should use this as follows:
*
*
* Marshaller marshaller = jaxbUtils.getMarshaller();
* try {
* // use the Marshaller here
* } finally {
* jaxbUtils.release( marshaller );
* }
*
*
* @return Marshaller
* @throws javax.xml.bind.JAXBException
*/
public Marshaller getMarshaller()
throws JAXBException
{
Marshaller marshaller = pollMarshaller();
if( marshaller == null )
{
marshaller = createMarshaller();
}
return marshaller;
}
private Marshaller createMarshaller()
throws JAXBException
{
getLog().debug( "Creating Marshaller" );
final Marshaller marshaller = new MarshallerWrapper();
if( marshallerCallback != null )
{
marshallerCallback.initialiseMarshaller( marshaller, this );
}
return marshaller;
}
@WriteLock
private Unmarshaller pollUnmarshaller()
{
return unmarshallerQueue.poll();
}
/**
* Get an Unmarshaller from the pool, creating one as necessary. If the pool
* is being used you should use this as follows:
*
*
* Unmarshaller unmarshaller = jaxbUtils.getUnmarshaller();
* try {
* // use the Marshaller here
* } finally {
* jaxbUtils.release( unmarshaller );
* }
*
*
* @return Unmarshaller
* @throws javax.xml.bind.JAXBException
*/
public Unmarshaller getUnmarshaller()
throws JAXBException
{
Unmarshaller unmarshaller = pollUnmarshaller();
if( unmarshaller == null )
{
unmarshaller = createUnmarshaller();
}
return unmarshaller;
}
private Unmarshaller createUnmarshaller()
throws JAXBException
{
getLog().debug( "Creating Unmarshaller" );
final Unmarshaller unmarshaller = new UnmarshallerWrapper();
if( unmarshallerCallback != null )
{
unmarshallerCallback.initialiseUnmarshaller( unmarshaller, this );
}
return unmarshaller;
}
/**
* Releases a Marshaller back to the pool.
*
*
* Once this method has been called the caller must not use that instance
* again as it may be reused by another thread.
*
*
* @param marshaller Marshaller to return to the pool
* @return true if the Marshaller is in the pool, false if it has been
* dropped due to the pool being full
*/
@WriteLock
public boolean release( final Marshaller marshaller )
{
if( marshaller instanceof MarshallerWrapper )
{
final MarshallerWrapper wrapper = MarshallerWrapper.class.cast(
marshaller );
if( wrapper.getPackageSerialId() == packageSerialId )
{
return marshallerQueue.offer( wrapper );
}
}
// Not one of ours or it's from an onder JAXBContext
return false;
}
/**
* Releases a Unmarshaller back to the pool.
*
*
* Once this method has been called the caller must not use that instance
* again as it may be reused by another thread.
*
*
* @param unmarshaller Unmarshaller to return to the pool
* @return true if the Unmarshaller is in the pool, false if it has been
* dropped due to the pool being full
*/
@WriteLock
public boolean release( final Unmarshaller unmarshaller )
{
if( unmarshaller instanceof UnmarshallerWrapper )
{
final UnmarshallerWrapper wrapper = UnmarshallerWrapper.class.cast(
unmarshaller );
if( wrapper.getPackageSerialId() == packageSerialId )
{
return unmarshallerQueue.offer( wrapper );
}
}
// Not one of ours or it's from an onder JAXBContext
return false;
}
/**
* Utiity to cast an object to JAXBElement<T>
* @param Type of the JAXBElement
* @param o Object to cast
* @return JAXBElement<T>
*/
@SuppressWarnings( value = "unchecked" )
public static JAXBElement getJAXBElement( final Object o )
{
return (JAXBElement) o;
}
/**
* A callback called when a Marshaller is first created allowing the
* application to perform additional configuration on the Marshaller before
* it is first used
*/
public static interface MarshallerCallback
{
/**
* Initialise the Marshaller
*
* @param marshaller virgin Marshaller
* @param jaxbUtil The JAXBUtil instance owning the marshaller
* @throws javax.xml.bind.PropertyException
*/
void initialiseMarshaller( Marshaller marshaller, JAXBUtil jaxbUtil )
throws PropertyException;
}
/**
* A callback called when a Unmarshaller is first created allowing the
* application to perform additional configuration on the Unmarshaller before
* it is first used
*/
public static interface UnmarshallerCallback
{
/**
* Initialise the Marshaller
*
* @param marshaller virgin Unmarshaller
* @param jaxbUtil The JAXBUtil instance owning the marshaller
* @throws javax.xml.bind.PropertyException
*/
void initialiseUnmarshaller( Unmarshaller marshaller, JAXBUtil jaxbUtil )
throws PropertyException;
}
/**
* The callback currently used by Marshaller's, null if none
* @return
*/
@ReadLock
public MarshallerCallback getMarshallerCallback()
{
return marshallerCallback;
}
/**
* Set the MarshallerCallback being used to configure Marshaller's, null if
* none
* @param marshallerCallback
*/
@WriteLock
public void setMarshallerCallback(
final MarshallerCallback marshallerCallback )
{
this.marshallerCallback = marshallerCallback;
}
/**
* The callback currently used by Unmarshaller's, null if none
* @return
*/
@ReadLock
public UnmarshallerCallback getUnmarshallerCallback()
{
return unmarshallerCallback;
}
/**
* Set the UnmarshallerCallback being used to configure Unmarshaller's,
* null if none
* @param unmarshallerCallback
*/
@WriteLock
public void setUnmarshallerCallback(
final UnmarshallerCallback unmarshallerCallback )
{
this.unmarshallerCallback = unmarshallerCallback;
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final ContentHandler out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final File out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final Node out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final OutputStream out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final Result out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final Writer out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final XMLEventWriter out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshal an object
* @param object Object to marshall
* @param out destination of object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
public void marshall( final Object object, final XMLStreamWriter out )
throws JAXBException
{
final Marshaller marshaller = getMarshaller();
try
{
marshaller.marshal( object, out );
}
finally
{
release( marshaller );
}
}
/**
* Marshall an object into a String
* @param object Object to marshall
* @return String containing the marshalled object
* @throws javax.xml.bind.JAXBException
* @since 9.3
*/
public String marshall( final Object object )
throws JAXBException
{
final StringWriter sw = new StringWriter();
marshall( object, sw );
return sw.toString();
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final File in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final InputSource in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final InputStream in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final Node in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final Reader in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final Source in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final URL in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final XMLEventReader in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final XMLStreamReader in )
throws JAXBException
{
final Unmarshaller unmarshaller = getUnmarshaller();
try
{
return (T) unmarshaller.unmarshal( in );
}
finally
{
release( unmarshaller );
}
}
/**
* Unmarshal from a source
* @param Type of required Object
* @param in source
* @return Object
* @throws javax.xml.bind.JAXBException
* @since 9.2
*/
@SuppressWarnings( "unchecked" )
public T unmarshall( final String in )
throws JAXBException
{
return this.unmarshall( new StringReader( in ) );
}
/**
* Wrapper used to identify what JAXBContext the marshaller was created from
* so if we add or remove packages from the instance then we do not accept
* a Marshaller back into the pool if it's from a previous entry
* @since 9.3
*/
private class MarshallerWrapper
extends MarshallerFacade
{
private final long packageSerialId;
public MarshallerWrapper()
throws JAXBException
{
super( getJAXBContext().createMarshaller() );
this.packageSerialId = JAXBUtil.this.packageSerialId;
}
public final long getPackageSerialId()
{
return packageSerialId;
}
}
/**
* Wrapper used to identify what JAXBContext the unmarshaller was created from
* so if we add or remove packages from the instance then we do not accept
* an Unmarshaller back into the pool if it's from a previous entry
* @since 9.3
*/
private class UnmarshallerWrapper
extends UnmarshallerFacade
{
private final long packageSerialId;
public UnmarshallerWrapper()
throws JAXBException
{
super( getJAXBContext().createUnmarshaller() );
this.packageSerialId = JAXBUtil.this.packageSerialId;
}
public final long getPackageSerialId()
{
return packageSerialId;
}
}
}