org.eclipse.persistence.oxm.mappings.XMLVariableXPathObjectMapping Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 2022 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:
// Matt MacIvor - 2.5.1 - Initial Implementation
package org.eclipse.persistence.oxm.mappings;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.sessions.Session;
public class XMLVariableXPathObjectMapping extends XMLCompositeObjectMapping implements VariableXPathObjectMapping, XMLMapping {
protected String variableAttributeName;
protected String variableGetMethodName;
protected String variableSetMethodName;
private AttributeAccessor variableAttributeAccessor;
private boolean isAttribute;
@Override
public void initialize(AbstractSession session) throws DescriptorException {
//modified so that reference class on composite mappings is no longer mandatory
String referenceClassName = getReferenceClassName();
if ((this.referenceClass == null) && (referenceClassName != null)) {
if (!referenceClassName.equals(XMLConstants.UNKNOWN_OR_TRANSIENT_CLASS)) {
setReferenceClass(session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(referenceClassName));
}
}
if (this.referenceClass != null) {
super.initialize(session);
} else {
//below should be the same as AbstractCompositeObjectMapping.initialize
if (this.field == null) {
throw DescriptorException.fieldNameNotSetInMapping(this);
}
setField(getDescriptor().buildField(this.field));
setFields(collectFields());
// initialize the converter - if necessary
if (hasConverter()) {
getConverter().initialize(this, session);
}
}
final XMLInverseReferenceMapping inverseReferenceMapping = getInverseReferenceMapping();
if (null != inverseReferenceMapping && null != inverseReferenceMapping.getAttributeAccessor()) {
inverseReferenceMapping.getAttributeAccessor().initializeAttributes(this.referenceClass);
}
if(variableAttributeName != null){
this.variableAttributeAccessor = new InstanceVariableAttributeAccessor();
this.variableAttributeAccessor.setAttributeName(variableAttributeName);
this.variableAttributeAccessor.initializeAttributes(this.getReferenceClass());
}else if(variableGetMethodName != null){
this.variableAttributeAccessor = new MethodAttributeAccessor();
this.variableAttributeAccessor.setAttributeName("VARIABLE");
((MethodAttributeAccessor)this.variableAttributeAccessor).setGetMethodName(variableGetMethodName);
if(variableSetMethodName == null){
this.variableAttributeAccessor.setIsWriteOnly(true);
}else{
((MethodAttributeAccessor)this.variableAttributeAccessor).setSetMethodName(variableSetMethodName);
}
this.variableAttributeAccessor.initializeAttributes(this.getReferenceClass());
}
}
@Override
protected Vector collectFields() {
if(field != null){
return super.collectFields();
}
// Vector fields = new Vector(1);
//fields.addElement(this.getField());
//return fields;
return NO_FIELDS;
}
@Override
public Vector getFields() {
return collectFields();
}
@Override
protected void initializeReferenceDescriptorAndField(AbstractSession session){
if (getReferenceClass() == null) {
throw DescriptorException.referenceClassNotSpecified(this);
}
setReferenceDescriptor(session.getDescriptor(getReferenceClass()));
ClassDescriptor refDescriptor = this.getReferenceDescriptor();
if (refDescriptor == null) {
session.getIntegrityChecker().handleError(DescriptorException.descriptorIsMissing(getReferenceClass().getName(), this));
return;
}
if (hasConverter()) {
getConverter().initialize(this, session);
}
}
@Override
public boolean isAbstractCompositeObjectMapping(){
return false;
}
public String getVariableAttributeName() {
return variableAttributeName;
}
@Override
public void setVariableAttributeName(String variableAttributeName) {
this.variableAttributeName = variableAttributeName;
}
public String getVariableGetMethodName() {
return variableGetMethodName;
}
@Override
public void setVariableGetMethodName(String variableGetMethodName) {
this.variableGetMethodName = variableGetMethodName;
}
public String getVariableSetMethodName() {
return variableSetMethodName;
}
@Override
public void setVariableSetMethodName(String variableSetMethodName) {
this.variableSetMethodName = variableSetMethodName;
}
@Override
public AttributeAccessor getVariableAttributeAccessor() {
return variableAttributeAccessor;
}
@Override
public void setVariableAttributeAccessor(
AttributeAccessor variableAttributeAccessor) {
this.variableAttributeAccessor = variableAttributeAccessor;
}
@Override
public void writeSingleValue(Object value, Object parent, XMLRecord xmlRow, AbstractSession session) {
Object attributeValue = convertObjectValueToDataValue(value, session, xmlRow.getMarshaller());
if (attributeValue != null) {
XMLField variableField = new XMLField();
variableField.setXPathFragment(getXPathFragmentForValue(attributeValue, xmlRow.getNamespaceResolver(), xmlRow.isNamespaceAware(), xmlRow.getNamespaceSeparator()));
xmlRow.put(variableField, buildCompositeRow(variableField, attributeValue, session, xmlRow, WriteType.UNDEFINED));
}
}
protected AbstractRecord buildCompositeRow(XMLField variableField, Object attributeValue, AbstractSession session, AbstractRecord parentRow, WriteType writeType) {
ClassDescriptor classDesc = getReferenceDescriptor(attributeValue, session);
return buildCompositeRowForDescriptor(classDesc, attributeValue, session, (XMLRecord)parentRow, writeType);
}
@Override
public XPathFragment getXPathFragmentForValue(Object obj, NamespaceResolver nr, boolean isNamespaceAware, char namespaceSep) {
Object value = getVariableAttributeAccessor().getAttributeValueFromObject(obj);
String returnString;
String uri = null;
if(value instanceof QName){
returnString = ((QName)value).getLocalPart();
uri = ((QName)value).getNamespaceURI();
}else{
returnString = (String)value;
}
XPathFragment frag = new XPathFragment();
if(isNamespaceAware && uri != null && uri.length() >0){
String prefix = nr.resolveNamespaceURI(uri);
if(prefix == null){
prefix = nr.generatePrefix();
//marshalRecord.namespaceDeclaration(prefix, uri);
frag.setGeneratedPrefix(true);
}
if(prefix != null && prefix.length() >0){
frag.setPrefix(prefix);
returnString = prefix + namespaceSep + returnString;
}
//In case of JSON marshalling namespace separator there should different like '.', than default in XPathFragment ':'.
//Namespace separator from there should be promoted to XPathFragment to correctly set localName.
if(namespaceSep != 0){
frag.setNamespaceSeparator(namespaceSep);
}
}
frag.setXPath(returnString);
frag.setNamespaceURI(uri);
return frag;
}
@Override
public boolean isAttribute() {
return isAttribute;
}
@Override
public void setAttribute(boolean isAttribute) {
this.isAttribute = isAttribute;
}
}