| /* |
| * 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.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<AbstractSession, AttributeAccessor, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLRecord>, 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; |
| } |
| } |
| frag.setXPath(returnString); |
| frag.setNamespaceURI(uri); |
| |
| |
| return frag; |
| } |
| |
| |
| @Override |
| public boolean isAttribute() { |
| return isAttribute; |
| } |
| |
| @Override |
| public void setAttribute(boolean isAttribute) { |
| this.isAttribute = isAttribute; |
| } |
| |
| |
| |
| } |