You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by kelvin goodson <ke...@gmail.com> on 2006/05/18 11:27:37 UTC

1) Hello and 2) Open Content issue

Hello,
  given the recent set of people announcing themselves as working on
Tuscany,  I guess I should say hello properly.  I'm Kelvin Goodson, and I'm
working on Java SDO.

To that end I've recently been doing some digging with SDO Java open content
programs, and I'm not sure what the behaviour should be at times.  I've been
jotting my musings at
http://wiki.apache.org/ws/Tuscany/Java/SDO/ThinkingAloud/OpenContent.

I'd like to clarify the behaviour of the Java code with respect to the
maxOccurs values associated with global elements and wildcards (I've opened
Jira http://issues.apache.org/jira/browse/TUSCANY-396 for this,  but the
discussion here goes beyond that issue.)

Here's my starting 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="openStockQuote" type="simple:OpenQuote"/>
   <xsd:element name="note" type="xsd:string"/>

   <xsd:complexType name="OpenQuote">
       <xsd:sequence>
          <xsd:element name="symbol" type="xsd:string"/>
          <xsd:any maxOccurs="1" 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 p =
XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/simpleGlobalElem",
"simple", true);

so then you should I think be 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");

but there's a problem with the code at the moment I think (see above
referenced Jira)

so at the moment you have to do something like this ...

      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);

      // value must be added as a list
      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>

 Open content with max occurs > 1

The behaviour of the code here may throw some light on why the single valued
case is as it is, and perhaps that I have misunderstood that case. Here's
where my experiments have led so far

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);

      Property pc2 =
XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
"count", isElement);

      List lcount = new ArrayList();
      lcount.add(new Integer(1));

      doq.set(pc2, lcount);

      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      XMLHelper.INSTANCE.save(doq, "http://www.example.com/open",
"openStockQuote2", baos);

      System.out.println(baos.toString());

Which kind of surprised me a bit, since I had expected the second set() call
to overwrite the first, but now it kind of makes sense. So that makes me
reconsider the semantics I had placed upon the single cardinality case
above, and begs the question whether the above referenced JIRA I raised was
in error.

OK, so if my theory is correct, that the cardinality of the global elements
(unspecified) causes this requirement for adding a value wrapped in a List,
then adding .....

   <xsd:element name="oneNote" type="xsd:string" maxOccurs="1" />

to the schema should allow me to do ...

      Property pOneNote =
XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
"oneNote", true);
      doq.set(pOneNote, "this is it!");

on a DataObject of Type OpenQuote

but it doesn't! it still fails as described above, when expecting the
supplied argument to be a List, even though both the xsd:any and the global
element have maxOccurs = 1 on them! So either I still misunderstand, or
there's something wrong here.

Re: 1) Hello and 2) Open Content issue

Posted by Edward Slattery <ed...@googlemail.com>.
According to my understanding of open properties, you are right.

If the schema contains a global property of the same name, in the same
namespace, then the open content should be created following the schema
definition for that global property.

I would expect that an open property described with a cardinality of 1 would
be single-valued, and one which was unbounded would be many-valued. I would
also expect that properties defined as xsd:string type would be of SDO
dataType.

The interesting problems arise when there is no schema definition of the
corresponding global property. In that case some assumptions are made, and I
believe the default is that the newly created property will itself be an
open sequenced dataObject type. Any text content read from the XML document
will appear as text elements in the sequence, and any elements found within
the open property will also be open, unless they have a global property
definition in the schema.

On 18/05/06, kelvin goodson <ke...@gmail.com> wrote:
>
> Hello,
> given the recent set of people announcing themselves as working on
> Tuscany,  I guess I should say hello properly.  I'm Kelvin Goodson, and
> I'm
> working on Java SDO.
>
> To that end I've recently been doing some digging with SDO Java open
> content
> programs, and I'm not sure what the behaviour should be at times.  I've
> been
> jotting my musings at
> http://wiki.apache.org/ws/Tuscany/Java/SDO/ThinkingAloud/OpenContent.
>
> I'd like to clarify the behaviour of the Java code with respect to the
> maxOccurs values associated with global elements and wildcards (I've
> opened
> Jira http://issues.apache.org/jira/browse/TUSCANY-396 for this,  but the
> discussion here goes beyond that issue.)
>
> Here's my starting 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="openStockQuote" type="simple:OpenQuote"/>
>   <xsd:element name="note" type="xsd:string"/>
>
>   <xsd:complexType name="OpenQuote">
>       <xsd:sequence>
>          <xsd:element name="symbol" type="xsd:string"/>
>          <xsd:any maxOccurs="1" 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 p =
> XSDHelper.INSTANCE.getGlobalProperty("
> http://www.example.com/simpleGlobalElem",
> "simple", true);
>
> so then you should I think be 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");
>
> but there's a problem with the code at the moment I think (see above
> referenced Jira)
>
> so at the moment you have to do something like this ...
>
>      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);
>
>      // value must be added as a list
>      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>
>
> Open content with max occurs > 1
>
> The behaviour of the code here may throw some light on why the single
> valued
> case is as it is, and perhaps that I have misunderstood that case. Here's
> where my experiments have led so far
>
> 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);
>
>      Property pc2 =
> XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
> "count", isElement);
>
>      List lcount = new ArrayList();
>      lcount.add(new Integer(1));
>
>      doq.set(pc2, lcount);
>
>      ByteArrayOutputStream baos = new ByteArrayOutputStream();
>
>      XMLHelper.INSTANCE.save(doq, "http://www.example.com/open",
> "openStockQuote2", baos);
>
>      System.out.println(baos.toString());
>
> Which kind of surprised me a bit, since I had expected the second set()
> call
> to overwrite the first, but now it kind of makes sense. So that makes me
> reconsider the semantics I had placed upon the single cardinality case
> above, and begs the question whether the above referenced JIRA I raised
> was
> in error.
>
> OK, so if my theory is correct, that the cardinality of the global
> elements
> (unspecified) causes this requirement for adding a value wrapped in a
> List,
> then adding .....
>
>   <xsd:element name="oneNote" type="xsd:string" maxOccurs="1" />
>
> to the schema should allow me to do ...
>
>      Property pOneNote =
> XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
> "oneNote", true);
>      doq.set(pOneNote, "this is it!");
>
> on a DataObject of Type OpenQuote
>
> but it doesn't! it still fails as described above, when expecting the
> supplied argument to be a List, even though both the xsd:any and the
> global
> element have maxOccurs = 1 on them! So either I still misunderstand, or
> there's something wrong here.
>
>

