217 lines
5.1 KiB
Java
217 lines
5.1 KiB
Java
package eu.dnetlib.miscutils.jaxb;
|
|
|
|
import java.io.StringReader;
|
|
import java.io.StringWriter;
|
|
import java.lang.annotation.Annotation;
|
|
|
|
import javax.xml.bind.JAXBContext;
|
|
import javax.xml.bind.JAXBElement;
|
|
import javax.xml.bind.JAXBException;
|
|
import javax.xml.bind.Marshaller;
|
|
import javax.xml.bind.Unmarshaller;
|
|
import javax.xml.bind.annotation.XmlRegistry;
|
|
import javax.xml.bind.annotation.XmlRootElement;
|
|
import javax.xml.namespace.QName;
|
|
import javax.xml.transform.Result;
|
|
import javax.xml.transform.Source;
|
|
import javax.xml.transform.stream.StreamSource;
|
|
|
|
/**
|
|
* Common base class for implementing the Jaxb ObjectFactory pattern.
|
|
*
|
|
* @author marko
|
|
*
|
|
* @param <T>
|
|
* type of the roote element
|
|
*/
|
|
@XmlRegistry
|
|
public class JaxbFactory<T> {
|
|
|
|
/**
|
|
* jaxb context.
|
|
*/
|
|
private JAXBContext context;
|
|
|
|
/**
|
|
* class for the root element handled by this factory.
|
|
*/
|
|
private Class<T> clazz;
|
|
|
|
/**
|
|
* Prevent instantiating with 0 arguments.
|
|
*
|
|
* @throws JAXBException
|
|
*/
|
|
protected JaxbFactory() throws JAXBException {
|
|
// prevent instantiation
|
|
}
|
|
|
|
/**
|
|
* creates a new jaxb factory.
|
|
*
|
|
* This constructor is needed because spring constructor injection doesn't work well will varargs.
|
|
*
|
|
* @param clazz
|
|
* @throws JAXBException
|
|
*/
|
|
public JaxbFactory(final Class<? extends T> clazz) throws JAXBException {
|
|
this(clazz, new Class<?>[] {});
|
|
}
|
|
|
|
/**
|
|
* creates a new jaxb factory.
|
|
*
|
|
* @param clazz
|
|
* class for the root element
|
|
* @param classes
|
|
* other classes
|
|
* @throws JAXBException
|
|
* could happen
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public JaxbFactory(final Class<? extends T> clazz, Class<?>... classes) throws JAXBException {
|
|
Class<?>[] all = new Class<?>[classes.length + 1];
|
|
for (int i = 0; i < classes.length; i++)
|
|
all[i + 1] = classes[i];
|
|
all[0] = clazz;
|
|
|
|
this.clazz = (Class<T>) clazz;
|
|
context = JAXBContext.newInstance(all);
|
|
}
|
|
|
|
/**
|
|
* Create a new T instance.
|
|
*
|
|
* @return new T instance
|
|
*/
|
|
public T newInstance() {
|
|
try {
|
|
return clazz.newInstance();
|
|
} catch (InstantiationException e) {
|
|
throw new IllegalStateException("jaxb bean not instantiable, e");
|
|
} catch (IllegalAccessException e) {
|
|
throw new IllegalStateException("jaxb bean not instantiable, e");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses a given string and creates a java object.
|
|
*
|
|
* @param value
|
|
* serialized representation
|
|
* @return java object
|
|
* @throws JAXBException
|
|
* could happen
|
|
*/
|
|
public T parse(final String value) throws JAXBException {
|
|
return parse(new StreamSource(new StringReader(value)));
|
|
}
|
|
|
|
/**
|
|
* Parses a given source and creates a java object.
|
|
*
|
|
* @param source
|
|
* serialized representation
|
|
* @return java object
|
|
* @throws JAXBException
|
|
* could happen
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public T parse(final Source source) throws JAXBException {
|
|
final Unmarshaller unmarshaller = context.createUnmarshaller();
|
|
return (T) unmarshaller.unmarshal(source);
|
|
}
|
|
|
|
/**
|
|
* Serializes a java object to the xml representation.
|
|
*
|
|
* @param value
|
|
* java object
|
|
* @return xml string
|
|
* @throws JAXBException
|
|
* could happen
|
|
*/
|
|
public String serialize(final T value) throws JAXBException {
|
|
final Marshaller marshaller = context.createMarshaller();
|
|
final StringWriter buffer = new StringWriter();
|
|
marshaller.marshal(createElement(value), buffer);
|
|
return buffer.toString();
|
|
}
|
|
|
|
/**
|
|
* Serializes a java object to a xml sink.
|
|
*
|
|
* @param value
|
|
* java object
|
|
* @param result
|
|
* transform sink
|
|
* @throws JAXBException
|
|
* could happen
|
|
*/
|
|
public void serialize(final T value, final Result result) throws JAXBException {
|
|
final Marshaller marshaller = context.createMarshaller();
|
|
marshaller.marshal(createElement(value), result);
|
|
}
|
|
|
|
/**
|
|
* creates a jax element for a given java object.
|
|
*
|
|
* @param value
|
|
* java object
|
|
* @return jaxb element
|
|
*/
|
|
protected JAXBElement<T> createElement(final T value) {
|
|
final XmlRootElement ann = findAnnotation(XmlRootElement.class, clazz);
|
|
return new JAXBElement<T>(new QName(ann.namespace(), ann.name()), this.clazz, null, value);
|
|
}
|
|
|
|
/**
|
|
* recursively searches a given annotation.
|
|
*
|
|
* @param <T>
|
|
* annotation type
|
|
* @param annotation
|
|
* annotation to search
|
|
* @param clazz
|
|
* root of the class hierarchy.
|
|
* @return annotation
|
|
*/
|
|
private <X extends Annotation> X findAnnotation(final Class<X> annotation, final Class<?> clazz) {
|
|
if (clazz == null)
|
|
return null;
|
|
|
|
final X ann = clazz.getAnnotation(annotation);
|
|
if (ann != null)
|
|
return ann;
|
|
|
|
for (Class<?> iface : clazz.getInterfaces()) {
|
|
final X iann = findAnnotation(annotation, iface);
|
|
if (iann != null)
|
|
return iann;
|
|
}
|
|
|
|
final X parent = findAnnotation(annotation, clazz.getSuperclass());
|
|
if (parent != null)
|
|
return parent;
|
|
|
|
return null;
|
|
}
|
|
|
|
public JAXBContext getContext() {
|
|
return context;
|
|
}
|
|
|
|
public void setContext(final JAXBContext context) {
|
|
this.context = context;
|
|
}
|
|
|
|
public Class<? extends T> getClazz() {
|
|
return clazz;
|
|
}
|
|
|
|
public void setClazz(final Class<T> clazz) {
|
|
this.clazz = clazz;
|
|
}
|
|
|
|
}
|