Avoiding the Property Race with Conditional Properties
The Property Race
When Rhapsody loads profiles it also loads any property files at that time. If a property is defined more than once (which may happen when you have multiple profiles) then there is a race condition - and there is no way to determine which property file will 'win' and which value will be used.
Conditional Properties
Conditional properties are extremely powerful in Rhapsody and allow properties to take their values from other properties (or even the rhapsody ini, environment variables and other sources).
Conditional properties may include an instruction to Rhapsody to look in all currently loaded profiles for a named property and combine all of their values into one - thereby avoiding the race condition (so long as all of the profiles use the same base conditional property)
The syntax is simply to prefix the original property key with Profiles:: and then Rhapsody will look in all profiles for a property with that name and a prefix of the profile name in which it's looking (which is how each profile defines it's own value).
Rhapsody uses this mechanism in it's own General::Model::VolatileProperties property. It starts with the following - which is the indicator to Rhapsody to evaulate this property and not just use it as a string
?<IsConditionalProperty>
Next there are two more parts. The first reads another property:
$<General::Model::DefaultVolatileProperties>,
And the second checks all loaded profiles for a General::Model::VolatileProperties property (except that the VolatileProperties part should be prefixed by the profile name)
$<Profiles::General::Model::VolatileProperties::,>
Example
Another good example is custom model browsers. Rhapsody has a property AdditionalBrowseHierarchy where those additional browsers are defined. But if you have multiple profiles and they all define browsers using that same property - only one profile will win and only it's custom browsers will show up. But if you use the Profiles conditional property then you can get them all.
I use this in my Profile Builder tool - custom browsers are automatically generated as two properties - one for the AdditionalBrowseHierarchy and a second AdditionalBrowseHierarchy with the profile name prefix. That means that any profiles you create using that tool will all be compatible with other profiles.
For example here is a snippet from it's own HEP file (the Profile Builder profile has custom browsers too) - these two properties are under Model::Project since this is part of a custom browser definition at project level:
This first property tells Rhapsody to check all loaded profiles for an AdditionalBrowseHierarchy property
Property AdditionalBrowseHierarchy String "?<IsConditionalProperty>$<Profiles::Model::Project::AdditionalBrowseHierarchy::,>"
And then this is the profile-specific version of that property that Rhapsody will find
Property ProfileBuilderAdditionalBrowseHierarchy String "CustomBrowser_Browse_Properties,CustomBrowser_Browse_Includes_Properties,CustomBrowser_Browse_Helpers,CustomBrowser_Browse_Add_New_Menus,CustomBrowser_Browse_Context_Patterns"