I am having problems creating data objects with the SDO API to match data 
objects created by loading an XML document.

The problems occur for elements that have maxOccurs greater than one.  The 
SDO implementation maps each such attribute to a List-valued property.
However, the Lists that are used behave differently.

Is there a way I can use the SDO API to dynamically create objects with 
the same properties as those created by loading an XML document?

For example, the test case shown at the end of this note produces this 
output:
-------------------------------------------------------------
for 'aString' property:
  XML & reference type value was: [This is a repeated string., This is a 
repeated string.]
  API & dynamic type   value was: [This is a repeated string.]
  API & reference type value was: [This is a repeated string.]

for 'aBoolean' property:
  XML & reference type value was: [true, false, true, true, false]
  API & dynamic type   value was: [true, false]
  API & reference type value was: [true, false]

for 'aFloat' property:
  XML & reference type value was: [0.0, 12.5, 0.0]
  API & dynamic type   value was: [0.0, 12.5]
  API & reference type value was: [0.0, 12.5]

object from XML & reference type sequence has size=21
 
 
  This is a repeated string.
 
 
  This is a repeated string.
 
 
  true
 
 
  false
 
 
  true
 
 
  true
 
 
  false
 
 
  0.0
 
 
  12.5
 
 
  0.0
 

object from API & dynamic type   sequence has size=5
  This is a repeated string.
  true
  false
  0.0
  12.5
object from API & reference type sequence has size=10
  This is a repeated string.
  This is a repeated string.
  true
  false
  true
  true
  false
  0.0
  12.5
  0.0

-------------------------------------------------------------

This is the test case that can be put in the 
Tuscany\java\sdo\impl\src\test\java\org\apache\tuscany\sdo\test directory 
and run as a JUnit test:
-------------------------------------------------------------
package org.apache.tuscany.sdo.test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;

import junit.framework.TestCase;

import org.apache.tuscany.sdo.util.SDOUtil;

import commonj.sdo.DataObject;
import commonj.sdo.Sequence;
import commonj.sdo.Type;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XMLDocument;
import commonj.sdo.helper.XMLHelper;
import commonj.sdo.helper.XSDHelper;

/**
 * Tests dynamic creation of SDO types from specifications in DataObject
 */
public class DynamicTypesFromDataObjectSimpleTestCase extends TestCase {
    private final String COMMONJ_SDO = "commonj.sdo";

    private final String DYNAMIC_ROOT_TYPE_0 = "TestType0";

    private final String DYNAMIC_TYPES_SCHEMA_STRING =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
        "<xsd:schema\n"+
        " 
targetNamespace=\"http://www.example.com/dynamicTypesFromSchemaSimple\"\n"+
        " 
xmlns:dtfs=\"http://www.example.com/dynamicTypesFromSchemaSimple\"\n"+
        "    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\";>\n"+
        "    \n"+
        "  <xsd:complexType name=\"TestType0\" mixed=\"true\">\n"+
        "    <xsd:sequence>\n"+
        "      <xsd:element name=\"aString\" minOccurs=\"0\" 
maxOccurs=\"unbounded\" type=\"xsd:string\"/>\n"+
        "      <xsd:element name=\"aBoolean\" minOccurs=\"0\" 
maxOccurs=\"unbounded\" type=\"xsd:boolean\"/>\n"+
        "      <xsd:element name=\"aFloat\" minOccurs=\"0\" 
maxOccurs=\"unbounded\" type=\"xsd:float\"/>\n"+
        "    </xsd:sequence>\n"+
        "  </xsd:complexType>\n"+
        "    \n"+
        "  <xsd:element name=\"testElement0\" 
type=\"dtfs:TestType0\"/>\n"+
        "    \n"+ 
        "</xsd:schema>\n";

    private final String DYNAMIC_TYPES_URI = 
"http://www.example.com/dynamicTypesFromSchemaSimple";;

    private final String TEST_XML_DOC_0_STRING = 
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
        "<dtfs:testElement0 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"+ 
        " 
xmlns:dtfs=\"http://www.example.com/dynamicTypesFromSchemaSimple\";>\n"+
        "  <aString>This is a repeated string.</aString>\n"+
        "  <aString>This is a repeated string.</aString>\n"+
        "  <aBoolean>true</aBoolean>\n"+
        "  <aBoolean>false</aBoolean>\n"+
        "  <aBoolean>true</aBoolean>\n"+
        "  <aBoolean>1</aBoolean>\n"+
        "  <aBoolean>0</aBoolean>\n"+
        "  <aFloat>0</aFloat>\n"+
        "  <aFloat>12.5</aFloat>\n"+
        "  <aFloat>0</aFloat>\n"+
        "</dtfs:testElement0>\n";

    protected void setUp() throws Exception {
        super.setUp();
    }

    private void specifyProperty(DataObject containingTypeDO, String 
nameString, Type typ, boolean isMany) {
        DataObject subordinateProperty = 
containingTypeDO.createDataObject("property");
        subordinateProperty.set("name", nameString);
        subordinateProperty.set("type", typ);
        subordinateProperty.setBoolean("many", isMany);
    }

