[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: [sdo] [SDO-118]: Creating wrapper objects for simple types
Frank Budinsky [17/Sep/07 03:55 PM] I like this idea. I wonder if we can take it a step further and say that calling getType() on the returned DataObject will return the simple (dataType=true) type. That way we also solve the problem in SDO-205. Blaise Doughan [17/Sep/07 09:19 PM] I can see how the following API would work: DataObject DataFactory.create(Type type); DataObject DataFactory.create(String uri, String typeName); We would need to be careful with the following API since several SDO types map to the same Java class (i.e. commonj.sdo.DateTime, commonj.sdo.URI, and commonj.sdo.String all map to java.lang.String). We could document the necessary assumptions though. DataObject DataFactory.create(Class interfaceClass); Would this DataObject still have a property called "value"? What would be the type of the property (if any)? Stefan Bünnig [18/Sep/07 11:48 AM] The intention of the proposal was just to allow the user to create wrapper objects. These wrapper objects are the same that every specification compliant XMLHelper should already be able to create during XML-parsing. We think, we should not change existing behavior for that. Returning a simple Type on DataObject.getType would be a breaking change. It would be unexpected for all existing algorithms that iterate over DataObject-trees in a generic way. May be, it is a good idea for SDO 3.0. The wrapper object should follow the rules in 9.9.4. The type of the wrapper should be dataType=false and open=true. The simple type is set on the "value"-property. The same should be valid for 3.1.3: An SDO implementation may, but is not required to, support conversion between DataObject and DataType values. For example, getDataObject() on String-type property may return a wrapper DataObject for the string value, and getString() on a DataObject property may do the reverse. The exact behavior of this conversion, if supported, is implementation dependent. If there are too many open questions for the method with the class parameter, we could exclude this method. Frank Budinsky [18/Sep/07 04:06 PM] Blaise, I think that create(Class interfaceClass) would work with the same assumptions as TypeHelper.getType(Class instanceClass). In other words, the "value" property of the wrapper would be the same type as TypeHelper.getType(instanceClass) returns. Steffan, To quote Ron from SDO-261: "We need a way for applications to determine if a DataObject is a "real" DataObject, ie, reflects something in the document, or a wrapper, and the document contains only a simple value." This strikes me as a good way to solve this. If DataObject.getType().isDataType() return true, you know that this is simply a data type wrapper, instead of a real DataObject. I think that makes it more fundamentally special (since we know the "value" property is very special anyway), then simply making it look like a normal DataObject, only with a reserved URI/name. I can't see what client code would be broken by this, but maybe I'm just missing something. Could you please show me some examples of client code that would break? Stefan Bünnig [18/Sep/07 05:03 PM] Frank: for me it sounds strange that a DataObject has a simple type but may be, it's a good idea anyway. Please keep in mind that in 9.2.3 XML Complex Types in the case "Complex Type extending a SimpleType" a similar "value"-property is used. Our solution should fit to both cases. You are right, we need a marker on type or DataObject to let the user know that he has a wrapper object in hand. The distinction by dataType on the DataObjects type equals true or false is not enough because the case "Complex Type extending a SimpleType" is not covered. Michael B. Yoder [18/Sep/07 05:31 PM] Having wrapper DataObject's having getType().isDataType() = true, is the way we have implemented the optional conversion between data types and DataObjects (Java spec 3.1.3). It also makes the C++ DataObjectList interface make more sense. In looking at supporting XSD substitution groups that mix simple and complex types, this conversion seems like it will be useful. Having a "value" property is consistent with the 2.1.1 spec, although for 3.0 it would be nice to propose doing away with it. It's not consistent with XPath, (there is no value element) and it requires annotations to fix up clashes with attributes named "value". It seems like using "" or "." would be a nicer XPath to retrive simple content. Blaise Doughan [18/Sep/07 10:03 PM] There are two "value" properties that come into play. The first is related to SDO-83 which corresponds to a name clash in the following situation: <option value="1">Toaster</option> The second is the "value" property on the DataObject wrapper (not the property that holds the DataObject wrapper). Is the consequence of this, that simple types would now have a declared property where before they would not? Ron Barack [18/Sep/07 11:03 PM] There's something very appealing about the Frank's idea that for a wrapper object, getType() returns the simple type. I'd like to consider this a little deeper. Does it mean that when I have a property of type {commonj.sdo}String, that I can set it to either a wrapper object or a java.lang.String? Does it mean that getDataObject should never throw a class cast exception, but instead return a wrapper object for the simple type? The value returned by getString is clear, but what is returned by get()? Does get() return wrapper or the value? Does it depend on what the user used when setting the object? As Stefan asks, can the wrapper object type be extended? How does this effect the answer to the previous questions? What effect does this have on other issues? Not just sdo-261, but also containment, deserialization of anyTypes, etc. Radu Preotiuc [20/Sep/07 05:21 PM] I think that changing the meaning of 'dataType' in this way isn't really a good idea, especially in V2.1.1. Until now, 'dataType' had a very precise meaning and there are a lot of places in the spec where dataType is referenced and user code may reference it as well. On the other hand, if we were to add a new boolean (say on the XML facet of the type, because after all this is a pure XML-ish thing, from the SDO point of view it doesn't matter if the 'value' property is instantiated as an attribute or as simple content) whose meaning is "if this flag is set, then the value of the "value" property is serialized as XML simple content", then it seems that would solve the problem in a way consistent with the current spec. As far as getType() returning the simple type and not the wrapper, I personally don't see how that could work. Is this for some spec-defined wrapper type only or for Schema-defined complex types with simple content? Michael B. Yoder [20/Sep/07 06:48 PM] I think the idea is not to change the meaning of dataType, but to allow DataObject's to represent both simple and complex types. The spec already optionally allows conversions between simple types and DataObjects. Although I do think that it doesn't make sense for a DataObject with getType().isDataType()=true to have a "value" property, since simple types don't have properties. For these DataObjects of simple type the value could be retreived with an xpath of "" or "." e.g. String value = dob.getString("") Radu Preotiuc [20/Sep/07 07:04 PM] After the phone call, I understand the proposal, let me restate it: There is no special wrapper type, an XML like <foo>text</foo> would produce (in the cases where wrapping is needed) a DataObject dobj where dobj.getType() is commonj.sdo.String. In this case, dobj.get("anything") could return the simple value, since there are no instance properties anyway. However, as stated, the proposal doesn't solve the case of the "Schema complex type simple content" (SDO-83). Also, it still seems a big change for SDO 2.1.1 because I think that up until now it was reasonable to think that dobj.getType().isDataType() returned "false", so I'll have to think about what possible implications there are. On the other hand, it would seem better to me if we did solve this in a way consistent with "Schema complex type with simple content". Radu Preotiuc [20/Sep/07 09:23 PM] And one more thing: If we have an SDO property of type commonj.sdo.DataObject (on-demand or otherwise) and we want to set an instance to a wrapped DataObject with type commonj.sdo.String, that would be inconsistent, because commonj.sdo.String does not have commonj.sdo.DataObject as its base type. Radu Preotiuc [26/Sep/07 04:00 AM] We have discussed this internally some more and having data objects whose type is a simple type sounds risky from a compatibility perspective. Let me propose two other ways of handling this: 1. Have the spec define, for each "primitive" datatype a corresponding data object type, which has datatype=true and one "value" property of that primitive datatype, i.e. StringWrapperType will have a "value" property of type "String". Then conversions between primitive datatypes and their wrapper counterparts will be intuitive (like Java autoboxing), all the constraints in the current spec will remain the same and the user will be able to tell by looking at the name/uri of the type that it is a wrapper type. 2. Have the spec define one additional wrapper type, with open content. Then, based on the type of the value being wrapped, an open-content property of that type (with name "value") will be created and added to the wrapper DataObject. Similar to proposal 1, but it requires only one extra spec-defined type. Stefan Bünnig [26/Sep/07 11:41 AM] We agree to Radu that his proposals are less risky than reinventing the type of DataObjects. We like the 2nd proposal more than the 1st. In the first proposal every simple type has to be duplicated. That is also true for user-defined simple types and restricted simple types. In that cases the handling is unclear again. If we accept one of Radus proposals, we should also refine the specification of the case "Complex Type extending a SimpleType". We could set the wrapper type as the base type of the created complex type. So the user had a chance to recognize also complex types as wrappes. Ron Barack [26/Sep/07 07:52 PM - Visible to jira-users] I want to make Stefans proposal a little more concrete, in the hopes of closing this issue and making progress on SDO-"Section 9.10 bullet 6 inconsistent with bullet 7". We are proposing specifying a type as follows URI = {commonj.sdo}Wrapper Open = true Defined Properties = none Base Type = none (or DataObject) Abstract = false The specification would state that this type should be used for simple values of anyTypes, per section 9.9.4, in the wrapper objects optionally returned in 3.1.3 (last paragraph) and potentially also in the resolution of SDO-"Section 9.10 bullet 6 inconsistent with bullet 7". It would also be specified to be the base type used when complex types extend simple types (page 84, second row). When the application recieves the object (as a result of an XMLHelper.load() operation), then the instance will have a single "on-the-fly" open content variable, defined as follows Name = value ContainingType = unspecified, with URI=null. Type = if an xsi:type is given, then the corresponding SDO type. — Otherwise, if the value is simple, then commonj.sdo#String — Otherwise, our unspecified Open, Mixed Type.|| xmlElement = true — This allows us to extend the WrapperType for use in ComplexTypes that extend SimpleTypes, avoiding name clashes on "value".| containment = true many = false There is a little optional magic associated with {commonj.sdo}Wrapper: namely, the automatic conversions described in the last paragraph of 3.1.3. I've been trying for hours to format this better, without success. Hope you all can read it! Ron Barack [27/Sep/07 04:47 PM] In my last comment, the second "otherwise" line should be removed, as the value is always a simple type. Ron Barack [29/Sep/07 01:23 AM] One more clarification: In the case of a ComplexType that extends a SimpleType, the "value" property is not OpenContent, but rather a defined property (as required by spec). On the otherhand, the generated type will still extend {commonj.sdo}Wrapper, which serves identifies the object, gives a hint regarding how getString() will operate, etc. Frank Budinsky [01/Oct/07 09:48 PM] If I understand this, the 2.1.1 objective here is simply to provide a standard way for users to tell the difference between a real DataObject and a simple type (dataType) wrapper, but the current proposal to simply define a standard Wrapper type causes too many issues IMO. I'll try to explain the issues with some examples, below, but I first want to say that I think we need to first try to understand what the proper (SDO 3) solution to this should be, without worrying about the constraints (no breaking changes) that SDO 2.1.1 imposes. Once we agree on the "right behavior", then we can try to introduce something in SDO 2.1.1 that won't be a breaking change, but at the same time won't be a 2.1.1 kludge, that will need to be rethought in 3.0. As far as approaches are concerned, I initially liked Radu's option #1. It's handling this exactly the same way Java does for primitive types that need to be manipulated as Objects. But, as Stefan pointed out, the problem is more complicated because unlike Java, which has a fixed set of primitive types (e.g., int, boolean, float, etc.), SDO dataTypes includes both the standard fixed set, but also can include an unlimited additional set (i.e., all the user defined XSD simpleTypes). To support that, we would need to have on-the-fly generated Wrapper types, or something like that, for simple types that are user defined, but I think that starts to get too ugly, even for 3.0. So, that leaves us with Radu's option 2, which has been proposed in a concrete form by Ron. Let's start with the following example: DataObject wrapper = dataFactory.create("commonj.sdo", "Boolean"); wrapper.set("value", Boolean.TRUE); // this should, and would work with the current proposal My first concern with the design is illustrated by the following: DataObject wrapper = dataFactory.create("commonj.sdo", "Boolean"); wrapper.set("value", "Hello there"); // this would also work, but should throw an exception Also, since the type is open, one could even do this: wrapper.set("foo", "something"); // this would also work, but should throw an exception Now, if we look at the use of this Wrapper type for the base type of ComplexTypes extending SimpleTypes (section 9.2.3), the side effect of "marking" the type as a dataType wrapper this way, is that we make all complex types with simple content isOpen=true. At the SDO level there would be no difference between: <complexType name="foo"> <simpleContent> <extension base="xsd:string"/> </simpleContent> </complexType> and this: <complexType name="foo"> <simpleContent> <extension base="xsd:string"/> </simpleContent> <anyAttribute/> </complexType> They both map to an open type named foo. I really don't see this as a design we want to define as standard behavior for 2.1.1. So, what's the alternative? How about some kind of TypeHelper method that is used to indicate if a type is a wrapper. Maybe something like this: DataObject dobj = ... if (typeHelper.isDataTypeWrapper(dobj)) { System.out.println("value = " + dobj.get("value"); } Both of the "foo" types, above, would return true, but only the second one would be isOpen=true. The DataObject returned from dataFactory.create(someSimpleType) would also be of a type that returns true and any wrappers returned by SDO-"Section 9.10 bullet 6 inconsistent with bullet 7" would also return true.This would also imply the automatic conversion behavior in 3.1.13. Any object who's type returns true, would be defined to have a "value" property, unless we can think of a better way to represent the simple data being wrapped. Btw, if this is all we said in 2.1.1, an implementation could implement it using either Radu's option 1 or 2 (or something else entirely) under the covers. Stefan Bünnig [02/Oct/07 02:59 PM] DataObject wrapper = dataFactory.create("commonj.sdo", "Boolean"); wrapper.set("value", "Hello there"); // this would also work, but should throw an exception When I tried to implement the feature, I have seen this problem too. My solution was to set the "value"-property explicitly to the types default value (e.g. 0 for int or null for String) in the create-method. The call wrapper.isSet("value") would return true after the creation and wrapper.getInstanceProperty("value") would return the "value"-property with the right type. I think that makes sense because if a wrapper is present, the value should be always set. With this solution the upper code snipped would throw an exception. We think an additional isDataTypeWrapper-method could be a good solution for 2.1.1. We would prefer one or both of the following variants: typeHelper.isDataTypeWrapper(dobj.getType()) // because the TypeHelper deals with types dataHelper.isDataTypeWrapper(dobj) // because the DataHelper deals with data Radu Preotiuc [04/Oct/07 03:26 AM] I also see the problem involved in having all complex types with simple content be open as a side-effect of extending the Wrapper type, so what about not trying to solve the two problems at the same time and have complex types with simple content NOT extend the Wrapper type? I still think that we should define this Wrapper type in the spec, because the role of the spec is to, well, specify things. As far as having a method like the one proposed by Frank/Stefan, I don't feel strongly about it, but I would not think about a type like <complexType name="foo"> <simpleContent> <extension base="xsd:string"/> </simpleContent> <attribute name="firstName" type="string"/> <attribute name="lastName" type="string"/> <attribute name="age" type="short"/> </complexType> to be a "wrapper" type. I guess I would prefer a different terminology, like "simpleContent". 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]