Fix for SDO bug 430104 Reviewed by Blaise Doughan
diff --git a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/record/UnmarshalRecordImpl.java b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/record/UnmarshalRecordImpl.java index f312b5d..c48cd0c 100644 --- a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/record/UnmarshalRecordImpl.java +++ b/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm/record/UnmarshalRecordImpl.java
@@ -1034,20 +1034,33 @@ } } else { XPathNode textNode = xPathNode.getTextNode(); - if (null != textNode && textNode.isWhitespaceAware() && getStringBuffer().length() == 0) { + + if (null != textNode && getStringBuffer().length() == 0) { NodeValue textNodeUnmarshalNodeValue = textNode.getUnmarshalNodeValue(); - if (textNodeUnmarshalNodeValue.isMappingNodeValue()) { - Mapping mapping = ((MappingNodeValue)textNodeUnmarshalNodeValue).getMapping(); - if(mapping.isAbstractDirectMapping() && isXsiNil) { - Object nullValue = ((DirectMapping)mapping).getNullValue(); - if(!(Constants.EMPTY_STRING.equals(nullValue))) { - setAttributeValue(null, mapping); - this.removeNullCapableValue((NullCapableValue)textNodeUnmarshalNodeValue); + if(textNode.isWhitespaceAware()){ + if (textNodeUnmarshalNodeValue.isMappingNodeValue()) { + Mapping mapping = ((MappingNodeValue)textNodeUnmarshalNodeValue).getMapping(); + if(mapping.isAbstractDirectMapping() && isXsiNil) { + Object nullValue = ((DirectMapping)mapping).getNullValue(); + if(!(Constants.EMPTY_STRING.equals(nullValue))) { + setAttributeValue(null, mapping); + this.removeNullCapableValue((NullCapableValue)textNodeUnmarshalNodeValue); + } + } else { + textNodeUnmarshalNodeValue.endElement(xPathFragment, this); + } + isXsiNil = false; + } + }else{ + + //This means empty tag + if(textNodeUnmarshalNodeValue.isMappingNodeValue()) { + Mapping mapping = ((MappingNodeValue)textNodeUnmarshalNodeValue).getMapping(); + if(mapping.isAbstractDirectMapping() && !isXsiNil && ((DirectMapping)mapping).getNullPolicy().isNullRepresentedByXsiNil()){ + removeNullCapableValue((NullCapableValue)textNodeUnmarshalNodeValue); } - } else { - textNodeUnmarshalNodeValue.endElement(xPathFragment, this); } - isXsiNil = false; + } } }
diff --git a/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xml b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xml new file mode 100644 index 0000000..4fce510 --- /dev/null +++ b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xml
@@ -0,0 +1,10 @@ +<ns0:root xmlns:ns0="namespace1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <ns0:nillableEmptyString></ns0:nillableEmptyString> + <ns0:nillableNilString xsi:nil="true"/> + <ns0:nonnillableEmptyString></ns0:nonnillableEmptyString> + <ns0:nonnillableNilString xsi:nil="true"/> + <ns0:nillableEmptyDecimal></ns0:nillableEmptyDecimal> + <ns0:nillableNilDecimal xsi:nil="true"/> + <ns0:nonnillableEmptyDecimal></ns0:nonnillableEmptyDecimal> + <ns0:nonnillableNilDecimal xsi:nil="true"/> +</ns0:root>
diff --git a/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xsd b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xsd new file mode 100644 index 0000000..5b67900 --- /dev/null +++ b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xsd
@@ -0,0 +1,23 @@ +<?xml version = '1.0' encoding = 'UTF-8'?> +<xsd:schema targetNamespace="namespace1" + xmlns:ns0="namespace1" + xmlns:sdo="commonj.sdo" xmlns:sdoJava="commonj.sdo/java" + elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:import namespace="commonj.sdo" schemaLocation="datagraph.xsd"/> + <xsd:element name="root" type="ns0:RootType"/> + <xsd:complexType name="RootType"> + <xsd:sequence> + <xsd:element name="nillableEmptyString" type="xsd:string" nillable="true"/> + <xsd:element name="nillableNilString" type="xsd:string" nillable="true"/> + <xsd:element name="nonnillableEmptyString" type="xsd:string" nillable="false"/> + <xsd:element name="nonnillableNilString" type="xsd:string" nillable="false"/> + + <xsd:element name="nillableEmptyDecimal" type="xsd:decimal" nillable="true"/> + <xsd:element name="nillableNilDecimal" type="xsd:decimal" nillable="true"/> + <xsd:element name="nonnillableEmptyDecimal" type="xsd:decimal" nillable="false"/> + <xsd:element name="nonnillableNilDecimal" type="xsd:decimal" nillable="false"/> + + </xsd:sequence> + </xsd:complexType> + +</xsd:schema> \ No newline at end of file
diff --git a/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/output.xml b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/output.xml new file mode 100644 index 0000000..23fc5fe --- /dev/null +++ b/sdo/eclipselink.sdo.test/resource/org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/output.xml
@@ -0,0 +1,8 @@ +<ns0:root xmlns:ns0="namespace1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <ns0:nillableNilString xsi:nil="true"/> + <ns0:nonnillableEmptyString></ns0:nonnillableEmptyString> + <ns0:nonnillableNilString/> + <ns0:nillableNilDecimal xsi:nil="true"/> + <ns0:nonnillableEmptyDecimal></ns0:nonnillableEmptyDecimal> + <ns0:nonnillableNilDecimal/> +</ns0:root>
diff --git a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/LoadAndSaveEmptyElementTestCases.java b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/LoadAndSaveEmptyElementTestCases.java new file mode 100644 index 0000000..07a1194 --- /dev/null +++ b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/LoadAndSaveEmptyElementTestCases.java
@@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 1998, 2012 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: + * Oracle - initial API and implementation from Oracle TopLink + ******************************************************************************/ +package org.eclipse.persistence.testing.sdo.helper.xmlhelper.loadandsave; + +import java.util.ArrayList; +import java.util.List; + +import commonj.sdo.DataObject; +import commonj.sdo.Type; +import commonj.sdo.helper.XMLDocument; +import junit.textui.TestRunner; +import org.eclipse.persistence.sdo.SDOConstants; +import org.eclipse.persistence.sdo.SDOType; + +public class LoadAndSaveEmptyElementTestCases extends LoadAndSaveTestCases { + public LoadAndSaveEmptyElementTestCases(String name) { + super(name); + } + + protected String getSchemaName() { + return "./org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xsd"; + } + + protected String getControlFileName() { + return ("./org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xml"); + } + + protected String getControlWriteFileName() { + return ("./org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/output.xml"); + } + + protected String getNoSchemaControlWriteFileName() { + return ("./org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/output.xml"); + } + + protected String getNoSchemaControlFileName() { + return ("./org/eclipse/persistence/testing/sdo/helper/xmlhelper/empty/input.xml"); + } + + protected String getControlRootURI() { + return "namespace1"; + } + + protected String getControlRootName() { + return "root"; + } + + protected String getRootInterfaceName() { + return "RootType"; + } + + protected void verifyAfterLoad (XMLDocument document) { + super.verifyAfterLoad(document); + DataObject rootDO = document.getRootObject(); + assertNull(rootDO.get("nillableEmptyString")); + assertFalse(rootDO.isSet("nillableEmptyString")); + + assertNull(rootDO.get("nillableNilString")); + assertTrue(rootDO.isSet("nillableNilString")); + + assertNull(rootDO.get("nonnillableEmptyString")); + assertTrue(rootDO.isSet("nonnillableEmptyString")); + + assertNull(rootDO.get("nonnillableNilString")); + assertTrue(rootDO.isSet("nonnillableNilString")); + + assertNull(rootDO.get("nillableEmptyDecimal")); + assertFalse(rootDO.isSet("nillableEmptyDecimal")); + + assertNull(rootDO.get("nillableNilDecimal")); + assertTrue(rootDO.isSet("nillableNilDecimal")); + + assertNull(rootDO.get("nonnillableEmptyDecimal")); + assertTrue(rootDO.isSet("nonnillableEmptyDecimal")); + + assertNull(rootDO.get("nonnillableNilDecimal")); + assertTrue(rootDO.isSet("nonnillableNilDecimal")); + } + + // Override package generation based on the JAXB 2.0 algorithm in SDOUtil.java + protected List<String> getPackages() { + List<String> packages = new ArrayList<String>(); + packages.add("namespace1"); + return packages; + } + + public void registerTypes() { + Type stringType = typeHelper.getType("commonj.sdo", "String"); + Type decimalType = typeHelper.getType("commonj.sdo", "Decimal"); + SDOType propertyType = (SDOType) typeHelper.getType(SDOConstants.SDO_URL, SDOConstants.PROPERTY); + + // create a new Type for Customers + DataObject rootType = dataFactory.create("commonj.sdo", "Type"); + rootType.set("uri", getControlRootURI()); + rootType.set("name", "rootType"); + + DataObject prop = addProperty(rootType, "nillableEmptyString", stringType, false, false, true); + prop.setBoolean("nullable", true); + + prop = addProperty(rootType, "nillableNilString", stringType, false, false, true); + prop.setBoolean("nullable", true); + + addProperty(rootType, "nonnillableEmptyString", stringType, false, false, true); + + addProperty(rootType, "nonnillableNilString", stringType, false, false, true); + + prop = addProperty(rootType, "nillableEmptyDecimal", decimalType, false, false, true); + prop.setBoolean("nullable", true); + + prop = addProperty(rootType, "nillableNilDecimal", decimalType, false, false, true); + prop.setBoolean("nullable", true); + + addProperty(rootType, "nonnillableEmptyDecimal", decimalType, false, false, true); + + addProperty(rootType, "nonnillableNilDecimal", decimalType, false, false, true); + + + // now define the Customer type so that customers can be made + Type rootSDOType = typeHelper.define(rootType); + + DataObject propDO = dataFactory.create(propertyType); + propDO.set("name", getControlRootName()); + propDO.set("type", rootSDOType); + typeHelper.defineOpenContentProperty(getControlRootURI(), propDO); + } + + public static void main(String[] args) { + String[] arguments = { "-c", "org.eclipse.persistence.testing.sdo.helper.xmlhelper.loadandsave.LoadAndSaveSimpleElementTestCases" }; + TestRunner.main(arguments); + } +}
diff --git a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/SDOXMLHelperLoadAndSaveTestSuite.java b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/SDOXMLHelperLoadAndSaveTestSuite.java index e36f6da..0e4f203 100644 --- a/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/SDOXMLHelperLoadAndSaveTestSuite.java +++ b/sdo/eclipselink.sdo.test/src/org/eclipse/persistence/testing/sdo/helper/xmlhelper/loadandsave/SDOXMLHelperLoadAndSaveTestSuite.java
@@ -51,6 +51,7 @@ suite.addTest(new TestSuite(LoadAndSaveExceptionBug325353TestCases.class)); suite.addTestSuite(ListEmptyElementTestCases.class); suite.addTestSuite(ListEmptyElementNullableTestCases.class); + suite.addTestSuite(LoadAndSaveEmptyElementTestCases.class); return suite; } }