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;

     }

 }