Differences between revisions 1 and 2
Revision 1 as of 2006-05-23 11:25:59
Size: 6404
Comment:
Revision 2 as of 2009-09-20 22:49:08
Size: 6404
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 99: Line 99:
[[Anchor(multiprop)]] <<Anchor(multiprop)>>

Musings on the way Open Content works in SDO

Document in progress ... state is very raw

A semi-public place to keep and share information on the way open content is spec'ed/implemented and the issues I have with it.

Disclaimer -- this info is a point in time snapshot of my understanding, it may be inaccurate. Feel free to point out my misconceptions.

Basic Stuff

A suitable schema for playing with open content ...

  • <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns:simple="http://www.example.com/open" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/open"> 
      
       <xsd:element name="openStockQuote" type="simple:OpenQuote"/>
       
       <xsd:element name="company">
         <xsd:complexType>
            <xsd:sequence>
               <xsd:element name="name" type="xsd:string"/>
            </xsd:sequence>
         </xsd:complexType>
       </xsd:element>
    
       <xsd:element name="note" type="xsd:string"/>
    
       <xsd:complexType name="OpenQuote">
           <xsd:sequence>
              <xsd:element name="symbol" type="xsd:string"/>
              <xsd:any namespace="##any"/>
           </xsd:sequence>
       </xsd:complexType>
    
    </xsd:schema>

To be able to set a value into a wildcard (<xsd:any>), you have to be able to get hold of a Property that is associated with a global element, the schema above demonstrates one way to create such a beast. In the code you can find the Property that is generated from the element "simple" with ...

  •       Property pc = XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open", "note", true);

so then you might think you should able to do ...

  •       OpenQuote oq = OpenFactory.INSTANCE.createOpenQuote();
          Property pc = XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open", "note", true);
          ((DataObject)oq).set(pc, "TBA"); 

    (Note: in the future it will be possible to do dob.set("<property>", value); to set into a wildcard (although I'm not sure at the moment how the namespace is selected in the property argument.))

But the thing is that the cardinality of association between the OpenQuote instance and the instance of the Property that's being attached by virtue of the xsd:any wildcard is defined by the global element (not the xsd:any), i.e. in this case the "note" element, and there's no way in schema to constrain the maxOccurs attribute of a global element. The upshot of that is that if you want to add a single Property value as open content, where the Property is derived from an XML Schema global element, you must wrap the value in a Collection...

  •       OpenQuote oq = OpenFactory.INSTANCE.createOpenQuote();
          oq.setSymbol("ww");
    
          DataObject doq = (DataObject)oq;
          
          boolean isElement = true;
          Property pc = XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open", "note", isElement);     
          
          List lnote = new ArrayList();
          lnote.add(new String("TBA"));
          
          doq.set(pc, lnote);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          
          XMLHelper.INSTANCE.save(doq, "http://www.example.com/open", "openStockQuote", baos);
          
          System.out.println(baos.toString());

which gives ...

  • <?xml version="1.0" encoding="ASCII"?>
    <open:openStockQuote xmlns:open="http://www.example.com/open">
      <symbol>ww</symbol>
      <open:note>TBA</open:note>
    </open:openStockQuote>

There is a way programmatically to create Property instances with maxOccurs=1 ...

  •       OpenQuote oq = OpenFactory.INSTANCE.createOpenQuote();
          Type globalType = SDOUtil.createType(TypeHelper.INSTANCE, "some-namespace", null, false);
          Property p = SDOUtil.createProperty(globalType, "newProp", TypeHelper.INSTANCE.getType("commonj.sdo", "String"));
          ((DataObject)oq).set(p, "newValue");

but if your environment constrains you to creating you metadata from XSD then currently there's no way to achieve this coding style. It has been mooted that a new SDO annotation could be added so that the generated code for the Property could ascribe the 0..1 cardinality behaviour.

So now I need to understand what semantics are placed on the maxOccurs=1 of the xsd:any -- any suggestions most welcome [kelvingoodson@gmail.com]

Open content with maxOccurs > 1

This section being reworked in the light of my newly gained understanding above

Considering the schema ...

  • <?xml version="1.0" encoding="UTF-8"?>
    <xsd:schema xmlns:simple="http://www.example.com/open" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/open"> 
      
       <xsd:element name="openStockQuote2" type="simple:OpenQuote2"/>
    
       <xsd:element name="note" type="xsd:string"/>
       <xsd:element name="count" type="xsd:int"/>
    
       <xsd:complexType name="OpenQuote2">
           <xsd:sequence>
              <xsd:element name="symbol" type="xsd:string"/>
              <xsd:any maxOccurs="unbounded" namespace="##any"/>
           </xsd:sequence>
       </xsd:complexType>
    
    </xsd:schema>

The following document ....

  • <?xml version="1.0" encoding="ASCII"?>
    <open:openStockQuote2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:open="http://www.example.com/open" xsi:type="open:OpenQuote2">
      <symbol>ww</symbol>
      <open:note>TBA</open:note>
      <open:count>1</open:count>
    </open:openStockQuote2>

is created by the following code ...

  •       OpenQuote2 oq = OpenFactory.INSTANCE.createOpenQuote2();
          oq.setSymbol("ww");
    
          DataObject doq = (DataObject)oq;
          
          boolean isElement = true;
          Property pc = XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open", "note", isElement);     
          
          List lnote = new ArrayList();
          lnote.add(new String("TBA"));
    
    
          doq.set(pc, lnote);
    
          pc = XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open", "count", isElement);     
    
          List lcount = new ArrayList();
          lcount.add(new Integer(1));
          
          doq.set(pc, lcount);
          
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          
          XMLHelper.INSTANCE.save(doq, "http://www.example.com/open", "openStockQuote2", baos);
          
          System.out.println(baos.toString());

Tuscany/TuscanyJava/SDO/ThinkingAloud/OpenContent (last edited 2009-09-20 22:49:08 by localhost)