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, 2018 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();
}
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);
}
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);
}
}
public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
return this.choiceElementNodeValue.startElement(xPathFragment, unmarshalRecord, atts);
}
public void setXPathNode(XPathNode xPathNode) {
super.setXPathNode(xPathNode);
this.choiceElementNodeValue.setXPathNode(xPathNode);
}
public Object getContainerInstance() {
return getContainerPolicy().containerInstance();
}
public void setContainerInstance(Object object, Object containerInstance) {
xmlChoiceCollectionMapping.setAttributeValueInObject(object, containerInstance);
}
public CoreContainerPolicy getContainerPolicy() {
return xmlChoiceCollectionMapping.getContainerPolicy();
}
public boolean isContainerValue() {
return true;
}
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;
}
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;
}
public boolean isUnmarshalNodeValue() {
return true;
}
public boolean isWrapperAllowedAsCollectionName() {
return false;
}
public boolean isMarshalNodeValue() {
return false;
}
public ChoiceCollectionMapping getMapping() {
return xmlChoiceCollectionMapping;
}
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.
*
*/
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.
*/
public boolean isMixedContentNodeValue() {
return this.isMixedNodeValue;
}
/**
* INTERNAL:
* Used to track the index of the corresponding containerInstance in the containerInstances Object[] on UnmarshalRecord
*/
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
*/
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
*/
public boolean isDefaultEmptyContainer() {
return getMapping().isDefaultEmptyContainer();
}
}