OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

sdo message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: [sdo] [SDO-56]: Need to improve anyType support so as not to use awrapping Data Object for simple types


(We'd like to optionally map xsd:anyType to java.lang.Object instead of
commonj.sdo.DataObject):
Currently xsd:anyType is mapped to the abstract type
commonj.sdo.DataObject. When passing data in a anyType element, the java
object you'd recieve back is commonj.sdo.DataObject whether the passed
data is simple or complex type.

We'd like the ability to specify the following behavior for xsd:anyType
(preferably using annotations):

      * When the data passed to the xsdType element is simple content
        (String, Integer, ...), the we'd like the serialization to
        follow
        the mapping rules for the simple content and get back:
        java.langString, java.lang.Integer, ...
      * When the data passed to the xsdType element is complex content,
        the we'd like the serialization to follow
        the mapping rules for that complete type and get back an SDO
        object representing the content.
      * The java type for a xsd:anyType should be java.lang.Object.

MySampleSDO sampleSDO = ...
Object value = sampleSDO.getMyAnyTypeProperty();

value = java.lang.String if what's sent in myAnyTypeProperty has
xsi:type="xsd:string".
value = MyDataObject if what's sent in myAnyTypeProperty has
xsi:type="MyDataObject".

We'd like this to be resolved in 2.1 release.


Frank Budinsky [31/May/06 04:54 PM] 
I have a few questions.

Given an anyType property like this:

Property myAnyTypeProperty = ...

Are you proposing a new special Type for it? For example, what would the
following return?

1) myAnyTypeProperty.getType().getName() 
2) myAnyTypeProperty.getType().getURI()
3) myAnyTypeProperty.getType().isDataType()
4) myAnyTypeProperty.isContainment()

It seems to me that this property will be very special, and will need
special handling all over the place. For example, won't things like
CopyHelper, etc. need to have special case (instanceof check) for this
kind of property?


Steve Brodsky [01/Jun/06 06:26 AM] 
The following should be all that is needed to support this issue:

1) <element type="xsd:any" sdo:dataType="sdo:Object"> maps to Property
type=sdo:Object containment=true

2) add a special case to the Property constraint "Property.containment
has no effect unless type.dataType=false" that containment is also
enforced when property.type==sdo:Object 

3) corner case #4 is now handled and can be removed


Steve Brodsky [09/Aug/06 09:01 PM] 
Resolve as Steve's comment above.


Ron Barack [10/Aug/06 04:51 PM] 
In this approach, can we distinguish between simple types that have the
same java instance class. For instance, between a element that had
"xsi:type="xs:QName" and one that had "xsi:type="xs:string"?

In the 2.01 spec, this case was handle by inserting a wrapper DataObject
that served as the value of the property itself, and had a single
property to contain the simple value. As awkward as this approach is, it
at least provided a place where the concrete simple type.


Omar Halaseh [10/Aug/06 07:30 PM] 
We should add a comment in the spec that when adding the
sdo:dataType="sdo:Object" annotation to map xsd:any to java.lang.Object,
one will not be able to determine the type of the simple type using
instanceof in the case where more than one simple type map to the same
java type. Examples:

These XSD types all map to java.lang.String:
dateTime, duration, gDay, gMonth, gMonthDay, gYear, gYearMonth, ID,
IDREF, QName, ...


Frank Budinsky [13/Oct/06 04:03 PM] 
Spec update complete - see column Q of latest version of
SDO2.1_JIRA_spec_impacts_2006mmdd.xls for details.


Frank Budinsky [09/May/07 07:32 PM] 
This decision was overturned - see (The new containment=true for
xsd:anyType with dataType="sdo:Object" feature may break existing code).


(The new containment=true for xsd:anyType with dataType="sdo:Object"
feature may break existing code):
There is lots of code that navigates data graphs by checking for
containment properties. For example:

Property property = dataObject.getType().getProperty("propertyName");
if (property.isContainment()) { DataObject child =
dataObject.getDataObject("propertyName"); ... }

The above code may fail on xsd:anyType if we map it to a property with
containment=true, because the value of a "containment" property may not
be a DataObject.

