org.eclipse.persistence.jaxb.JAXBUnmarshaller Maven / Gradle / Ivy
Show all versions of org.eclipse.persistence.moxy
/*******************************************************************************
* Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.jaxb;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.PropertyException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.UnmarshallerHandler;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
import javax.xml.bind.helpers.DefaultValidationEventHandler;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.validation.Schema;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import org.eclipse.persistence.oxm.IDResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.record.XMLEventReaderInputSource;
import org.eclipse.persistence.internal.oxm.record.XMLEventReaderReader;
import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderInputSource;
import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jaxb.JAXBErrorHandler;
import org.eclipse.persistence.jaxb.JAXBUnmarshallerHandler;
import org.eclipse.persistence.jaxb.JAXBContext.RootLevelXmlAdapter;
import org.eclipse.persistence.jaxb.attachment.AttachmentUnmarshallerAdapter;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.jaxb.IDResolverWrapper;
import org.eclipse.persistence.internal.jaxb.WrappedValue;
import org.eclipse.persistence.internal.jaxb.many.ManyValue;
/**
* INTERNAL:
* Purpose:To Provide an implementation of the JAXB 2.0 Unmarshaller Interface
*
Responsibilities:
*
* - Provide a JAXB wrapper on the XMLUnmarshaller API
* - Perform XML to Object Conversions
*
* This implementation of the JAXB 2.0 Unmarshaller interface provides the required functionality
* by acting as a thin wrapper on the existing XMLMarshaller API.
*
* @author mmacivor
* @since Oracle TopLink 11.1.1.0.0
* @see javax.xml.bind.Unmarshaller
* @see org.eclipse.persistence.oxm.XMLUnmarshaller
*/
public class JAXBUnmarshaller implements Unmarshaller {
private static final String SUN_ID_RESOLVER = "com.sun.xml.bind.IDResolver";
private static final String SUN_JSE_ID_RESOLVER = "com.sun.xml.internal.bind.IDResolver";
private ValidationEventHandler validationEventHandler;
private XMLUnmarshaller xmlUnmarshaller;
private JAXBContext jaxbContext;
private XMLInputFactory xmlInputFactory;
private boolean initializedXMLInputFactory = false;
public static final String XML_JAVATYPE_ADAPTERS = "xml-javatype-adapters";
public static final String STAX_SOURCE_CLASS_NAME = "javax.xml.transform.stax.StAXSource";
public JAXBUnmarshaller(XMLUnmarshaller newXMLUnmarshaller) {
super();
validationEventHandler = new DefaultValidationEventHandler();
xmlUnmarshaller = newXMLUnmarshaller;
xmlUnmarshaller.setValidationMode(XMLUnmarshaller.NONVALIDATING);
xmlUnmarshaller.setUnmarshalListener(new JAXBUnmarshalListener(this));
xmlUnmarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
}
private XMLInputFactory getXMLInputFactory() {
if(!initializedXMLInputFactory) {
try {
xmlInputFactory = XMLInputFactory.newInstance();
} catch(FactoryConfigurationError e) {
} finally {
initializedXMLInputFactory = true;
}
}
return xmlInputFactory;
}
public XMLUnmarshaller getXMLUnmarshaller() {
return xmlUnmarshaller;
}
public Object unmarshal(File file) throws JAXBException {
try {
Object value = xmlUnmarshaller.unmarshal(file);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public Object unmarshal(InputStream inputStream) throws JAXBException {
try {
XMLInputFactory xmlInputFactory = getXMLInputFactory();
if(null == xmlInputFactory ||
XMLUnmarshaller.NONVALIDATING != xmlUnmarshaller.getValidationMode()) {
return createJAXBElementOrUnwrapIfRequired(xmlUnmarshaller.unmarshal(inputStream));
} else {
if(null == inputStream) {
throw XMLMarshalException.nullArgumentException();
}
XMLStreamReader xmlStreamReader;
xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
Object value = unmarshal(xmlStreamReader);
xmlStreamReader.close();
return value;
}
} catch(JAXBException jaxbException) {
throw jaxbException;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
} catch (Exception exception) {
throw new UnmarshalException(exception);
}
}
public Object unmarshal(URL url) throws JAXBException {
try {
Object value = xmlUnmarshaller.unmarshal(url);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public Object unmarshal(InputSource inputSource) throws JAXBException {
try {
Object value = xmlUnmarshaller.unmarshal(inputSource);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public Object unmarshal(Reader reader) throws JAXBException {
try {
XMLInputFactory xmlInputFactory = getXMLInputFactory();
if(null == xmlInputFactory ||
XMLUnmarshaller.NONVALIDATING != xmlUnmarshaller.getValidationMode()) {
return createJAXBElementOrUnwrapIfRequired(xmlUnmarshaller.unmarshal(reader));
} else {
if(null == reader) {
throw XMLMarshalException.nullArgumentException();
}
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(reader);
Object value = unmarshal(xmlStreamReader);
xmlStreamReader.close();
return value;
}
} catch(JAXBException jaxbException) {
throw jaxbException;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
} catch (Exception exception) {
throw new UnmarshalException(exception);
}
}
public Object unmarshal(Node node) throws JAXBException {
try {
Object value = xmlUnmarshaller.unmarshal(node);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
/**
* Create a JAXBElement instance. If the object is an instance
* of XMLRoot, we will use its field values to create the
* JAXBElement. If the object is not an XMLRoot instance, we
* will have to determine the 'name' value. This will be done
* using the object's descriptor default root element - any
* prefix will be resolved, and a QName created.
*
* @param obj
* @return
*/
private JAXBElement buildJAXBElementFromObject(Object obj, Class declaredClass) {
// if an XMLRoot was returned, the root element != the default root
// element of the object being marshalled to - need to create a
// JAXBElement from the returned XMLRoot object
if (obj instanceof XMLRoot) {
JAXBElement jaxbElement = createJAXBElementFromXMLRoot(((XMLRoot)obj), declaredClass);
if(((XMLRoot)obj).isNil()) {
jaxbElement.setNil(((XMLRoot)obj).isNil());
jaxbElement.setValue(null);
}
return jaxbElement;
}
if(obj instanceof JAXBElement) {
return (JAXBElement) obj;
}
// at this point, the default root element of the object being marshalled
// to == the root element - here we need to create a JAXBElement
// instance using information from the returned object
org.eclipse.persistence.sessions.Session sess = xmlUnmarshaller.getXMLContext().getSession(obj);
XMLDescriptor desc = (XMLDescriptor) sess.getClassDescriptor(obj);
// here we are assuming that if we've gotten this far, there
// must be a default root element set on the descriptor. if
// this is incorrect, we need to check for null and throw an
// exception
String rootName = desc.getDefaultRootElement();
if (rootName == null) {
return createJAXBElement(new QName(""), obj.getClass(), obj);
}
String rootNamespaceUri = null;
int idx = rootName.indexOf(":");
if (idx != -1) {
rootNamespaceUri = desc.getNamespaceResolver().resolveNamespacePrefix(rootName.substring(0, idx));
rootName = rootName.substring(idx + 1);
}
QName qname;
if (rootNamespaceUri == null) {
qname = new QName(rootName);
} else {
qname = new QName(rootNamespaceUri, rootName);
}
if(declaredClass != null){
return createJAXBElement(qname, declaredClass, obj);
}else{
return createJAXBElement(qname, obj.getClass(), obj);
}
}
public JAXBElement unmarshal(Node node, Class javaClass) throws JAXBException {
if(null == javaClass) {
throw new IllegalArgumentException();
}
try {
Class classToUnmarshalTo = getClassToUnmarshalTo(javaClass);
if(jaxbContext.getArrayClassesToGeneratedClasses() != null) {
Class generatedClass = jaxbContext.getArrayClassesToGeneratedClasses().get(javaClass.getCanonicalName());
if(generatedClass != null){
classToUnmarshalTo = generatedClass;
}
}
return buildJAXBElementFromObject(xmlUnmarshaller.unmarshal(node, classToUnmarshalTo), javaClass);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public Object unmarshal(Source source) throws JAXBException {
try {
Object value = xmlUnmarshaller.unmarshal(source);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public JAXBElement unmarshal(Source source, Class javaClass) throws JAXBException {
if(null == javaClass) {
throw new IllegalArgumentException();
}
try {
Class classToUnmarshalTo = getClassToUnmarshalTo(javaClass);
return buildJAXBElementFromObject(xmlUnmarshaller.unmarshal(source, classToUnmarshalTo), javaClass);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
private JAXBElement unmarshal(Source source, Class javaClass, Class declaredType) {
Class classToUnmarshalTo = javaClass;
if(jaxbContext.getArrayClassesToGeneratedClasses() != null) {
Class generatedClass = jaxbContext.getArrayClassesToGeneratedClasses().get(javaClass.getCanonicalName());
if(generatedClass != null){
classToUnmarshalTo = generatedClass;
}
}
return buildJAXBElementFromObject(xmlUnmarshaller.unmarshal(source, classToUnmarshalTo), declaredType);
}
public JAXBElement unmarshal(Source source, Type type) throws JAXBException {
if(null == type) {
throw new IllegalArgumentException();
}
try {
if(jaxbContext.getTypeToTypeMappingInfo() != null) {
TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(type);
if(tmi != null) {
return unmarshal(source, tmi);
}
}
Class unmarshalClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(type);
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(source, unmarshalClass, Object.class);
Class declaredClass = null;
if(type instanceof Class){
declaredClass = (Class)type;
}else{
declaredClass = Object.class;
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}else if(type instanceof Class){
return unmarshal(source, (Class)type, Object.class);
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
/**
* Unmarshal the object based on the binding metadata associated with the
* TypeMappingInfo.
*/
public JAXBElement unmarshal(Source source, TypeMappingInfo type) throws JAXBException {
try {
Class unmarshalClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(type);
RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(source, unmarshalClass);
Class declaredClass = null;
if(type.getType() instanceof Class){
declaredClass = (Class)type.getType();
}else{
declaredClass = Object.class;
}
Object value = unmarshalled.getValue();
if(adapter != null) {
try {
value = adapter.getXmlAdapter().unmarshal(value);
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}else if(type.getType() instanceof Class){
if(adapter != null) {
JAXBElement element = unmarshal(source, adapter.getBoundType());
try {
Object value = adapter.getXmlAdapter().unmarshal(element.getValue());
element.setValue(value);
return element;
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
return unmarshal(source, (Class)type.getType());
} else if(type.getType() instanceof ParameterizedType) {
return unmarshal(source, ((ParameterizedType)type.getType()).getRawType());
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public JAXBElement unmarshal(XMLStreamReader streamReader, Class javaClass) throws JAXBException {
if(null == streamReader || null == javaClass) {
throw new IllegalArgumentException();
}
try {
XMLStreamReaderReader staxReader = new XMLStreamReaderReader(xmlUnmarshaller);
XMLStreamReaderInputSource inputSource = new XMLStreamReaderInputSource(streamReader);
if(XMLConversionManager.getDefaultJavaTypes().get(javaClass) != null ||ClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(javaClass) ||ClassConstants.DURATION.isAssignableFrom(javaClass)) {
PrimitiveContentHandler primitiveContentHandler = new PrimitiveContentHandler(javaClass);
staxReader.setContentHandler(primitiveContentHandler);
staxReader.parse(inputSource);
return primitiveContentHandler.getJaxbElement();
}
Class classToUnmarshalTo = getClassToUnmarshalTo(javaClass);
JAXBElement unmarshalled = buildJAXBElementFromObject(xmlUnmarshaller.unmarshal(staxReader, inputSource, classToUnmarshalTo), javaClass);
if(classToUnmarshalTo != javaClass){
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), javaClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}
return unmarshalled;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
} catch (Exception e) {
throw new JAXBException(e);
}
}
public JAXBElement unmarshal(XMLStreamReader streamReader, Type type) throws JAXBException {
if(null == streamReader || null == type) {
throw new IllegalArgumentException();
}
try {
if(jaxbContext.getTypeToTypeMappingInfo() != null) {
TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(type);
if(tmi != null) {
return unmarshal(streamReader, tmi);
}
}
Class unmarshalClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(type);
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(streamReader, unmarshalClass);
Class declaredClass = null;
if(type instanceof Class){
declaredClass = (Class)type;
}else{
declaredClass = Object.class;
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}else if(type instanceof Class){
return unmarshal(streamReader, (Class)type);
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
/**
* Unmarshal the object based on the binding metadata associated with the
* TypeMappingInfo.
*/
public JAXBElement unmarshal(XMLStreamReader streamReader, TypeMappingInfo type) throws JAXBException {
try {
XMLDescriptor xmlDescriptor = type.getXmlDescriptor();
if(null != xmlDescriptor && null == getSchema()) {
RootLevelXmlAdapter adapter= null;
if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() >0){
adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
}
UnmarshalRecord unmarshalRecord = (UnmarshalRecord) xmlDescriptor.getObjectBuilder().createRecord((AbstractSession) xmlUnmarshaller.getXMLContext().getSession(0));
XMLStreamReaderReader staxReader = new XMLStreamReaderReader(xmlUnmarshaller);
unmarshalRecord.setUnmarshaller(xmlUnmarshaller);
unmarshalRecord.setXMLReader(staxReader);
staxReader.setContentHandler(unmarshalRecord);
staxReader.parse(streamReader);
Object value = null;
if(unmarshalRecord.isNil()) {
value = null;
} else {
value = unmarshalRecord.getCurrentObject();
}
if(value instanceof WrappedValue){
value = ((WrappedValue)value).getValue();
}
if(value instanceof ManyValue){
value = ((ManyValue)value).getItem();
}
if(adapter != null) {
try {
value = adapter.getXmlAdapter().unmarshal(value);
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
Class declaredClass = null;
if(type.getType() instanceof Class){
declaredClass = (Class)type.getType();
}else{
declaredClass = Object.class;
}
return new JAXBElement(new QName(unmarshalRecord.getRootElementNamespaceUri(), unmarshalRecord.getLocalName()), declaredClass, value);
}
if(jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
return unmarshal(streamReader, type.getType());
}
RootLevelXmlAdapter adapter= null;
if(jaxbContext.getTypeMappingInfoToJavaTypeAdapters().size() >0){
adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
}
Class unmarshalClass = null;
if(jaxbContext.getTypeMappingInfoToGeneratedType().size() >0){
unmarshalClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(type);
}
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(streamReader, unmarshalClass);
Class declaredClass = null;
if(type.getType() instanceof Class){
declaredClass = (Class)type.getType();
}else{
declaredClass = Object.class;
}
Object value = unmarshalled.getValue();
if(adapter != null) {
try {
value = adapter.getXmlAdapter().unmarshal(value);
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), value);
return returnVal;
}else if(type.getType() instanceof Class){
if(adapter != null) {
JAXBElement element = unmarshal(streamReader, adapter.getBoundType());
try {
Object value = adapter.getXmlAdapter().unmarshal(element.getValue());
element.setValue(value);
return element;
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
return unmarshal(streamReader, (Class)type.getType());
} else if(type.getType() instanceof ParameterizedType) {
return unmarshal(streamReader, ((ParameterizedType)type.getType()).getRawType());
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
} catch (SAXException e) {
throw new JAXBException(e);
}
}
public Object unmarshal(XMLStreamReader streamReader) throws JAXBException {
if(null == streamReader) {
throw new IllegalArgumentException();
}
try {
XMLStreamReaderReader staxReader = new XMLStreamReaderReader(xmlUnmarshaller);
XMLStreamReaderInputSource inputSource = new XMLStreamReaderInputSource(streamReader);
Object value = xmlUnmarshaller.unmarshal(staxReader, inputSource);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public JAXBElement unmarshal(XMLEventReader eventReader, Class javaClass) throws JAXBException {
if(null == eventReader || null == javaClass) {
throw new IllegalArgumentException();
}
try {
Class classToUnmarshalTo = getClassToUnmarshalTo(javaClass);
XMLEventReaderReader staxReader = new XMLEventReaderReader(xmlUnmarshaller);
XMLEventReaderInputSource inputSource = new XMLEventReaderInputSource(eventReader);
JAXBElement unmarshalled = buildJAXBElementFromObject(xmlUnmarshaller.unmarshal(staxReader, inputSource, classToUnmarshalTo), javaClass);
if(classToUnmarshalTo != javaClass){
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), javaClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}
return unmarshalled;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public JAXBElement unmarshal(XMLEventReader eventReader, Type type) throws JAXBException {
if(null == eventReader || null == type) {
throw new IllegalArgumentException();
}
try {
if(jaxbContext.getTypeToTypeMappingInfo() != null) {
TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(type);
if(tmi != null) {
return unmarshal(eventReader, tmi);
}
}
Class unmarshalClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(type);
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(eventReader, unmarshalClass);
Class declaredClass = null;
if(type instanceof Class){
declaredClass = (Class)type;
}else{
declaredClass = Object.class;
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), unmarshalled.getValue());
return returnVal;
}else if(type instanceof Class){
return unmarshal(eventReader, (Class)type);
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
/**
* Unmarshal the object based on the binding metadata associated with the
* TypeMappingInfo.
*/
public JAXBElement unmarshal(XMLEventReader eventReader, TypeMappingInfo type) throws JAXBException {
try {
if(jaxbContext.getTypeMappingInfoToGeneratedType() == null) {
return unmarshal(eventReader, type.getType());
}
Class unmarshalClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(type);
RootLevelXmlAdapter adapter = jaxbContext.getTypeMappingInfoToJavaTypeAdapters().get(type);
if(unmarshalClass != null){
JAXBElement unmarshalled = unmarshal(eventReader, unmarshalClass);
Class declaredClass = null;
if(type.getType() instanceof Class){
declaredClass = (Class)type.getType();
}else{
declaredClass = Object.class;
}
Object value = unmarshalled.getValue();
if(adapter != null) {
try {
value = adapter.getXmlAdapter().unmarshal(value);
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
JAXBElement returnVal = new JAXBElement(unmarshalled.getName(), declaredClass, unmarshalled.getScope(), value);
return returnVal;
}else if(type.getType() instanceof Class){
if(adapter != null) {
JAXBElement element = unmarshal(eventReader, adapter.getBoundType());
try {
Object value = adapter.getXmlAdapter().unmarshal(element.getValue());
element.setValue(value);
return element;
} catch(Exception ex) {
throw new JAXBException(XMLMarshalException.marshalException(ex));
}
}
return unmarshal(eventReader, (Class)type.getType());
} else if(type.getType() instanceof ParameterizedType) {
return unmarshal(eventReader, ((ParameterizedType)type.getType()).getRawType());
}
return null;
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public Object unmarshal(XMLEventReader eventReader) throws JAXBException {
if(null == eventReader) {
throw new IllegalArgumentException();
}
try {
XMLEventReaderReader staxReader = new XMLEventReaderReader(xmlUnmarshaller);
XMLEventReaderInputSource inputSource = new XMLEventReaderInputSource(eventReader);
Object value = xmlUnmarshaller.unmarshal(staxReader, inputSource);
return createJAXBElementOrUnwrapIfRequired(value);
} catch (XMLMarshalException xmlMarshalException) {
throw handleXMLMarshalException(xmlMarshalException);
}
}
public UnmarshallerHandler getUnmarshallerHandler() {
return new JAXBUnmarshallerHandler(this);
}
public void setValidating(boolean validate) throws JAXBException {
if (validate) {
xmlUnmarshaller.setValidationMode(XMLUnmarshaller.SCHEMA_VALIDATION);
} else {
xmlUnmarshaller.setValidationMode(XMLUnmarshaller.NONVALIDATING);
}
}
public boolean isValidating() throws JAXBException {
return xmlUnmarshaller.getValidationMode() != XMLUnmarshaller.NONVALIDATING;
}
public void setEventHandler(ValidationEventHandler newValidationEventHandler) throws JAXBException {
if (null == newValidationEventHandler) {
validationEventHandler = new DefaultValidationEventHandler();
} else {
validationEventHandler = newValidationEventHandler;
}
xmlUnmarshaller.setErrorHandler(new JAXBErrorHandler(validationEventHandler));
}
public ValidationEventHandler getEventHandler() throws JAXBException {
return validationEventHandler;
}
public void setProperty(String key, Object value) throws PropertyException {
if (key == null) {
throw new IllegalArgumentException();
} else if (UnmarshallerProperties.ID_RESOLVER.equals(key)) {
setIDResolver((IDResolver) value);
} else if (SUN_ID_RESOLVER.equals(key) || SUN_JSE_ID_RESOLVER.equals(key)) {
setIDResolver(new IDResolverWrapper(value));
} else {
throw new PropertyException(key, value);
}
}
public Object getProperty(String key) throws PropertyException {
if (key == null) {
throw new IllegalArgumentException();
}
if (UnmarshallerProperties.ID_RESOLVER.equals(key)) {
return xmlUnmarshaller.getIDResolver();
} else if (SUN_ID_RESOLVER.equals(key) || SUN_JSE_ID_RESOLVER.equals(key)) {
IDResolverWrapper wrapper = (IDResolverWrapper) xmlUnmarshaller.getIDResolver();
return wrapper.getResolver();
}
throw new PropertyException(key);
}
public Unmarshaller.Listener getListener() {
return ((JAXBUnmarshalListener)xmlUnmarshaller.getUnmarshalListener()).getListener();
}
public void setListener(Unmarshaller.Listener listener) {
((JAXBUnmarshalListener)xmlUnmarshaller.getUnmarshalListener()).setListener(listener);
}
public XmlAdapter getAdapter(Class javaClass) {
HashMap result = (HashMap) xmlUnmarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
if (result == null) {
return null;
}
return (XmlAdapter) result.get(javaClass);
}
public void setAdapter(Class javaClass, XmlAdapter adapter) {
HashMap result = (HashMap) xmlUnmarshaller.getProperty(XML_JAVATYPE_ADAPTERS);
if (result == null) {
result = new HashMap();
xmlUnmarshaller.getProperties().put(XML_JAVATYPE_ADAPTERS, result);
}
result.put(javaClass, adapter);
}
public void setAdapter(XmlAdapter adapter) {
setAdapter(adapter.getClass(), adapter);
}
public void setSchema(Schema schema) {
this.xmlUnmarshaller.setSchema(schema);
}
public Schema getSchema() {
return this.xmlUnmarshaller.getSchema();
}
public AttachmentUnmarshaller getAttachmentUnmarshaller() {
if(xmlUnmarshaller.getAttachmentUnmarshaller() == null) {
return null;
}
return ((AttachmentUnmarshallerAdapter)xmlUnmarshaller.getAttachmentUnmarshaller()).getAttachmentUnmarshaller();
}
public void setAttachmentUnmarshaller(AttachmentUnmarshaller unmarshaller) {
if(unmarshaller == null) {
xmlUnmarshaller.setAttachmentUnmarshaller(null);
} else {
xmlUnmarshaller.setAttachmentUnmarshaller(new AttachmentUnmarshallerAdapter(unmarshaller));
}
}
public void setUnmarshalCallbacks(java.util.HashMap callbacks) {
((JAXBUnmarshalListener)xmlUnmarshaller.getUnmarshalListener()).setClassBasedUnmarshalEvents(callbacks);
}
private Object createJAXBElementOrUnwrapIfRequired(Object value){
if(value instanceof XMLRoot){
JAXBElement jaxbElement = createJAXBElementFromXMLRoot((XMLRoot)value, Object.class);
jaxbElement.setNil(((XMLRoot) value).isNil());
return jaxbElement;
} else if(value instanceof WrappedValue) {
return ((WrappedValue)value).getValue();
}
return value;
}
private JAXBElement createJAXBElementFromXMLRoot(XMLRoot xmlRoot, Class declaredType){
Object value = xmlRoot.getObject();
if(value instanceof WrappedValue){
QName qname = new QName(xmlRoot.getNamespaceURI(), xmlRoot.getLocalName());
return new JAXBElement(qname, ((WrappedValue)value).getDeclaredType(), ((WrappedValue)value).getValue());
}
if(value instanceof JAXBElement) {
return (JAXBElement) value;
}
QName qname = new QName(xmlRoot.getNamespaceURI(), xmlRoot.getLocalName());
if(value instanceof ManyValue){
value = ((ManyValue)value).getItem();
}
Map qNamesToDeclaredClasses = jaxbContext.getQNamesToDeclaredClasses();
if(qNamesToDeclaredClasses != null && qNamesToDeclaredClasses.size() >0){
Class declaredClass = qNamesToDeclaredClasses.get(qname);
if(declaredClass != null){
return createJAXBElement(qname, declaredClass, value);
}
}
XMLDescriptor descriptorForQName = xmlUnmarshaller.getXMLContext().getDescriptor(qname);
if(descriptorForQName != null){
return createJAXBElement(qname, descriptorForQName.getJavaClass(), value);
}
if(value != null){
XMLConversionManager xcm = ((XMLConversionManager)xmlUnmarshaller.getXMLContext().getSession(0).getDatasourcePlatform().getConversionManager());
if( xcm.getDefaultJavaTypes().get(value.getClass()) != null){
return createJAXBElement(qname, declaredType, value);
}
}
return createJAXBElement(qname, declaredType, value);
}
private JAXBElement createJAXBElement(QName qname, Class theClass, Object value){
if(theClass == null){
return new JAXBElement(qname, Object.class, value);
}
if(ClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(theClass)){
theClass = ClassConstants.XML_GREGORIAN_CALENDAR;
}else if(ClassConstants.DURATION.isAssignableFrom(theClass)){
theClass = ClassConstants.DURATION;
}
return new JAXBElement(qname, theClass, value);
}
public JAXBContext getJaxbContext() {
return jaxbContext;
}
public void setJaxbContext(JAXBContext jaxbContext) {
this.jaxbContext = jaxbContext;
}
private Class getClassToUnmarshalTo(Class originalClass) {
Class classToUnmarshalTo = originalClass;
if(jaxbContext.getArrayClassesToGeneratedClasses() != null && jaxbContext.getArrayClassesToGeneratedClasses().size() >0) {
Class generatedClass = jaxbContext.getArrayClassesToGeneratedClasses().get(originalClass.getCanonicalName());
if(generatedClass != null){
classToUnmarshalTo = generatedClass;
}
}
if(jaxbContext.getCollectionClassesToGeneratedClasses() != null && jaxbContext.getCollectionClassesToGeneratedClasses().size() >0){
Class generatedClass = jaxbContext.getCollectionClassesToGeneratedClasses().get(originalClass);
if(generatedClass != null){
classToUnmarshalTo = generatedClass;
}
}
if(jaxbContext.getTypeToTypeMappingInfo() != null){
TypeMappingInfo tmi = jaxbContext.getTypeToTypeMappingInfo().get(originalClass);
if(tmi != null && jaxbContext.getTypeMappingInfoToGeneratedType() != null) {
Class generatedClass = jaxbContext.getTypeMappingInfoToGeneratedType().get(tmi);
if(generatedClass != null){
classToUnmarshalTo = generatedClass;
}
}
}
return classToUnmarshalTo;
}
private JAXBException handleXMLMarshalException(XMLMarshalException xmlMarshalException) {
if(xmlMarshalException.getErrorCode() == XMLMarshalException.NULL_ARGUMENT) {
throw new IllegalArgumentException(xmlMarshalException);
} else {
return new UnmarshalException(xmlMarshalException);
}
}
/**
* Return this Unmarshaller's custom IDResolver.
*
* @see IDResolver
* @since 2.3.3
* @return the custom IDResolver, or null if one has not been specified.
*/
public IDResolver getIDResolver() {
return getXMLUnmarshaller().getIDResolver();
}
/**
* Set this Unmarshaller's custom IDResolver.
*
* @see IDResolver
* @since 2.3.3
*/
public void setIDResolver(IDResolver idResolver) {
getXMLUnmarshaller().setIDResolver(idResolver);
}
private static class PrimitiveContentHandler extends DefaultHandler {
private Class clazz;
private JAXBElement jaxbElement;
private Map namespaces = new HashMap(3);
private StringBuilder stringBuilder = new StringBuilder();
private String xsiType;
private boolean xsiNil;
public PrimitiveContentHandler(Class clazz) {
this.clazz = clazz;
}
public void characters(char[] ch, int start, int length) throws SAXException {
stringBuilder.append(ch, start, length);
}
@Override
public void endElement(String namespaceURI, String localName, String qualifiedName) throws SAXException {
XMLConversionManager xcm = XMLConversionManager.getDefaultXMLManager();
T value;
if(xsiNil) {
value = null;
} else if(null == xsiType) {
if (clazz == ClassConstants.ABYTE || clazz == ClassConstants.APBYTE || clazz.getCanonicalName().equals("javax.activation.DataHandler")) {
value = (T) xcm.convertObject(stringBuilder.toString(), clazz, XMLConstants.BASE_64_BINARY_QNAME);
} else {
value = (T) xcm.convertObject(stringBuilder.toString(), clazz);
}
} else {
int colonIndex = xsiType.indexOf(':');
String typePrefix;
String typeName;
if(colonIndex == -1) {
typePrefix = XMLConstants.EMPTY_STRING;
typeName = xsiType;
} else {
typePrefix = xsiType.substring(0, colonIndex);
typeName = xsiType.substring(colonIndex + 1);
}
String typeNamespace = namespaces.get(typePrefix);
QName typeQName = new QName(typeNamespace, typeName);
value = (T) xcm.convertObject(stringBuilder.toString(), clazz, typeQName);
}
QName qName;
if(namespaceURI != null && namespaceURI.length() == 0) {
qName = new QName(qualifiedName);
} else {
qName = new QName(namespaceURI, localName);
}
jaxbElement = new JAXBElement(qName, clazz, value);
}
public JAXBElement getJaxbElement() {
return jaxbElement;
}
@Override
public void startElement(String namespaceURI, String localName, String qualifiedName, Attributes attributes) throws SAXException {
xsiNil = attributes.getValue(XMLConstants.SCHEMA_INSTANCE_URL, XMLConstants.SCHEMA_NIL_ATTRIBUTE) != null;
if(!xsiNil) {
xsiType = attributes.getValue(XMLConstants.SCHEMA_INSTANCE_URL, XMLConstants.SCHEMA_TYPE_ATTRIBUTE);
}
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
namespaces.put(prefix, uri);
}
}
}