org.eclipse.persistence.internal.oxm.XMLChoiceCollectionMappingUnmarshalNodeValue 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, 2020 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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.oxm;
import java.util.Collection;
import java.util.Map;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.mappings.AnyCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.BinaryDataCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CollectionReferenceMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.DirectCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.UnmarshalContext;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.xml.sax.Attributes;
/**
* INTERNAL:
* Purpose: This is how the XML Choice Collection Mapping is
* handled when used with the TreeObjectBuilder.
* @author mmacivor
*/
public class XMLChoiceCollectionMappingUnmarshalNodeValue extends MappingNodeValue implements ContainerValue {
private NodeValue choiceElementNodeValue;
private NodeValue choiceElementMarshalNodeValue;
private ChoiceCollectionMapping xmlChoiceCollectionMapping;
private Mapping nestedMapping;
private Map fieldToNodeValues;
private Field xmlField;
private ContainerValue containerNodeValue;
private boolean isMixedNodeValue;
private boolean isAny;
private int index = -1;
public XMLChoiceCollectionMappingUnmarshalNodeValue(ChoiceCollectionMapping mapping, Field xmlField) {
this.xmlChoiceCollectionMapping = mapping;
this.xmlField = xmlField;
if(xmlField == null && mapping.isAny()){
isAny = true;
}else{
this.nestedMapping = (Mapping)mapping.getChoiceElementMappings().get(xmlField);
}
initializeNodeValue();
}
public XMLChoiceCollectionMappingUnmarshalNodeValue(ChoiceCollectionMapping mapping, Field xmlField, Mapping nestedMapping) {
this.xmlChoiceCollectionMapping = mapping;
this.xmlField = xmlField;
this.nestedMapping = nestedMapping;
initializeNodeValue();
}
@Override
public boolean isOwningNode(XPathFragment xPathFragment) {
if(isMixedNodeValue) {
if(xPathFragment.nameIsText()) {
return true;
} else {
return false;
}
}
return choiceElementNodeValue.isOwningNode(xPathFragment);
}
private void initializeNodeValue() {
if(nestedMapping == null && isAny){
nestedMapping = xmlChoiceCollectionMapping.getAnyMapping();
}
Mapping xmlMapping = this.nestedMapping;
if(xmlMapping instanceof BinaryDataCollectionMapping) {
choiceElementNodeValue = new XMLBinaryDataCollectionMappingNodeValue((BinaryDataCollectionMapping)xmlMapping);
choiceElementMarshalNodeValue = choiceElementNodeValue;
} else if(xmlMapping instanceof DirectCollectionMapping) {
choiceElementNodeValue = new XMLCompositeDirectCollectionMappingNodeValue((DirectCollectionMapping)xmlMapping);
choiceElementMarshalNodeValue = choiceElementNodeValue;
} else if(xmlMapping instanceof CompositeCollectionMapping){
choiceElementNodeValue = new XMLCompositeCollectionMappingNodeValue((CompositeCollectionMapping)xmlMapping);
choiceElementMarshalNodeValue = choiceElementNodeValue;
}else if(xmlMapping instanceof AnyCollectionMapping){
choiceElementNodeValue = new XMLAnyCollectionMappingNodeValue((AnyCollectionMapping)xmlMapping);
choiceElementMarshalNodeValue = choiceElementNodeValue;
} else {
choiceElementNodeValue = new XMLCollectionReferenceMappingNodeValue((CollectionReferenceMapping)xmlMapping, xmlField);
CollectionReferenceMapping refMapping = ((CollectionReferenceMapping)xmlMapping);
if(refMapping.usesSingleNode() || refMapping.getFields().size() == 1) {
choiceElementMarshalNodeValue = new XMLCollectionReferenceMappingNodeValue(refMapping, xmlField);
} else {
choiceElementMarshalNodeValue = new XMLCollectionReferenceMappingMarshalNodeValue((CollectionReferenceMapping)xmlMapping);
}
}
}
public void setContainerNodeValue(XMLChoiceCollectionMappingUnmarshalNodeValue nodeValue) {
this.containerNodeValue = nodeValue;
}
public void setNullValue(Object object, CoreSession session) {
xmlChoiceCollectionMapping.setAttributeValueInObject(object, null);
}
@Override
public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
Object collection = unmarshalRecord.getContainerInstance(this.containerNodeValue);
if(null != xmlChoiceCollectionMapping.getConverter()) {
UnmarshalContext unmarshalContext = unmarshalRecord.getUnmarshalContext();
unmarshalRecord.setUnmarshalContext(new ChoiceUnmarshalContext(unmarshalContext, xmlChoiceCollectionMapping));
this.choiceElementNodeValue.endElement(xPathFragment, unmarshalRecord, collection);
unmarshalRecord.setUnmarshalContext(unmarshalContext);
} else {
this.choiceElementNodeValue.endElement(xPathFragment, unmarshalRecord, collection);
}
}
@Override
public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
return this.choiceElementNodeValue.startElement(xPathFragment, unmarshalRecord, atts);
}
@Override
public void setXPathNode(XPathNode xPathNode) {
super.setXPathNode(xPathNode);
this.choiceElementNodeValue.setXPathNode(xPathNode);
}
@Override
public Object getContainerInstance() {
return getContainerPolicy().containerInstance();
}
@Override
public void setContainerInstance(Object object, Object containerInstance) {
xmlChoiceCollectionMapping.setAttributeValueInObject(object, containerInstance);
}
@Override
public CoreContainerPolicy getContainerPolicy() {
return xmlChoiceCollectionMapping.getContainerPolicy();
}
@Override
public boolean isContainerValue() {
return true;
}
@Override
public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
//empty impl in the unmarshal node value
return false;
}
@Override
public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
//dummy impl in the unmarshal node value
return false;
}
public NodeValue getChoiceElementNodeValue() {
return this.choiceElementNodeValue;
}
public NodeValue getChoiceElementMarshalNodeValue() {
return this.choiceElementMarshalNodeValue;
}
@Override
public boolean isUnmarshalNodeValue() {
return true;
}
@Override
public boolean isWrapperAllowedAsCollectionName() {
return false;
}
@Override
public boolean isMarshalNodeValue() {
return false;
}
@Override
public ChoiceCollectionMapping getMapping() {
return xmlChoiceCollectionMapping;
}
@Override
public boolean getReuseContainer() {
return getMapping().getReuseContainer();
}
public void setFieldToNodeValues(Map fieldToNodeValues) {
this.fieldToNodeValues = fieldToNodeValues;
}
public Collection getAllNodeValues() {
return this.fieldToNodeValues.values();
}
/**
* The underlying choice element node value will handle attributes.
*
*/
@Override
public void attribute(UnmarshalRecord unmarshalRecord, String URI, String localName, String value) {
this.choiceElementNodeValue.attribute(unmarshalRecord, URI, localName, value);
}
/**
* INTERNAL:
* Indicates that this is the choice mapping node value that represents the mixed content.
*/
public void setIsMixedNodeValue(boolean isMixed) {
this.isMixedNodeValue = isMixed;
}
/**
* INTERNAL:
* Return true if this is the node value representing mixed content.
*/
@Override
public boolean isMixedContentNodeValue() {
return this.isMixedNodeValue;
}
/**
* INTERNAL:
* Used to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord
*/
@Override
public void setIndex(int index){
this.index = index;
}
/**
* INTERNAL:
* Set to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord
* Set during TreeObjectBuilder initialization
*/
@Override
public int getIndex(){
return index;
}
/**
* INTERNAL
* Return true if an empty container should be set on the object if there
* is no presence of the collection in the XML document.
* @since EclipseLink 2.3.3
*/
@Override
public boolean isDefaultEmptyContainer() {
return getMapping().isDefaultEmptyContainer();
}
}