Re: 1) Hello and 2) Open Content issue

Posted by Frank Budinsky <fr...@ca.ibm.com>.
Hi Kelvin,

First, regarding JIRA-396, it is working as designed, although it could be 
better I suppose. The bottom line, as you seem to have figured out, is 
that the multiplicity of the feature being added is the one that 
determines whether a list or single value is expected. The multiplicity of 
the xsd:any is ignored. It's really an issue of whether or not the SDO API 
ensures that only valid documents can be created. The fact that it allows 
you to exceed the maxOccurs=1 is no different than it not preventing you 
from exceeding a limit like maxOccurs=10 on any ordinary property. Unless 
you run a validator, there is no guarantee that multiplicity limits aren't 
being exceeded. In general, for the maxOccurs=1 case, SDO enforces it by 
the fact that the API becomes set() instead of List. For the open content 
maxOccurs=1 xsd:any case, we could possibly change to set(value), since we 
know that adding more than one is invalid ... that would be a little 
nicer, but as you've pointed out that still wouldn't prevent one from 
creating an invalid document.

Second, although your theory is right, the problem with your example:

   <xsd:element name="oneNote" type="xsd:string" maxOccurs="1" />

is that it is invalid XSD ... maxOccurs is not allowed on global elements. 
If you run your schema through a validator, it will show this to be an 
error. So, the bottom line for SDO is that there is no standard way to 
specify a single valued global element in XMLSchema. Maybe SDO should 
consider adding an annotation to allow this.

You should be able to get this to work, if you define a global property 
using dynamic SDO (and make the xsd:any processContents="lax"). That way 
you can create a property with maxOccurs=1. You just can't define it in 
XSD.

I like the wiki page you're creating ... maybe eventually it can be turned 
into an article or be added to the SDO documentation.

Frank.




"kelvin goodson" <ke...@gmail.com> 
05/18/2006 05:27 AM
Please respond to
tuscany-dev


To
tuscany-dev <tu...@ws.apache.org>
cc

Subject
1) Hello and 2) Open Content issue






Hello,
  given the recent set of people announcing themselves as working on
Tuscany,  I guess I should say hello properly.  I'm Kelvin Goodson, and 
I'm
working on Java SDO.

To that end I've recently been doing some digging with SDO Java open 
content
programs, and I'm not sure what the behaviour should be at times.  I've 
been
jotting my musings at
http://wiki.apache.org/ws/Tuscany/Java/SDO/ThinkingAloud/OpenContent.

I'd like to clarify the behaviour of the Java code with respect to the
maxOccurs values associated with global elements and wildcards (I've 
opened
Jira http://issues.apache.org/jira/browse/TUSCANY-396 for this,  but the
discussion here goes beyond that issue.)

Here's my starting 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="openStockQuote" type="simple:OpenQuote"/>
   <xsd:element name="note" type="xsd:string"/>

   <xsd:complexType name="OpenQuote">
       <xsd:sequence>
          <xsd:element name="symbol" type="xsd:string"/>
          <xsd:any maxOccurs="1" 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 p =
XSDHelper.INSTANCE.getGlobalProperty("
http://www.example.com/simpleGlobalElem",
"simple", true);

so then you should I think be 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");

but there's a problem with the code at the moment I think (see above
referenced Jira)

so at the moment you have to do something like this ...

      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);

      // value must be added as a list
      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>

 Open content with max occurs > 1

The behaviour of the code here may throw some light on why the single 
valued
case is as it is, and perhaps that I have misunderstood that case. Here's
where my experiments have led so far

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);

      Property pc2 =
XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
"count", isElement);

      List lcount = new ArrayList();
      lcount.add(new Integer(1));

      doq.set(pc2, lcount);

      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      XMLHelper.INSTANCE.save(doq, "http://www.example.com/open",
"openStockQuote2", baos);

      System.out.println(baos.toString());

Which kind of surprised me a bit, since I had expected the second set() 
call
to overwrite the first, but now it kind of makes sense. So that makes me
reconsider the semantics I had placed upon the single cardinality case
above, and begs the question whether the above referenced JIRA I raised 
was
in error.

OK, so if my theory is correct, that the cardinality of the global 
elements
(unspecified) causes this requirement for adding a value wrapped in a 
List,
then adding .....

   <xsd:element name="oneNote" type="xsd:string" maxOccurs="1" />

to the schema should allow me to do ...

      Property pOneNote =
XSDHelper.INSTANCE.getGlobalProperty("http://www.example.com/open",
"oneNote", true);
      doq.set(pOneNote, "this is it!");

on a DataObject of Type OpenQuote

but it doesn't! it still fails as described above, when expecting the
supplied argument to be a List, even though both the xsd:any and the 
global
element have maxOccurs = 1 on them! So either I still misunderstand, or
there's something wrong here.