use of org.eclipse.persistence.internal.oxm.mappings.Field in project eclipselink by eclipse-ee4j.
the class XMLCompositeDirectCollectionMappingNodeValue method marshal.
/**
* Override the method in XPathNode such that the marshaller can be set on the
* marshalRecord - this is required for XMLConverter usage.
*/
@Override
public boolean marshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, CoreAbstractSession session, NamespaceResolver namespaceResolver) {
if (xmlCompositeDirectCollectionMapping.isReadOnly()) {
return false;
}
CoreContainerPolicy cp = getContainerPolicy();
Object collection = xmlCompositeDirectCollectionMapping.getAttributeAccessor().getAttributeValueFromObject(object);
if (null == collection) {
AbstractNullPolicy wrapperNP = xmlCompositeDirectCollectionMapping.getWrapperNullPolicy();
if (wrapperNP != null && wrapperNP.getMarshalNullRepresentation() == XMLNullRepresentationType.XSI_NIL) {
marshalRecord.nilSimple(namespaceResolver);
return true;
} else {
return false;
}
}
Object iterator = cp.iteratorFor(collection);
Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();
if (null != iterator && cp.hasNext(iterator)) {
XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
marshalRecord.closeStartGroupingElements(groupingFragment);
} else {
if (xmlField.usesSingleNode() && !xmlCompositeDirectCollectionMapping.isDefaultEmptyContainer()) {
XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
marshalRecord.closeStartGroupingElements(groupingFragment);
} else {
return marshalRecord.emptyCollection(xPathFragment, namespaceResolver, xmlCompositeDirectCollectionMapping.getWrapperNullPolicy() != null);
}
}
Object objectValue;
if (xmlField.usesSingleNode()) {
StringBuilder stringValueStringBuilder = new StringBuilder();
String newValue;
QName schemaType = null;
if (xPathFragment != null && !xPathFragment.isAttribute() && !xPathFragment.nameIsText) {
marshalRecord.openStartElement(xPathFragment, namespaceResolver);
}
while (cp.hasNext(iterator)) {
objectValue = cp.next(iterator, session);
objectValue = xmlCompositeDirectCollectionMapping.convertObjectValueToDataValue(objectValue, session, marshalRecord.getMarshaller());
schemaType = xmlField.getSchemaTypeForValue(objectValue, session);
newValue = marshalRecord.getValueToWrite(schemaType, objectValue, (ConversionManager) session.getDatasourcePlatform().getConversionManager());
if (null != newValue) {
stringValueStringBuilder.append(newValue);
if (cp.hasNext(iterator)) {
stringValueStringBuilder.append(SPACE);
}
}
}
XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
if (xPathFragment != null && xPathFragment.isAttribute()) {
marshalRecord.attribute(xPathFragment, namespaceResolver, stringValueStringBuilder.toString());
marshalRecord.closeStartGroupingElements(groupingFragment);
} else {
marshalRecord.closeStartGroupingElements(groupingFragment);
if (xmlCompositeDirectCollectionMapping.isCDATA()) {
marshalRecord.cdata(stringValueStringBuilder.toString());
} else {
marshalRecord.characters(stringValueStringBuilder.toString());
if (xPathFragment != null && !xPathFragment.isAttribute() && !xPathFragment.nameIsText) {
marshalRecord.endElement(xPathFragment, namespaceResolver);
}
}
}
} else {
int valueSize = cp.sizeFor(collection);
if (marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.startCollection();
}
while (cp.hasNext(iterator)) {
objectValue = cp.next(iterator, session);
marshalSingleValue(xPathFragment, marshalRecord, object, objectValue, session, namespaceResolver, ObjectMarshalContext.getInstance());
}
if (marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.endCollection();
}
}
return true;
}
use of org.eclipse.persistence.internal.oxm.mappings.Field in project eclipselink by eclipse-ee4j.
the class XMLCompositeDirectCollectionMappingNodeValue method endElement.
@Override
public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
Field xmlField = (Field) xmlCompositeDirectCollectionMapping.getField();
Object value = unmarshalRecord.getCharacters().toString();
if (((String) value).length() == 0 && !xmlField.usesSingleNode()) {
if (xmlCompositeDirectCollectionMapping.getNullValue() != null) {
value = xmlCompositeDirectCollectionMapping.getNullValue();
}
}
unmarshalRecord.resetStringBuffer();
XPathFragment lastXPathFragment = xmlField.getLastXPathFragment();
if (!lastXPathFragment.nameIsText()) {
return;
}
if (xmlField.usesSingleNode()) {
Object collection = unmarshalRecord.getContainerInstance(this);
StringTokenizer stringTokenizer = new StringTokenizer((String) value);
while (stringTokenizer.hasMoreTokens()) {
addUnmarshalValue(unmarshalRecord, stringTokenizer.nextToken(), collection);
}
} else {
if (!unmarshalRecord.getXMLReader().isInCollection() && unmarshalRecord.isNil()) {
unmarshalRecord.setAttributeValueNull(this);
} else {
Object collection = unmarshalRecord.getContainerInstance(this);
addUnmarshalValue(unmarshalRecord, value, collection);
}
}
}
use of org.eclipse.persistence.internal.oxm.mappings.Field in project eclipselink by eclipse-ee4j.
the class XMLCompositeObjectMappingNodeValue method attribute.
@Override
public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {
unmarshalRecord.removeNullCapableValue(this);
Descriptor referenceDescriptor = (Descriptor) getMapping().getReferenceDescriptor();
ObjectBuilder treeObjectBuilder = (ObjectBuilder) referenceDescriptor.getObjectBuilder();
MappingNodeValue textMappingNodeValue = (MappingNodeValue) treeObjectBuilder.getRootXPathNode().getTextNode().getNodeValue();
Mapping textMapping = textMappingNodeValue.getMapping();
Object childObject = referenceDescriptor.getInstantiationPolicy().buildNewInstance();
if (textMapping.isAbstractDirectMapping()) {
DirectMapping xmlDirectMapping = (DirectMapping) textMappingNodeValue.getMapping();
Field xmlField = (Field) xmlDirectMapping.getField();
Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (ConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(), unmarshalRecord);
Object convertedValue = xmlDirectMapping.getAttributeValue(realValue, unmarshalRecord.getSession(), unmarshalRecord);
xmlDirectMapping.setAttributeValueInObject(childObject, convertedValue);
} else {
Object oldChildObject = unmarshalRecord.getCurrentObject();
CompositeObjectMapping nestedXMLCompositeObjectMapping = (CompositeObjectMapping) textMappingNodeValue.getMapping();
unmarshalRecord.setCurrentObject(childObject);
textMappingNodeValue.attribute(unmarshalRecord, namespaceURI, localName, value);
unmarshalRecord.setCurrentObject(oldChildObject);
}
setAttributeValue(childObject, unmarshalRecord);
}
use of org.eclipse.persistence.internal.oxm.mappings.Field in project eclipselink by eclipse-ee4j.
the class XMLCompositeObjectMappingNodeValue method startElement.
@Override
public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
try {
unmarshalRecord.removeNullCapableValue(this);
Descriptor xmlDescriptor = (Descriptor) xmlCompositeObjectMapping.getReferenceDescriptor();
if (null == xmlDescriptor) {
xmlDescriptor = findReferenceDescriptor(xPathFragment, unmarshalRecord, atts, xmlCompositeObjectMapping, xmlCompositeObjectMapping.getKeepAsElementPolicy());
if (xmlDescriptor == null) {
if (xmlCompositeObjectMapping.getField() != null) {
// try leaf element type
QName leafType = ((Field) xmlCompositeObjectMapping.getField()).getLastXPathFragment().getLeafElementType();
if (leafType != null) {
XPathFragment frag = new XPathFragment();
frag.setNamespaceAware(unmarshalRecord.isNamespaceAware());
String xpath = leafType.getLocalPart();
String uri = leafType.getNamespaceURI();
if (uri != null && uri.length() > 0) {
frag.setNamespaceURI(uri);
String prefix = ((Descriptor) xmlCompositeObjectMapping.getDescriptor()).getNonNullNamespaceResolver().resolveNamespaceURI(uri);
if (prefix != null && prefix.length() > 0) {
xpath = prefix + Constants.COLON + xpath;
}
}
frag.setXPath(xpath);
Context xmlContext = unmarshalRecord.getUnmarshaller().getContext();
xmlDescriptor = xmlContext.getDescriptorByGlobalType(frag);
}
}
}
UnmarshalKeepAsElementPolicy policy = xmlCompositeObjectMapping.getKeepAsElementPolicy();
if (null != policy && ((xmlDescriptor == null && policy.isKeepUnknownAsElement()) || policy.isKeepAllAsElement())) {
QName schemaType = unmarshalRecord.getTypeQName();
if (schemaType == null) {
schemaType = ((Field) xmlCompositeObjectMapping.getField()).getSchemaType();
unmarshalRecord.setTypeQName(schemaType);
}
if (schemaType != null) {
Class<Object> theClass = unmarshalRecord.getConversionManager().javaType(schemaType);
if (theClass == null) {
setupHandlerForKeepAsElementPolicy(unmarshalRecord, xPathFragment, atts);
return true;
}
} else {
setupHandlerForKeepAsElementPolicy(unmarshalRecord, xPathFragment, atts);
return true;
}
}
}
//
// Null Composite Objects are marshalled in 2 ways when the input XML node is empty.
// (1) as null
// - isNullRepresentedByEmptyNode = true
// (2) as empty object
// - isNullRepresentedByEmptyNode = false
// A deferred contentHandler is used to queue events until we are able to determine
// whether we are in one of empty/simple/complex state.
// Control is returned to the UnmarshalHandler after creation of (1) or (2) above is started.
// Object creation was deferred to the DeferredContentHandler
//
// Check if we need to create the DeferredContentHandler based on policy state
AbstractNullPolicy nullPolicy = xmlCompositeObjectMapping.getNullPolicy();
if (nullPolicy.isNullRepresentedByEmptyNode()) {
String qnameString = xPathFragment.getLocalName();
if (xPathFragment.getPrefix() != null) {
qnameString = xPathFragment.getPrefix() + Constants.COLON + qnameString;
}
if (null != xmlDescriptor) {
// Process null capable value
CompositeObjectMappingContentHandler aHandler = new //
CompositeObjectMappingContentHandler(unmarshalRecord, this, xmlCompositeObjectMapping, atts, xPathFragment, xmlDescriptor);
// Send control to the handler
aHandler.startElement(xPathFragment.getNamespaceURI(), xPathFragment.getLocalName(), qnameString, atts);
XMLReader xmlReader = unmarshalRecord.getXMLReader();
xmlReader.setContentHandler(aHandler);
xmlReader.setLexicalHandler(aHandler);
}
} else {
if (unmarshalRecord.getXMLReader().isNullRecord(nullPolicy, atts, unmarshalRecord) && nullPolicy.ignoreAttributesForNil()) {
xmlCompositeObjectMapping.setAttributeValueInObject(unmarshalRecord.getCurrentObject(), null);
} else {
Field xmlFld = (Field) this.xmlCompositeObjectMapping.getField();
if (xmlFld.hasLastXPathFragment()) {
unmarshalRecord.setLeafElementType(xmlFld.getLastXPathFragment().getLeafElementType());
}
processChild(xPathFragment, unmarshalRecord, atts, xmlDescriptor, xmlCompositeObjectMapping);
}
}
} catch (SAXException e) {
throw XMLMarshalException.unmarshalException(e);
}
return true;
}
use of org.eclipse.persistence.internal.oxm.mappings.Field in project eclipselink by eclipse-ee4j.
the class XMLAnyCollectionMappingNodeValue method marshalSingleValue.
@Override
public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
if (null == value) {
return false;
}
boolean wasXMLRoot = false;
XPathFragment xmlRootFragment = null;
Object originalValue = value;
Descriptor descriptor;
ObjectBuilder objectBuilder;
CoreAbstractSession childSession;
Marshaller marshaller = marshalRecord.getMarshaller();
XPathFragment rootFragment;
if (xmlAnyCollectionMapping.usesXMLRoot() && (value instanceof Root)) {
xmlRootFragment = new XPathFragment();
xmlRootFragment.setNamespaceAware(marshalRecord.isNamespaceAware());
wasXMLRoot = true;
value = ((Root) value).getObject();
if (null == value) {
setupFragment(((Root) originalValue), xmlRootFragment, marshalRecord);
marshalRecord.nilComplex(xmlRootFragment, namespaceResolver);
return true;
}
}
UnmarshalKeepAsElementPolicy keepAsElementPolicy = xmlAnyCollectionMapping.getKeepAsElementPolicy();
if (value instanceof String) {
marshalSimpleValue(xmlRootFragment, marshalRecord, originalValue, object, value, session, namespaceResolver);
} else if (null != keepAsElementPolicy && (keepAsElementPolicy.isKeepUnknownAsElement() || keepAsElementPolicy.isKeepAllAsElement()) && value instanceof org.w3c.dom.Node) {
marshalRecord.node((org.w3c.dom.Node) value, marshalRecord.getNamespaceResolver());
} else {
try {
childSession = marshaller.getContext().getSession(value);
} catch (XMLMarshalException e) {
marshalSimpleValue(xmlRootFragment, marshalRecord, originalValue, object, value, session, namespaceResolver);
return true;
}
descriptor = (Descriptor) childSession.getDescriptor(value);
pushAttributeGroup(marshalRecord, descriptor, getMapping().getAttributeName());
objectBuilder = (ObjectBuilder) descriptor.getObjectBuilder();
List extraNamespaces = objectBuilder.addExtraNamespacesToNamespaceResolver(descriptor, marshalRecord, session, true, true);
if (wasXMLRoot) {
setupFragment(((Root) originalValue), xmlRootFragment, marshalRecord);
}
/*
* B5112171: 25 Apr 2006
* During marshalling - XML AnyObject and AnyCollection
* mappings throw a NullPointerException when the
* "document root element" on child object descriptors are not
* all defined. These nodes will be ignored with a warning.
*/
String defaultRootElementString = descriptor.getDefaultRootElement();
if (!wasXMLRoot && (defaultRootElementString == null)) {
throw XMLMarshalException.defaultRootElementNotSpecified(descriptor);
} else {
marshalRecord.beforeContainmentMarshal(value);
if (xmlRootFragment != null) {
rootFragment = xmlRootFragment;
} else {
rootFragment = new XPathFragment(defaultRootElementString);
// resolve URI
if (rootFragment.getNamespaceURI() == null) {
String uri = descriptor.getNonNullNamespaceResolver().resolveNamespacePrefix(rootFragment.getPrefix());
rootFragment.setNamespaceURI(uri);
}
}
if (!wasXMLRoot) {
marshalRecord.setLeafElementType(descriptor.getDefaultRootElementType());
}
getXPathNode().startElement(marshalRecord, rootFragment, object, childSession, marshalRecord.getNamespaceResolver(), objectBuilder, value);
writeExtraNamespaces(extraNamespaces, marshalRecord, session);
pushAttributeGroup(marshalRecord, descriptor, rootFragment.getLocalName());
marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, descriptor, (Field) xmlAnyCollectionMapping.getField(), originalValue, value, wasXMLRoot, false);
objectBuilder.buildRow(marshalRecord, value, session, marshaller, null);
marshalRecord.afterContainmentMarshal(object, value);
marshalRecord.endElement(rootFragment, namespaceResolver);
marshalRecord.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session);
marshalRecord.popAttributeGroup();
}
marshalRecord.popAttributeGroup();
}
return true;
}
Aggregations