    /**
     * test #0 of Data Object primitive datatypes
     */
    public void testDynamicTypesGroup0DO() throws IOException {
        HelperContext hcDO = SDOUtil.createHelperContext();

        TypeHelper thDO = hcDO.getTypeHelper();
        DataFactory dfDO = hcDO.getDataFactory();

        // create a container object type
        DataObject containerTypeDO = dfDO.create("commonj.sdo", "Type");
        containerTypeDO.set("uri", DYNAMIC_TYPES_URI);
        containerTypeDO.set("name", DYNAMIC_ROOT_TYPE_0);
        containerTypeDO.set("sequenced", Boolean.TRUE);

        specifyProperty(containerTypeDO, "aString", 
thDO.getType(COMMONJ_SDO, "String"), true);
        specifyProperty(containerTypeDO, "aBoolean", 
thDO.getType(COMMONJ_SDO, "Boolean"), true);
        specifyProperty(containerTypeDO, "aFloat", 
thDO.getType(COMMONJ_SDO, "Float"), true);

        Type containerType = thDO.define(containerTypeDO);
        assertNotNull(containerType);

        DataObject doFromApiAndDynTyp = dfDO.create(containerType);
        assertNotNull(doFromApiAndDynTyp);
        doFromApiAndDynTyp.getList("aString").add("This is a repeated 
string.");
        doFromApiAndDynTyp.getList("aString").add("This is a repeated 
string.");
        doFromApiAndDynTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndDynTyp.getList("aBoolean").add(new Boolean(false));
        doFromApiAndDynTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndDynTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndDynTyp.getList("aBoolean").add(new Boolean(false));
        doFromApiAndDynTyp.getList("aFloat").add(new Float(0));
        doFromApiAndDynTyp.getList("aFloat").add(new Float(12.5));
        doFromApiAndDynTyp.getList("aFloat").add(new Float(0));

        Type rootType = thDO.getType(DYNAMIC_TYPES_URI, 
DYNAMIC_ROOT_TYPE_0);
        assertNotNull(rootType);
        assertSame(containerType, rootType);

        // now load xml to get a reference data object using schema
        HelperContext hcRef = SDOUtil.createHelperContext();
        XSDHelper xsdHelper = hcRef.getXSDHelper();
        List typeList = xsdHelper.define(DYNAMIC_TYPES_SCHEMA_STRING);
        assertNotNull(typeList);
        TypeHelper thRef = hcRef.getTypeHelper();
        Type rootTypeRef = thRef.getType(DYNAMIC_TYPES_URI, 
DYNAMIC_ROOT_TYPE_0);

        assertNotNull(rootTypeRef);

        XMLHelper xhRef = hcRef.getXMLHelper();
        //XMLDocument docRef = 
xhRef.load(getClass().getResourceAsStream(TEST_XML_DOC_0));
        XMLDocument docRef = xhRef.load(TEST_XML_DOC_0_STRING);
        DataObject doFromXmlAndRefTyp = docRef.getRootObject();

        assertNotNull(doFromXmlAndRefTyp);
 
        // create a data object using dynamic API from reference type
        DataFactory dfRef = hcRef.getDataFactory();
        DataObject doFromApiAndRefTyp = dfRef.create(rootTypeRef);
        assertNotNull(doFromApiAndRefTyp);
        doFromApiAndRefTyp.getList("aString").add("This is a repeated 
string.");
        doFromApiAndRefTyp.getList("aString").add("This is a repeated 
string.");
        doFromApiAndRefTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndRefTyp.getList("aBoolean").add(new Boolean(false));
        doFromApiAndRefTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndRefTyp.getList("aBoolean").add(new Boolean(true));
        doFromApiAndRefTyp.getList("aBoolean").add(new Boolean(false));
        doFromApiAndRefTyp.getList("aFloat").add(new Float(0));
        doFromApiAndRefTyp.getList("aFloat").add(new Float(12.5));
        doFromApiAndRefTyp.getList("aFloat").add(new Float(0));


        //PrintStream ps = new PrintStream(new 
FileOutputStream("C:\\temp\\testDynamicTypesSimple0cmp.txt")); // qqq
        PrintStream ps = System.out;
        printPropertiesForRefAndTest(ps, "aString",  doFromXmlAndRefTyp, 
doFromApiAndDynTyp, doFromApiAndRefTyp);
        printPropertiesForRefAndTest(ps, "aBoolean", doFromXmlAndRefTyp, 
doFromApiAndDynTyp, doFromApiAndRefTyp);
        printPropertiesForRefAndTest(ps, "aFloat",   doFromXmlAndRefTyp, 
doFromApiAndDynTyp, doFromApiAndRefTyp);
        printSequence(ps, "object from XML & reference type", 
doFromXmlAndRefTyp.getSequence());
        printSequence(ps, "object from API & dynamic type  ", 
doFromApiAndDynTyp.getSequence());
        printSequence(ps, "object from API & reference type", 
doFromApiAndRefTyp.getSequence());
        //ps.close();
    }
 
    private void printPropertiesForRefAndTest(PrintStream ps, String 
propName, DataObject xmlAndRefTypDO, DataObject apiAndDynTypDO, DataObject 
apiAndRefTypDO) {
        Object refProperty = xmlAndRefTypDO.get(propName);
        Object tstProperty = apiAndDynTypDO.get(propName);
        ps.println("for '"+propName+"' property:");
        ps.println("  XML & reference type value was: "+refProperty);
        ps.println("  API & dynamic type   value was: "+tstProperty);
        ps.println("  API & reference type value was: "+tstProperty+"\n");
    }

    private void printSequence(PrintStream ps, String header, Sequence 
sequence) {
        if (sequence == null) {
            ps.println(header + " sequence is null");
        } else {
            ps.println(header + " sequence has size=" + sequence.size());
            for (int i = 0; i < sequence.size(); i++) {
                ps.println("  " + sequence.getValue(i));
            }
        }
    }
}
-------------------------------------------------------------

Regards,
Paul Golick
e-mail:  [EMAIL PROTECTED]

Reply via email to