blob: 1dd4c229f108c532f1c0049e432f48904b7fccc5 [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:
// 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.exceptions.XMLMarshalException;
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.VariableXPathCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.XMLContainerMapping;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.MapContainerPolicy;
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.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 XMLVariableXPathCollectionMapping extends XMLCompositeCollectionMapping implements VariableXPathCollectionMapping<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLRecord>, XMLMapping, XMLContainerMapping {
protected String variableAttributeName;
protected String variableGetMethodName;
protected String variableSetMethodName;
private AttributeAccessor variableAttributeAccessor;
private boolean isAttribute;
/**
* Default constructor.
*/
public XMLVariableXPathCollectionMapping() {
super();
}
@Override
public void initialize(AbstractSession session) throws DescriptorException {
super.initialize(session);
if(variableAttributeAccessor == null){
if(variableAttributeName != null){
this.variableAttributeAccessor = new InstanceVariableAttributeAccessor();
this.variableAttributeAccessor.setAttributeName(variableAttributeName);
}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());
}
public void useMapClass(String concreteContainerClassName) {
MapContainerPolicy policy = new MapContainerPolicy(concreteContainerClassName);
this.setContainerPolicy(policy);
}
@Override
protected void initializeMapContainerPolicy(AbstractSession session, MapContainerPolicy cp){
super.initializeMapContainerPolicy(session, cp);
if(variableAttributeName != null){
cp.setKeyName(variableAttributeName);
}else if(variableGetMethodName != null){
cp.setKeyMethodName(variableGetMethodName);
}
}
@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();
}
// public Vector getFields() {
// return fields;
//return NO_FIELDS;
// }
@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(field != null){
setField(getDescriptor().buildField(this.field));
setFields(collectFields());
}
if (hasConverter()) {
getConverter().initialize(this, session);
}
}
@Override
public boolean isAbstractCompositeCollectionMapping(){
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 writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) throws DescriptorException {
if (this.isReadOnly()) {
return;
}
Object attributeValue = this.getAttributeValueFromObject(object);
ContainerPolicy cp = this.getContainerPolicy();
Object iter = cp.iteratorFor(attributeValue);
if(null != iter) {
while(cp.hasNext(iter)) {
Object element = cp.next(iter, session);
// convert the value - if necessary
element = convertObjectValueToDataValue(element, session, ((XMLRecord) row).getMarshaller());
if(element != null) {
XMLField variableField = new XMLField();
XMLRecord xmlRow = (XMLRecord)row;
//variableField.setXPathFragment(getXPathFragmentForValue(element,(XMLRecord)row));
variableField.setXPathFragment(getXPathFragmentForValue(element,xmlRow.getNamespaceResolver(), xmlRow.isNamespaceAware(), xmlRow.getNamespaceSeparator()));
row.put(variableField, buildCompositeRow(variableField, element, session, row, writeType));
}
}
}
}
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 sep) {
Object value = getVariableAttributeAccessor().getAttributeValueFromObject(obj);
if(value == null){
throw XMLMarshalException.nullValueNotAllowed(getVariableAttributeName(), getReferenceClassName());
}
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();
frag.setLocalName(returnString);
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 + sep + returnString;
}
}
//frag.setXPath(returnString);
//frag.setLocalName(localName);
frag.setNamespaceURI(uri);
return frag;
}
@Override
public boolean isAttribute() {
return isAttribute;
}
@Override
public void setAttribute(boolean isAttribute) {
this.isAttribute = isAttribute;
}
@Override
public void useMapClassName(String concreteContainerClassName, String methodName) {
// the reference class has to be specified before coming here
if (this.getReferenceClassName() == null) {
throw DescriptorException.referenceClassNotSpecified(this);
}
MapContainerPolicy policy = new MapContainerPolicy(concreteContainerClassName);
policy.setKeyName(methodName, getReferenceClass().getName());
this.setContainerPolicy(policy);
}
}