This new feature is optional (you don't "need" to use it), but
nevertheless, using it as currently defined will cause exisitng code to
break.


Ron Barack [25/Oct/06 08:21 PM] 
Does the spec actually say that properties with datatypes as types are
not containment? Was one guarenteed that the above code would work under
2.01?

I would say that, if anything, datatypes should always be contained as
they certainly are not referenced.


Frank Budinsky [25/Oct/06 09:56 PM] 
The spec says this:

Property.isContainment() returns true if the Property is a containment
reference

and the printDataObject() example in the spec does this:

if (value != null && property.isContainment())

{ // For containment properties, display the value with printDataObject
Type type = property.getType(); String typeName = type.getName();
System.out.println( margin + propertyName + " (" +typeName+ "):");
printDataObject((DataObject) value, indent + 1); } 

So yes, I'd say the 2.0.1 spec guaranteed it to work.

Even if this wasn't a guaranteed breaking change, I would say that we've
introduced a major usability issue with this feature. Navigating data
graphs is a very common operation. Where we used to be able to simply
navigate through containment properties, we'd now need to first get the
value and then check if it is an insanceof DataObject before navigating
down the graph.

I don't see a solution to this issue. I think we may need to reject this
change. 

Maybe we can come up with another way to handle the initial requirement
of being able to get and set a simple value of an anyType property.
Maybe we could do this by adding automatic DataObject wrappering to the
conversions that are supported, e.g.,
someObject.setBoolean(anyTypeProperty, true);


Ron Barack [27/Oct/06 10:15 AM] 
I'm wondering if the code snippet in the problem description is really
broken under 2.1. If the value is not a data object, getDataObject()
must return null, right. Isn't it true that all get<T>()'s avoid
throwing exceptions so that clients can "avoid defensive programming"?
In this case, the code must simply check if the value is null (which it
must do anyway, so this is no extra burden on the programmer).

So the question is, what is really the problem here?


Ron Barack [27/Oct/06 10:40 AM] 
But of course the code on page 126, which Frank references above, is
still broken, as the value is retrieved with get() and then simply
casted to DO. 

And getDataObject(int) and getDataObject(Property) still throw
exceptions, so although the example is working, we would get a problem
if the code iterated using the indices.

Or did we decide something different the other we, as we discussed
SDO-136? Could please enter the resolution into the JIRA?


Frank Budinsky [27/Oct/06 04:22 PM] 
Ron, you really should be a lawyer 

I entered in (Various clarifications/ rewordings for the spec.) the
resolution that we agreed to last week for the get<T>(String) issue. My
notes from the meeting said that we agreed that get<T>(String) should
throw ClassCastException if the conversion can't be done, but otherwise
it doesn't throw exceptions. That's how I wrote it up. Let me know if
you think I misunderstood.

With that resolution, I'd say my example at the top of this issue would
fail (throw ClassCastException). Regardless of that particular example,
as you point out, there are many other examples that will fail.


Frank Budinsky [27/Oct/06 10:54 PM] 
Here is a concrete proposal.

We add Object <--> DataObject as another supported conversion. 

DataHelper.convert() can now be used to allow you set an anyType
property with a value that may be either simple or a DataObject:

Object someValue = ... // may be a DataObject or may be a simple value,
e.g., Integer.
myDO.set(myAnyTypeProperty, dataHelper.convert(myAnyTypeProperty,
someValue));

The dataHelper.convert() call will wrap someValue in a DataObject if it
is not already an instanceof DataObject. Otherwise, it just returns
someValue.

To read back the value without the wrapper, you just do the opposite:

Object retrievedValue = dataHelper.convert(objectType,
myDO.get(myAnyTypeProperty));
// retrievedValue will be either a DataObject or the unwrapped simple
type

I don't think we need to mandate exactly how simple types get wrapped,
we can leave that up to the implementation. I think we should say:

When converting from Object to DataObject:

1. if the Object is an instanceof DataObject, return the same Object.
2. otherwise, wrap the Object in in a DataObject either using a value
property or as sequence text.

When converting from DataObject to Object:

1. if the DataObject contains only a dataType property named "value",
return it.
2. otherwise, if the DataObject contains a single text sequence entry,
return it as a String value
3. otherwise, return the DataObject itself.

Given that all DataTypes extend from Object, I think that this also
means that users will be able to call any getXXX/setXXX method and get
the wrappering there as well:

myDO.setFloat(myAnyTypeProperty, 0.99);
float result = myDO.getFloat(myAnyTypeProperty); // result will be 0.99


Omar Halaseh [28/Oct/06 01:38 AM] 
Then would this still work with (We'd like to optionally map xsd:anyType
to java.lang.Object instead of commonj.sdo.DataObject)
sdo:dataType="sdo:Object" annotation?

I want to use the annotation above so the Object<-->DataObject
conversion occurs implicitly.
This way, I get the option of getting back java.lang.Object which could
be a simple type in anyType or a DataObject in the case of a complexType
in anyType.

But now anyonw who wants to cast the anyProperty value must be careful
to check the annotation value
before casting.

Can you please confirm?


Frank Budinsky [30/Oct/06 08:08 PM] 
Then would this still work with (We'd like to optionally map xsd:anyType
to java.lang.Object instead of commonj.sdo.DataObject)
sdo:dataType="sdo:Object" annotation?
No. Using the sdo:dataType="sdo:Object" annotation will work the same as
in SDO 2.0.1. It will map it to a dataType=true property with instance
class java.lang.Object. You can get/set the value with either a simple
value or a DataObject, but when you serialize it, if it is a DataObject
value, it will not be nested (contained). It will instead serialize it
as anyURI reference to the DataObject, which must be contained somewhere
else.

If you want it to be contained, then you have no choice but to use the
default mapping of anyType to DataObject. You need to wrapper simple
values in a DataObject, but the conversion methods I'm proposing above,
let the user avoid dealing with the wrapper. It would be quite
reasonable for a code generator to provide an option to generate Object
versions of the static get/set methods, which also automatically do the
conversion. For example:

Object getMyAnyTypeProperty() { return dataHelper.convert(objectType,
myAnyTypeProperty); }

instead of the normal (return DataObject) pattern:

DataObject getMyAnyTypeProperty() { return myAnyTypeProperty; }

Clients calling this static API wouldn't need to know about the
DataObject warpper.

Note that the only thing that must not change is that the value passed
into and returned form DataObject.set() and DataObject.get() methods
(i.e., the primitive non-converting methods) must be a DataObject for a
proper anyType property. If this isn't the case, we will break the SDO
containment model.


Blaise Doughan [01/Nov/06 09:55 PM] 
I would say that, if anything, datatypes should always be contained as
they certainly are not referenced.

For the above are datatypes contained or referenced? My original
assumption is that they were contained but from Frank's posts I believe
they might be referenced (not contained).


Frank Budinsky [01/Nov/06 10:41 PM] 
Blaise, 

You are right, dataTypes are contained. Sorry if my comment was a little
confusing. What I was referring to is the special case of an sdo:Object
type property having a DataObject value. The point I was making is
reflected in the definition of type Object in sdoModel.xsd:

<xsd:simpleType name="Object" sdoJava:instanceClass="java.lang.Object">
<!-- Only the schema for schemas is allowed to restrict anySimpleType.
<xsd:restriction base="xsd:anySimpleType"/>
The equivalent declaration is a union of the predefined XSD data types.
-->
<xsd:union memberTypes="xsd:anyURI xsd:base64Binary xsd:boolean xsd:byte
xsd:date xsd:dateTime xsd:decimal xsd:double xsd:duration xsd:ENTITIES
xsd:ENTITY xsd:float
xsd:gDay xsd:gMonth xsd:gMonthDay xsd:gYear xsd:gYearMonth xsd:hexBinary
xsd:ID xsd:IDREF xsd:IDREFS
xsd:int xsd:integer xsd:language xsd:long xsd:Name xsd:NCName
xsd:negativeInteger
xsd:NMTOKEN xsd:NMTOKENS xsd:nonNegativeInteger xsd:nonPositiveInteger
xsd:normalizedString xsd:NOTATION xsd:positiveInteger xsd:QName
xsd:short xsd:string
xsd:time xsd:token xsd:unsignedByte xsd:unsignedInt xsd:unsignedLong
xsd:unsignedShort"/>
</xsd:simpleType>

Notice that the union includes anyURI and IDREF. In the case that the
value is a DataObject it needs to serialize a reference to the
DataObject. For example:

<someObject>
<someAnyTypeProperty>...someURI_or_IDREF...</someAnyTypeProperty>
...
</someObject>

For normal dataType values, you'd always get the contained value, for
example:

<someObject>
<someAnyTypeProperty>99.9</someAnyTypeProperty>
</someObject>

I hope this clarifies what I was trying to say.


Ron Barack [01/Nov/06 11:23 PM] 
Frank, could you clarify your clarification: if I have a property p, and
p.getType().isDataType() is true, then p.getContainment() must be false,
correct? Because otherwise, the code examples you gave above will not
work. So DataTypes are not contained, right?


Frank Budinsky [02/Nov/06 12:01 AM] 
My goodness ... I'm really doing a very bad job of clarifying here 

Yes, you are right Ron. I thought that Blaise was asking about XML
element containment vs SDO property containment. Two different things.

In SDO, the concept of containment only applies to DataObjects, it has
no meaning with dataTypes. But in XML, a dataType will still be
serialized as a contained element (unless it's serialized as an
attribute, of course). I thought that was what Blaise was talking about
when I answered his question.

I hope this helps.


Blaise Doughan [02/Nov/06 05:17 PM] 
Yes, you are right Ron. I thought that Blaise was asking about XML
element containment vs SDO property containment. Two different things.
        
In SDO, the concept of containment only applies to DataObjects, it has
no meaning with dataTypes. But in XML, a dataType will still be
serialized as a contained element (unless it's serialized as an
attribute, of course). I thought that was what Blaise was talking about
when I answered his question.

Is this really what users will expect? I find that SDO follows the XML
model with very few exceptions. My understanding was that the
significance of isContainment was to determine if the content was
inlined or available through a reference (not a short cut to determine
if the child was a DataObject). If isContainment works the same for DOs
and data types then we could come up with a decent solution for anyType,
if containment is only for DOs then the anyType solutions become
awkward.


Frank Budinsky [08/Nov/06 06:27 PM] 
I'm planning to make the following update to the document:

1. Reverse the changes that were made for (We'd like to optionally map
xsd:anyType to java.lang.Object instead of commonj.sdo.DataObject).
2. Clarify that isContainment() always returns false for data type
properties.
3. Add DataObject <--> Object as another supported conversion.

Please let me know if I've missed anything.

I'm sorry to be so inflexible on this one, but IBM can absolutely not
live with the earlier resolution to (We'd like to optionally map
xsd:anyType to java.lang.Object instead of commonj.sdo.DataObject).

P.S. Another insight on SDO Property.containment:

Property.containment really was never intended to have anything to do
DataTypes. It's not about XML containment, but rather, DataObject
containment. DataObject containment has special semantic meaning ...
when a DataObject is added to a containment property, it will be removed
from any other container that it may be in. This never happens with
DataTypes. DataObject also has the methods getContainer() and
getContainmentProperty(), which is navigating up containment properties.
Again, this doesn't apply to DataTypes.


Omar Halaseh [09/Nov/06 08:52 PM] 
Oracle position on this issue is to keep it they way it is documented in
the latest spec Java-SDO-Spec-v2.1.0-FINAL_20061108.doc:

==When an element of anyType is used with xsi:type specifying simple
content, a wrapper DataObject must be ==used with a property named
"value" and type of SDO >>Object that is set to the wrapped type. For
example, ==<element name="e" type="anyType"> and a document <e
xsi:type="xsd:int">5</e> results in a wrapper ==DataObject where the
value property is set to the Integer with value 5.

We do not wish to expose convenience conversion methods between
DataObject and simple types at this time. 

In 3.0 we need to revisit this issue and propose a cleaner solution. I
will submit a 3.0 JIRA to track this.




Notice:  This email message, together with any attachments, may contain information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated entities,  that may be confidential,  proprietary,  copyrighted  and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]