blob: 437fd66d5ac52201a13656151fd656e520de7a91 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 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 v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// bdoughan - July 29/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.internal.jaxb;
import jakarta.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.mappings.converters.CoreConverter;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.sessions.Session;
public class JAXBElementConverter implements XMLConverter {
private XPathFragment rootFragment;
private Field associatedField;
private CoreMapping mapping;
private CoreConverter nestedConverter;
private Class<?> declaredType;
private Class<?> scope;
public JAXBElementConverter(Field associatedField, Class<?> declaredType, Class<?> scope) {
this.associatedField = associatedField;
this.declaredType = declaredType;
this.scope = scope;
}
public CoreConverter getNestedConverter() {
return nestedConverter;
}
public void setNestedConverter(CoreConverter nestedConverter) {
this.nestedConverter = nestedConverter;
}
@Override
public Object convertDataValueToObjectValue(Object dataValue,
Session session, XMLUnmarshaller unmarshaller) {
return convertDataValueToObjectValue(dataValue, session);
}
@Override
public Object convertObjectValueToDataValue(Object objectValue,
Session session, XMLMarshaller marshaller) {
return convertObjectValueToDataValue(objectValue, session);
}
@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
QName name = new QName(rootFragment.getNamespaceURI(), rootFragment.getLocalName());
if(mapping.isAbstractDirectMapping() && null == nestedConverter){
if ((dataValue == null) || (dataValue.getClass() != mapping.getAttributeClassification())) {
try {
dataValue = session.getDatasourcePlatform().convertObject(dataValue, mapping.getAttributeClassification());
} catch (ConversionException e) {
throw ConversionException.couldNotBeConverted(this, mapping.getDescriptor(), e);
}
}
}
if(null != nestedConverter) {
dataValue = nestedConverter.convertDataValueToObjectValue(dataValue, session);
}
if(dataValue instanceof JAXBElement) {
return dataValue;
}
if(null == declaredType) {
return new JAXBElement(name, Object.class, scope, dataValue);
} else {
return new JAXBElement(name, declaredType, scope, dataValue);
}
}
@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
if(objectValue instanceof JAXBElement) {
ClassDescriptor desc = session.getDescriptor(objectValue);
if(desc == null || objectValue instanceof WrappedValue){
objectValue = ((JAXBElement)objectValue).getValue();
}
} else if(objectValue instanceof Root) {
objectValue = ((Root) objectValue).getObject();
}
if(null != nestedConverter) {
objectValue = nestedConverter.convertObjectValueToDataValue(objectValue, session);
}
return objectValue;
}
@Override
public void initialize(DatabaseMapping mapping, Session session) {
if(null != nestedConverter) {
nestedConverter.initialize(mapping, session);
}
XPathFragment fragment = associatedField.getXPathFragment();
while(fragment.getNextFragment() != null && !(fragment.getNextFragment().nameIsText())) {
fragment = fragment.getNextFragment();
}
if(fragment.hasNamespace() && associatedField.getNamespaceResolver() != null){
String uri = associatedField.getNamespaceResolver().resolveNamespacePrefix(fragment.getPrefix());
fragment.setNamespaceURI(uri);
}
this.rootFragment = fragment;
this.mapping = mapping;
}
@Override
public boolean isMutable() {
return false;
}
}