There are two ways to access a derived property with OCL in medini analyze:
- Dot notation (as accessing any other attribute)
- Using getProfilePropertyValue()
Which one you use depends on whether the property returns a single object or a collection. Using the wrong one may lead to incorrect results.
Using Dot Notation
Let’s assume there is the given OCL-based profile property user_prop:
self.mediniGetTracedElements(hazard::PlainItem)
The result of mediniGetTracedElements is always a collection of elements, maybe empty, but nevertheless a collection. Let’s assume now this property is used in another OCL property or in an OCL constraint:
self.user_prop->notEmpty()
Surprisingly, this evaluates always to true, even when an empty collection is returned. The reason is that OCL is a typed language: every operation or operator is checked in advance against the object type of the operand. Profile properties are all typed Object with multiplicity 1. So OCL treats any result as a single object, no matter what actual type is returned at runtime (unlike JavaScript). Now using the OCL collection operator -> on a single object puts that object into a new collection, which is never empty, which explains the behavior.
Using getProfilePropertyValue()
Instead of using dot notation to access a profile property, you can use self.getProfilePropertyValue('user_prop'). This operation is typed as an EList<Object> which means that it always returns a collection. This behavior is different from dot notation: if the expression or query of the derived property user_prop returns a collection, the function just returns it unmodified as the result. The statement
self.getProfilePropertyValue('user_prop)->isEmpty()
works as expected. If, however, the property returns a single object, that object is wrapped in the collection and then returned by the operation. The result might not be expected.
Recommendation
- If the derived property always returns a single object, use dot notation in OCL to access it
- If the property always returns a collection, use getProfilePropertyValue() in OCL to access it
- If the property can return either a single object or a collection, do not access it from OCL scripts or constraints at all