Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Annoying intrinsic default values for primitive types
Annoying intrinsic default values for primitive types [message #1002263] Fri, 18 January 2013 09:17 Go to next message
Eclipse User
Hello,

In an xsd specification I have an attribute like this:

<xs:attribute name="availability"
use="optional" type="T_Availability">

<xs:simpleType name="T_Availability">
<xs:restriction base="xs:float">
<xs:maxInclusive value="1.0"/>
<xs:minInclusive value="0.0"/>
</xs:restriction>
</xs:simpleType>

Here is the issue: given an XML instance that does NOT specify
"availability", reading this attribute still always returns the default
value. My expectation would have been that I get null, because the
attribute is still unset.

I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
representing a Java Float, so this attribute always has a default value
of 0.0f.

I noticed that the same happens with normal ecore models as well: if a
class has an EInt or EFloat attribute, I just cannot unset this to null.

Is there any way for me to get truely unsettable float attributes in the
XSD based model?

Thanks
Marius
Re: Annoying intrinsic default values for primitive types [message #1002273 is a reply to message #1002263] Fri, 18 January 2013 09:43 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Marius,

Comments below.

On 18/01/2013 10:17 AM, Marius Gröger wrote:
> Hello,
>
> In an xsd specification I have an attribute like this:
>
> <xs:attribute name="availability"
> use="optional" type="T_Availability">
>
> <xs:simpleType name="T_Availability">
> <xs:restriction base="xs:float">
> <xs:maxInclusive value="1.0"/>
> <xs:minInclusive value="0.0"/>
> </xs:restriction>
> </xs:simpleType>
>
> Here is the issue: given an XML instance that does NOT specify
> "availability", reading this attribute still always returns the default
> value. My expectation would have been that I get null, because the
> attribute is still unset.
But the feature is of type "float" so of course that cn't be null.
>
> I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
> representing a Java Float, so this attribute always has a default value
> of 0.0f.
Because that's a Java thing. Primitives must have a value and can't be
null.
>
> I noticed that the same happens with normal ecore models as well: if a
> class has an EInt or EFloat attribute, I just cannot unset this to null.
Just as you can't do "int x = null" in Java.
>
> Is there any way for me to get truely unsettable float attributes in the
> XSD based model?
Don't you end up with isSetAvailability/unsetAvailability method?

I think you can use ecore:type="ecore:EFloatObject" if you import
Ecore.xsd so that you end up with a feature of type Float rather than
float. It's an ugly API though and has a significant memory impact.
>
> Thanks
> Marius
Re: Annoying intrinsic default values for primitive types [message #1002352 is a reply to message #1002273] Fri, 18 January 2013 12:44 Go to previous messageGo to next message
Eclipse User
On 18.01.2013 10:43, Ed Merks wrote:
>> I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
>> representing a Java Float, so this attribute always has a default value
>> of 0.0f.
> Because that's a Java thing. Primitives must have a value and can't be
> null.

Well the attribute can certainly be null/unset in the original XML
instance, and it can also be null/unset in my EMF model (in which I'm
not directly using EFloat but a custom EDataType with java.lang.Float).
It is only during the transformation from XML to EMF that the
XSDEcoreBuilder constructed model sneaks in the intrinsic default value.

>> Is there any way for me to get truely unsettable float attributes in the
>> XSD based model?
> Don't you end up with isSetAvailability/unsetAvailability method?

I don't understand what you're saying here. Where should I find these
methods? Could you elaborate this, please?

> I think you can use ecore:type="ecore:EFloatObject" if you import
> Ecore.xsd so that you end up with a feature of type Float rather than
> float. It's an ugly API though and has a significant memory impact.

I'm afraid this is not an option in my project.

I tried to subclass the XSDEcoreBuilder and change the way it builds
EDataTypes but that code is obviously not intended to be modified the
way I want.

Is there any other way to have xs:float values in the XML and have them
mapped to something else than "float"?

Regards
Marius
Re: Annoying intrinsic default values for primitive types [message #1002380 is a reply to message #1002352] Fri, 18 January 2013 13:35 Go to previous messageGo to next message
Eclipse User
> I tried to subclass the XSDEcoreBuilder and change the way it builds
> EDataTypes but that code is obviously not intended to be modified the
> way I want.

I was able to find the following work around:

public class AvoidPrimitiveTypesXSDEcoreBuilder extends XSDEcoreBuilder {
@Override
protected String getInstanceClassName(
XSDTypeDefinition xsdTypeDefinition,
EDataType baseEDataType) {
final String baseTypeName = baseEDataType.getName();
if ("Float".equals(baseTypeName)) {
return "java.lang.Float";
}
// .. other overrides ..
return super.getInstanceClassName(xsdTypeDefinition, baseEDataType);
}
}

This way it is possible to enforce using the java.lang.* types over the
primitive types, and the intrinsic defaults EDataType.getDefault() won't
be triggered.

Regards
Marius
Re: Annoying intrinsic default values for primitive types [message #1002391 is a reply to message #1002352] Fri, 18 January 2013 13:51 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Marius,

Comments below.

On 18/01/2013 1:44 PM, Marius Gröger wrote:
> On 18.01.2013 10:43, Ed Merks wrote:
>>> I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
>>> representing a Java Float, so this attribute always has a default value
>>> of 0.0f.
>> Because that's a Java thing. Primitives must have a value and can't be
>> null.
> Well the attribute can certainly be null/unset in the original XML
> instance,
It's an attribute so it's can't be nillable in the schema sense...
> and it can also be null/unset in my EMF model (in which I'm
> not directly using EFloat but a custom EDataType with java.lang.Float).
Why not just use EFloatObject?
> It is only during the transformation from XML to EMF that the
> XSDEcoreBuilder constructed model sneaks in the intrinsic default value.
Float isn't primitive, so this EDataType's getDefaultValue will be null,
so I'm not sure I follow what you're saying.
>
>>> Is there any way for me to get truely unsettable float attributes in the
>>> XSD based model?
>> Don't you end up with isSetAvailability/unsetAvailability method?
> I don't understand what you're saying here. Where should I find these
> methods? Could you elaborate this, please?
In the generated API you attribute I expect those two methods to be
generated, along with getAvailability/setAvailability.
>
>> I think you can use ecore:type="ecore:EFloatObject" if you import
>> Ecore.xsd so that you end up with a feature of type Float rather than
>> float. It's an ugly API though and has a significant memory impact.
> I'm afraid this is not an option in my project.
So I don't understand how you used you own EDataType for java.lang.Float...
>
> I tried to subclass the XSDEcoreBuilder and change the way it builds
> EDataTypes but that code is obviously not intended to be modified the
> way I want.
>
> Is there any other way to have xs:float values in the XML and have them
> mapped to something else than "float"?
You can only change the mappings with ecore annotations.

I get the feeling your trying to solve a problem that's really not a
problem because you already have isSet/unset methods that provide the
necessary state preservation that you're seeking to achieve...
>
> Regards
> Marius
>
>
>
Re: Annoying intrinsic default values for primitive types [message #1002393 is a reply to message #1002380] Fri, 18 January 2013 13:55 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Marius,

No, because this is unnecessary. One doesn't often see wrapper types
used in APIs because they're unnatural and memory inefficient.

On 18/01/2013 2:35 PM, Marius Gröger wrote:
>> I tried to subclass the XSDEcoreBuilder and change the way it builds
>> EDataTypes but that code is obviously not intended to be modified the
>> way I want.
> I was able to find the following work around:
>
> public class AvoidPrimitiveTypesXSDEcoreBuilder extends XSDEcoreBuilder {
> @Override
> protected String getInstanceClassName(
> XSDTypeDefinition xsdTypeDefinition,
> EDataType baseEDataType) {
> final String baseTypeName = baseEDataType.getName();
> if ("Float".equals(baseTypeName)) {
> return "java.lang.Float";
> }
> // .. other overrides ..
> return super.getInstanceClassName(xsdTypeDefinition, baseEDataType);
> }
> }
>
> This way it is possible to enforce using the java.lang.* types over the
> primitive types, and the intrinsic defaults EDataType.getDefault() won't
> be triggered.
>
> Regards
> Marius
>
Re: Annoying intrinsic default values for primitive types [message #1002418 is a reply to message #1002391] Fri, 18 January 2013 14:38 Go to previous messageGo to next message
Eclipse User
Hi Ed,

thanks for your patience. I guess there is a certain degree of
missunderstanding. Maybe this helps to clear it up:

* I working with 2 models
* model A is XSD based and loaded at runtime using XSDEcoreBuilder
* model B is .ecore based and there is a generated API
* I need to transform content from A -> B
* Instances of model A end up with "float" EDataTypes and create
implicit default values in my QVT transformation, where I just write:

modelBObject.afloatValue := modelAObject.afloatValue;

The issue I'm trying to solve is that I want to have XML instances of
model A where the afloatValue is not set at all, and I want to carry
this fact into model B. But above line sneaks in a 0.0f value into the
model B instance.

As I said in my other post, I'm now able to route XSDEcoreBuilder from
the primitive type to the wrapper type and so the issue doesn't show up
anymore.

Regards
Marius

On 18.01.2013 14:51, Ed Merks wrote:
> Marius,
>
> Comments below.
>
> On 18/01/2013 1:44 PM, Marius Gröger wrote:
>> On 18.01.2013 10:43, Ed Merks wrote:
>>>> I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
>>>> representing a Java Float, so this attribute always has a default value
>>>> of 0.0f.
>>> Because that's a Java thing. Primitives must have a value and can't be
>>> null.
>> Well the attribute can certainly be null/unset in the original XML
>> instance,
> It's an attribute so it's can't be nillable in the schema sense...
>> and it can also be null/unset in my EMF model (in which I'm
>> not directly using EFloat but a custom EDataType with java.lang.Float).
> Why not just use EFloatObject?
>> It is only during the transformation from XML to EMF that the
>> XSDEcoreBuilder constructed model sneaks in the intrinsic default value.
> Float isn't primitive, so this EDataType's getDefaultValue will be null,
> so I'm not sure I follow what you're saying.
>>
>>>> Is there any way for me to get truely unsettable float attributes in
>>>> the
>>>> XSD based model?
>>> Don't you end up with isSetAvailability/unsetAvailability method?
>> I don't understand what you're saying here. Where should I find these
>> methods? Could you elaborate this, please?
> In the generated API you attribute I expect those two methods to be
> generated, along with getAvailability/setAvailability.
>>
>>> I think you can use ecore:type="ecore:EFloatObject" if you import
>>> Ecore.xsd so that you end up with a feature of type Float rather than
>>> float. It's an ugly API though and has a significant memory impact.
>> I'm afraid this is not an option in my project.
> So I don't understand how you used you own EDataType for java.lang.Float...
>>
>> I tried to subclass the XSDEcoreBuilder and change the way it builds
>> EDataTypes but that code is obviously not intended to be modified the
>> way I want.
>>
>> Is there any other way to have xs:float values in the XML and have them
>> mapped to something else than "float"?
> You can only change the mappings with ecore annotations.
>
> I get the feeling your trying to solve a problem that's really not a
> problem because you already have isSet/unset methods that provide the
> necessary state preservation that you're seeking to achieve...
>>
>> Regards
>> Marius
>>
>>
>>
>
Re: Annoying intrinsic default values for primitive types [message #1002430 is a reply to message #1002418] Fri, 18 January 2013 15:05 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Marius,

Comments below.

On 18/01/2013 3:38 PM, Marius Gröger wrote:
> Hi Ed,
>
> thanks for your patience. I guess there is a certain degree of
> missunderstanding. Maybe this helps to clear it up:
>
> * I working with 2 models
> * model A is XSD based and loaded at runtime using XSDEcoreBuilder
> * model B is .ecore based and there is a generated API
> * I need to transform content from A -> B
> * Instances of model A end up with "float" EDataTypes and create
> implicit default values in my QVT transformation, where I just write:
>
> modelBObject.afloatValue := modelAObject.afloatValue;
>
> The issue I'm trying to solve is that I want to have XML instances of
> model A where the afloatValue is not set at all, and I want to carry
> this fact into model B. But above line sneaks in a 0.0f value into the
> model B instance.
I see, so autoboxing is kicking in somehow and assigning the boxed
default... QVT offers no way of testing isAFloatValueSet as a guard?
>
> As I said in my other post, I'm now able to route XSDEcoreBuilder from
> the primitive type to the wrapper type and so the issue doesn't show up
> anymore.
>
> Regards
> Marius
>
> On 18.01.2013 14:51, Ed Merks wrote:
>> Marius,
>>
>> Comments below.
>>
>> On 18/01/2013 1:44 PM, Marius Gröger wrote:
>>> On 18.01.2013 10:43, Ed Merks wrote:
>>>>> I found out that the XSDEcoreBuilder maps the xs:float to an EDataType
>>>>> representing a Java Float, so this attribute always has a default value
>>>>> of 0.0f.
>>>> Because that's a Java thing. Primitives must have a value and can't be
>>>> null.
>>> Well the attribute can certainly be null/unset in the original XML
>>> instance,
>> It's an attribute so it's can't be nillable in the schema sense...
>>> and it can also be null/unset in my EMF model (in which I'm
>>> not directly using EFloat but a custom EDataType with java.lang.Float).
>> Why not just use EFloatObject?
>>> It is only during the transformation from XML to EMF that the
>>> XSDEcoreBuilder constructed model sneaks in the intrinsic default value.
>> Float isn't primitive, so this EDataType's getDefaultValue will be null,
>> so I'm not sure I follow what you're saying.
>>>>> Is there any way for me to get truely unsettable float attributes in
>>>>> the
>>>>> XSD based model?
>>>> Don't you end up with isSetAvailability/unsetAvailability method?
>>> I don't understand what you're saying here. Where should I find these
>>> methods? Could you elaborate this, please?
>> In the generated API you attribute I expect those two methods to be
>> generated, along with getAvailability/setAvailability.
>>>> I think you can use ecore:type="ecore:EFloatObject" if you import
>>>> Ecore.xsd so that you end up with a feature of type Float rather than
>>>> float. It's an ugly API though and has a significant memory impact.
>>> I'm afraid this is not an option in my project.
>> So I don't understand how you used you own EDataType for java.lang.Float...
>>> I tried to subclass the XSDEcoreBuilder and change the way it builds
>>> EDataTypes but that code is obviously not intended to be modified the
>>> way I want.
>>>
>>> Is there any other way to have xs:float values in the XML and have them
>>> mapped to something else than "float"?
>> You can only change the mappings with ecore annotations.
>>
>> I get the feeling your trying to solve a problem that's really not a
>> problem because you already have isSet/unset methods that provide the
>> necessary state preservation that you're seeking to achieve...
>>> Regards
>>> Marius
>>>
>>>
>>>
Re: Annoying intrinsic default values for primitive types [message #1002448 is a reply to message #1002430] Fri, 18 January 2013 15:53 Go to previous messageGo to next message
Eclipse User
On 18.01.2013 16:05, Ed Merks wrote:>> * I working with 2 models
>> * model A is XSD based and loaded at runtime using XSDEcoreBuilder
>> * model B is .ecore based and there is a generated API
>> * I need to transform content from A -> B
>> * Instances of model A end up with "float" EDataTypes and create
>> implicit default values in my QVT transformation, where I just write:
>>
>> modelBObject.afloatValue := modelAObject.afloatValue;
>>
>> The issue I'm trying to solve is that I want to have XML instances of
>> model A where the afloatValue is not set at all, and I want to carry
>> this fact into model B. But above line sneaks in a 0.0f value into the
>> model B instance.
> I see, so autoboxing is kicking in somehow and assigning the boxed
> default...

No, its not autoboxing. And Qvt isn't at fault here either, because it
simply transfers the value from right to left.

The root cause is the model as generated by XSDEcoreModel. Basically
it's the same what happens if you just define a normal ecore model and
add an attribute of type "EFloat". The open the generic EMF editor on a
model instance and you will find that even if the attribute is
unsettable=true and lowerBound=0, it will always be shown as "0.0". It
will never be empty.

> QVT offers no way of testing isAFloatValueSet as a guard?

No, afaik it doesn't. As far as I could learn on the QVT NG, QVTo as
defined by the OMG simply has no notion of attributes being unset.

Regards
Marius
Re: Annoying intrinsic default values for primitive types [message #1002478 is a reply to message #1002448] Fri, 18 January 2013 16:54 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Marius,

Comments below.

On 18/01/2013 4:53 PM, Marius Gröger wrote:
> On 18.01.2013 16:05, Ed Merks wrote:>> * I working with 2 models
>>> * model A is XSD based and loaded at runtime using XSDEcoreBuilder
>>> * model B is .ecore based and there is a generated API
>>> * I need to transform content from A -> B
>>> * Instances of model A end up with "float" EDataTypes and create
>>> implicit default values in my QVT transformation, where I just write:
>>>
>>> modelBObject.afloatValue := modelAObject.afloatValue;
>>>
>>> The issue I'm trying to solve is that I want to have XML instances of
>>> model A where the afloatValue is not set at all, and I want to carry
>>> this fact into model B. But above line sneaks in a 0.0f value into the
>>> model B instance.
>> I see, so autoboxing is kicking in somehow and assigning the boxed
>> default...
> No, its not autoboxing.
Something must. From what you described a primitive is being assigned
to a boxed type...
> And Qvt isn't at fault here either, because it
> simply transfers the value from right to left.
Yes, it's doing exactly what you instructed it to do.
>
> The root cause is the model as generated by XSDEcoreModel. Basically
> it's the same what happens if you just define a normal ecore model and
> add an attribute of type "EFloat". The open the generic EMF editor on a
> model instance and you will find that even if the attribute is
> unsettable=true and lowerBound=0, it will always be shown as "0.0".
Yes, primitives always have a value. Actually, everything always has a
value, but for primitives there is no null value...
> It
> will never be empty.
>
>> QVT offers no way of testing isAFloatValueSet as a guard?
> No, afaik it doesn't.
I saw a post that such a utility can be written generically...
> As far as I could learn on the QVT NG, QVTo as
> defined by the OMG simply has no notion of attributes being unset.
Yes, it's not a concept supported by EMOF. Nor does EMOF have any
concept of primitive types, so EMOF's mapping onto Java for the case of
primitive types is problematic... What does it mean for an attribute to
be optional verses required when its impossible for a primitive-typed
attribute not to have a value?
>
> Regards
> Marius
>
Re: Annoying intrinsic default values for primitive types [message #1002492 is a reply to message #1002478] Fri, 18 January 2013 17:43 Go to previous message
Ed Willink is currently offline Ed Willink
Messages: 4061
Registered: July 2009
Senior Member
Hi Ed

On 18/01/2013 16:54, Ed Merks wrote:
>> As far as I could learn on the QVT NG, QVTo as
>> defined by the OMG simply has no notion of attributes being unset.
Correct. The deficiency is easily overcome by a helper function.
> Yes, it's not a concept supported by EMOF. Nor does EMOF have any
> concept of primitive types, so EMOF's mapping onto Java for the case
> of primitive types is problematic... What does it mean for an
> attribute to be optional verses required when its impossible for a
> primitive-typed attribute not to have a value?
No. EMOF does have unset, but because it's an implementation detail the
point is not laboured. Any value can be optional (unset) by specifying
[0..1] multiplicity.

In practice for EMOF some approach like EMF's extra eFlags is-set bit is
required.

Regards

Ed Willink
Previous Topic:[CDO] [DAWN] State of the project?
Next Topic:[XCore] Altering generated code
Goto Forum:
  


Current Time: Thu Oct 02 04:23:42 GMT 2014

Powered by FUDForum. Page generated in 0.02441 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software