Hi Adrian
The OCL 2.0 specification was never consistenly updated to redefine the
'undefined' value as the 'null' and the 'invalid' functionality. Most
of the MDT-OCL behaviour can be justified by one of the many contradictory
statements in the specification; though NPEs can never be right. Please
submit your example as a Bugzilla and we'll fix it.
I posted a substantive revised text to resolve 'null' and 'invalid' as
http://www.omg.org/issues/ocl2-rtf#Issue14197. We are working to have an
unambiguous specification and an implementation compliant with it.
The corresponding rationalisation of invalid/Invalid/OclInvalid was
applied to CVS HEAD yesterday as part of
https://bugs.eclipse.org/bugs/show_bug.cgi?id=282882.
We are currently resolving a variety of areas where the treatment of
null and invalid is not quite right.
Issue 14197 is our best guess at what is correct and we might have
it implemented by M3 or perhaps M4.
For now I'm afraid you just need to do excess empirical testing.
Regards
Ed Willink
Adrian Price wrote:
Good day mdt.ocl,
Many of our OCL constraints involve complex chained expressions
referencing modelled features and query operations, any part of which
could be undefined.
According to "OCL 2.0 Specification ptc/2005-06-06" Paragraph 7.4.11 (?)
"Undefined Values":
"Some expressions will, when evaluated, have an undefined value. For
instance, typecasting with oclAsType() to a type that the object does not
support or getting the ->first() element of an empty collection will
result in undefined. In general, an expression where one of the parts is
undefined will itself be undefined..." However, in practice I see
NullPointerExceptions when such expressions are evaluated. For example:
inv inParamControlDisabled: let opposite : Bindable =
getInboundValueBinding()->first().getOppositeEndpoint(self).target in
enabled.value and opposite.oclIsKindOf(Parameter) implies
opposite.oclAsType(Parameter).inout <> InOutType::IN
throws NPE if getInboundValueBinding() returns an empty list, apparently
as a result of attempting to using Java reflection APIs to invoke the
getOppositeEndpoint() method on a null reference. At present the only way
around this is to make the OCL expressions self-null-checking, which
obviously makes them more complicated than the spec. suggests they need
be, less readily comprehensible and (presumably) less performant.
Is my understanding of the OCL spec. flawed or is this a bug?
Thanks in advance,
Adrian Price
Senior Architect
TIBCO Software, Inc.