/******************************************************************************* * Copyright (c) 1998, 2015 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: * 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; 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); } 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; } public Vector getFields() { return collectFields(); } // public Vector getFields() { // return fields; //return NO_FIELDS; // } 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); } } public boolean isAbstractCompositeCollectionMapping(){ return false; } public String getVariableAttributeName() { return variableAttributeName; } public void setVariableAttributeName(String variableAttributeName) { this.variableAttributeName = variableAttributeName; } public String getVariableGetMethodName() { return variableGetMethodName; } public void setVariableGetMethodName(String variableGetMethodName) { this.variableGetMethodName = variableGetMethodName; } public String getVariableSetMethodName() { return variableSetMethodName; } public void setVariableSetMethodName(String variableSetMethodName) { this.variableSetMethodName = variableSetMethodName; } public AttributeAccessor getVariableAttributeAccessor() { return variableAttributeAccessor; } public void setVariableAttributeAccessor( AttributeAccessor variableAttributeAccessor) { this.variableAttributeAccessor = variableAttributeAccessor; } 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); } 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; } public boolean isAttribute() { return isAttribute; } public void setAttribute(boolean isAttribute) { this.isAttribute = isAttribute; } 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); } }