All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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.oxm.mappings.nullpolicy;

import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.NullCapableValue;
import org.eclipse.persistence.internal.oxm.XPathEngine;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathNode;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;

/**
 * PUBLIC: Description: This node null policy allows for the handling of
 * various representations of null in XML documents.
*

* Null policies have 2 concrete implementations: *

    *
  • NullPolicy (default implementation)
  • *
  • IsSetNullPolicy (keyed off isSet() state of the node)
  • *
* * * * * * * * * * * * * * * * * * *
Unmarshal FlagDescription
isSetPerformedForAbsentNode This umarshal flag represents whether a set is done for * absent nodes only.
isNullRepresentedByEmptyNode If this unmarshal flag is false for empty nodes we set an * empty Object for composite mappings, otherwise we set to null.
isNullRepresentedByXsiNil If this unmarshal flag is false for xsi:nil nodes we ignore * the xsi:nil attribute and treat as an empty node.
* Otherwise we set to null.
* * * * * * * * * * * * * * * * * * *
Marshal EnumXMLNullRepresentationType Description
XSI_NIL Nillable: Write out an xsi:nil="true" attribute.
ABSENT_NODE(default) Optional: Write out no node.
EMPTY_NODE Required: Write out an empty {@literal } or node="" node.
 Usage:
* * @see org.eclipse.persistence.internal.oxm.NullCapableValue * @since Oracle TopLink 11g Release 1 (11.1.1) */ public abstract class AbstractNullPolicy { protected static final String TRUE = "true"; protected static final String COLON_W_SCHEMA_NIL_ATTRIBUTE = Constants.COLON + Constants.SCHEMA_NIL_ATTRIBUTE; protected static final String XSI_NIL_ATTRIBUTE = Constants.SCHEMA_INSTANCE_PREFIX + COLON_W_SCHEMA_NIL_ATTRIBUTE; /** * This state flag determines how we unmarshal absent nodes. true = * (default) Perform a set(null). false = Do not perform a set(null). */ protected boolean isSetPerformedForAbsentNode = true; /** * This state flag determines how we unmarshal empty nodes. true = Perform a * set(null) or primitive type equivalent. false = (default) Perform a * set(new Object()). */ protected boolean isNullRepresentedByEmptyNode = false; /** * This state flag determines how we unmarshal xsi:nil nodes. A set is * performed in both cases. true = Perform a set(null) or primitive type * equivalent.. false = (default) do nothing and treat as an empty node. */ protected boolean isNullRepresentedByXsiNil = false; /** * This state flag determines how we unmarshal xsi:nil nodes when there * are other attributes (other than xsi:nil) present. If false, we ignore * any attributes and treat the element as nil. If true, we inspect if * some attributes are present and if yes, we process them. */ protected boolean ignoreAttributesForNil = true; /** * This enum instance determines what to write out during a marshal * operation. We are defaulting to ABSENT_NODE */ protected XMLNullRepresentationType marshalNullRepresentation = XMLNullRepresentationType.ABSENT_NODE; /** * Get the enum that determines what XML to write when a null value is encountered. */ public XMLNullRepresentationType getMarshalNullRepresentation() { return marshalNullRepresentation; } /** * Set the enum that determines what XML to write when a null value is encountered. */ public void setMarshalNullRepresentation(XMLNullRepresentationType anEnumInstance) { marshalNullRepresentation = anEnumInstance; } /** * INTERNAL: * When using the SAX or DOM Platform, this method is responsible for * marshalling null values for the XML Direct Mapping. * * @param xPathFragment * @param marshalRecord * @param object * @param session * @param namespaceResolver * @return true if this method caused any nodes to be marshaled, else false. */ public boolean directMarshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, // Object object, CoreSession session, NamespaceResolver namespaceResolver) { // Handle attributes - XSI_NIL, ABSENT_NODE have the same behavior if (xPathFragment.isAttribute()) { // Write out an empty attribute if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { marshalRecord.emptyAttribute(xPathFragment, namespaceResolver); return true; } else { // XSI_NIL attributes are invalid - and are ignored // ABSENT_NODE - Write out nothing return false; } } else { // Nillable: write out xsi:nil="true" attribute in empty element if (marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { marshalRecord.nilSimple(namespaceResolver); return true; } else { // EMPTY_NODE - Write out empty element if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { marshalRecord.emptySimple(namespaceResolver); return true; } else { // ABSENT_NODE - Write out nothing return false; } } } } /** * INTERNAL: When using the SAX Platform, this method is responsible for * marshalling null values for the XML Composite Object Mapping. * * @param xPathFragment * @param marshalRecord * @param object * @param session * @param namespaceResolver * @return true if this method caused any nodes to be marshaled, else false. */ public boolean compositeObjectMarshal(XPathFragment xPathFragment, MarshalRecord marshalRecord, // Object object, CoreSession session, NamespaceResolver namespaceResolver) { if (marshalNullRepresentation == XMLNullRepresentationType.ABSENT_NODE){ return false; } // Nillable else if (marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { marshalRecord.nilComplex(xPathFragment, namespaceResolver); return true; } else if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { // Optional and Required // This call is really only valid when using DOM - TBD false // Write out empty element - we need to differentiate between // object=null and object=new Object() with null fields and 0-numeric primitive values // EMPTY_NODE - Write out empty element - Required marshalRecord.emptyComplex(xPathFragment, namespaceResolver); return true; } return false; } /** * INTERNAL: When using the DOM Platform, this method is responsible for * marshalling null values for the XML Composite Object Mapping. * * @param record * @param object * @param field * @return true if this method caused any objects to be marshaled, else false. */ public boolean compositeObjectMarshal(AbstractMarshalRecord record, Object object, Field field, CoreAbstractSession session) { if (marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { record.put(field, XMLRecord.NIL); return true; } else { // EMPTY_NODE - Write out empty element - Required if (marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { Node element = XPathEngine.getInstance().createUnownedElement(record.getDOM(), field); record.put(field, element); return true; } else { // ABSENT_NODE - Write out nothing - Optional return false; } } } /** * INTERNAL: When using the SAX or DOM Platform during unmarshal operations. * Use the attributes to determine if the element represents a null value. * * @param attributes * @return true if based on the attributes the corresponding element * represents a null value, else false. */ public boolean valueIsNull(Attributes attributes) { // Nillable if (isNullRepresentedByXsiNil()) { // Ignore any other attributes that are in addition to xsi:nil if(null == attributes) { return false; } return attributes.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE) != null; } else { // EMPTY_NODE - Required if (isNullRepresentedByEmptyNode() && (null == attributes || attributes.getLength() == 0)) { return true; } } return false; } /** * INTERNAL: When using the DOM Platform during unmarshal operations. * Use the element to determine if the element represents a null value. * * @param element * @return true if based on the element it represents a null value, else false. */ public boolean valueIsNull(Element element) { // Check Nillable: Ignore any other attributes that are in addition to xsi:nil if (null == element) { return true; } else { if (isNullRepresentedByXsiNil() && element.hasAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE)) { return true; } else { // EMPTY_NODE - Required // Verify no attributes and no child nodes on the DOM element if (isNullRepresentedByEmptyNode() && !element.hasAttributes() && (element.getChildNodes().getLength() == 0)) { return true; } else { return false; } } } } /** * INTERNAL: When using the SAX Platform this allows a NodeValue to be * registered to receive events from the TreeObjectBuilder. * @param xPathNode * @param nullCapableValue */ public abstract void xPathNode(XPathNode xPathNode, NullCapableValue nullCapableValue); /** * @return the isSetPerformedForAbsentNode flag */ public boolean getIsSetPerformedForAbsentNode() { return isSetPerformedForAbsentNode; } /** * * @return */ public boolean isNullRepresentedByEmptyNode() { return isNullRepresentedByEmptyNode; } /** * * @param bIsNullRepresentedByEmptyNode */ public void setNullRepresentedByEmptyNode(boolean bIsNullRepresentedByEmptyNode) { isNullRepresentedByEmptyNode = bIsNullRepresentedByEmptyNode; } /** * * @return */ public boolean isNullRepresentedByXsiNil() { return isNullRepresentedByXsiNil; } /** * * @param bIsNullRepresentedByXsiNil */ public void setNullRepresentedByXsiNil(boolean bIsNullRepresentedByXsiNil) { isNullRepresentedByXsiNil = bIsNullRepresentedByXsiNil; } /** * * @return */ public boolean ignoreAttributesForNil() { return ignoreAttributesForNil; } /** * * @param ignoreAttributesForNil */ public void setIgnoreAttributesForNil(boolean ignoreAttributesForNil) { this.ignoreAttributesForNil = ignoreAttributesForNil; } /** * INTERNAL: * Private function to process or create an entry in the NamespaceResolver for the xsi prefix. * @param namespaceResolver * @return xsi prefix */ protected String processNamespaceResolverForXSIPrefix(NamespaceResolver namespaceResolver, MarshalRecord marshalRecord) { String xsiPrefix; if (null == namespaceResolver) { // add new xsi entry into the properties map xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX; marshalRecord.namespaceDeclaration(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); } else { // find an existing xsi entry in the map xsiPrefix = namespaceResolver.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); if (null == xsiPrefix) { xsiPrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX); marshalRecord.namespaceDeclaration(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); } } return xsiPrefix; } /** * INTERNAL */ public void directMarshal(Field field, AbstractMarshalRecord record, Object object) { Object fieldValue = null; if(marshalNullRepresentation == XMLNullRepresentationType.EMPTY_NODE) { fieldValue = Constants.EMPTY_STRING; } else { if(!field.getLastXPathFragment().isAttribute()) { if(marshalNullRepresentation == XMLNullRepresentationType.XSI_NIL) { fieldValue = XMLRecord.NIL; } } } record.put(field, fieldValue); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy