5.8 OSATE Properties API
This section describes the OSATE API for manipulating properties in AADL models. The methods for getting property declarations, looking up property values, and setting property values are described.
5.8.1 Using Predeclared Properties
The class PredeclaredPropertyNames in package edu.cmu.sei.aadl.model.property.predeclared contains static references to names of the property definitions, types, and constants declared in the standard AADL property sets AADL_Properties and AADL_Project. [Doesn’t currently contain all of them, only the ones we have needed. Should fix this.] When looking up property names in the initPropertyReferences() method of your plug-in action, you should use these constants to get references to predeclared types, constants, and properties.
5.8.2 Getting PropertyDefinition Objects
As discussed in Section 5.3 AADL Properties in the Meta Model, AADL property name declarations are represented as PropertyDefinition objects, which are contained in PropertySet objects. Given a PropertySet object, a property definition can be looked up using the method PropertySet.findPropertyDefinition(String name), which returns the PropertyDeclaration object if it exists, or null if it does not. Similarly, PropertySet also contains the methods findPropertyType(String name) and findPropertyConstant(String name).
Ref lookup methods that we already talked about. What to say about context parameter?
But how is a PropertySet object retrieved? The class OsateResourceManager in package edu.cmu.sei.aadl.model.pluginsupport manages the AADL models, packages, and property sets loaded into Eclipse. In effect, it is the root of the AADL name space. It contains the following static methods for looking up property-related model elements:
    • The method OsateResourceManager.findPropertySet(String name) looks for the property set with the given name and returns the appropriate PropertySet object if it is found. If no such property set is found, the method returns null.
    • The method OsateResourceManager.getAllPropertySets() returns a Set of PropertySet objects, one for each PropertySet in the workspace.
The class also contains static convenience methods that combine findPropertySet with one of PropertySet.findPropertyDeclaration, PropertySet.findPropertyType, and PropertySet.findPropertyConstant. These methods return null if the property set is not found, of if the given element is not found within the property set. The methods are:
    • OsateResourceManager.findPropertyConstant(String psName, String name)
    • OsateResourceManager.findPropertyDefinition(String psName, String name)
    • OsateResourceManager.findPropertyType(String psName, String name)
5.8.3 Testing “Applies to”
It is sometimes interesting to know whether a particular property applies to a given PropertyHolder. The method PropertyHolder.acceptsProperty(PropertyDefinition pd) returns true if the property can be applied to the given component, that is, if the component can hold property values associated with the given property.
5.8.4 Getting Property Values
Class PropertyHolder contains a small army of methods supporting the retrieval of property values. The AADL property lookup algorithm is embodied in the method PropertyHolder.getPropertyValue(PropertyDefinition pd) which returns the given component’s property value for the given property. This method returns a ModalPropertyValue object which deals with the most general case where a value of a property association could depend on the modes of the components in the system. This class is described in Section 5.8.4.1 Modal Property Lookup.
A plug-in typically needs to get the values from specific properties, and thus the author of the plug-in knows ahead of time the property type of the property, whether the property’s values should be lists, and whether the value should depend on the mode. Section 5.5 Getting Simple Property Values introduces the PropertyHolder convenience methods getSimplePropertyValue and getSimplePropertyValueList, as well as the methods of the PropertyUtils class.
As already stated in Section 5.3 AADL Properties in the Meta Model, in addition to searching for property associations based on the AADL specification’s algorithm, the property lookup methods also interpret the append operator +=>, as well as evaluate property values that are references to other property values, references to property constants, and Boolean expressions. Specifically, a PropertyReference object will never be returned by getSimplePropertyValue, or be a member of the List returned by getPropertyValueList or obtained from a ModalPropertyValue. Similarly, the only BooleanValue objects that will be returned will be instances of TRUE and FALSE. Even more concretely, the property lookup methods will only return instances of TRUE, FALSE, StringValue, IntegerValue, RealValue, IntegerRangeValue, RealRangeValue, EnumValue, ClassifierValue, ReferenceValue, and InstanceReferenceValue.
Modal Property Lookup
When traversing an instance model, the methods getSimplePropertyValue and getPropertyValueList are sensitive to the current system operation mode. When the current system operation mode is set, these methods may be safely used with properties whose value depends on the mode because the system operation mode provides the context for determining the correct property value. See ????.
When the value associated with a property may depend on the mode, and you are not using system operation modes, you must use the getPropertyValue method. This method returns a ModalPropertyValue object, which abstracts the secondary process of dealing with the modes in which the property has different values. The interface ModalPropertyValue, and the other classes mentioned in this section, are in package edu.cmu.sei.aadl.model.properties. The interface has the following methods:
    • Method boolean isModal() indicates whether the value depends on modes.
    • Method AadlPropertyValue getValue() returns the property value when it is non- modal. The exception ModeNotSpecifiedException is thrown if isModal returns true. The interface AadlPropertyValue is discussed subsequently.
    • Method Set getModeContexts() returns a set of ModeContext objects. Each ModeContext object represents a component whose modes can affect the value of the property. The modes in scope in a particular ModeContext are returned by method getModes().
    • Method ModeContext[] getModeContextsAsArray() is as above, but returns an array instead of a set.
    • Method AadlPropertyValue getValue(Map modes) gets the property value under the given mode bindings. The Map maps from ModeContext objects to Mode objects, indicating the particular mode that each ModeContext is in. The exception ModeNotSpecifiedException is thrown if a particular mode context requires a binding and is not provided in the map.
    • Method Collection getAllModeBindings() returns all the Maps that make sense to use with getValue.
    • Method Collection getAllValues() returns all the values this property could have as ReflectiveAadlPropertyValue objects.
It is expected that most users will use the getAllValues method. When analyzing system instances that represent modal systems, it is best to use the system operation mode functionality, which removes the complexity of handling modes by allowing the use of the methods getSimplePropertyValue and getPropertyValueList.
As described in Section 5.7.2 Nonexistent Property Values, the value associated with a property can not only be not present, but also nonexistent. Because null cannot be used to represent both cases, OSATE contains the interface AadlPropertyValue. This interface declares the following methods:
    • Method boolean exists() returns whether the value exists or not. If exists() returns false, then the rest of the methods are irrelevant.
    • Method boolean isNotPresent() returns whether the value is not present.
    • Method boolean isList() returns whether the value is a list or not. Returns false if !exists() || isNotPresent().
    • Method PropertyValue getScalarValue() returns the value if !isList(). The method throws an UnsupportedOperationException if isList().
    • Method List getValue() returns the value as a List of PropertyValue objects. If !isList(), then the list has a length of one, and the list contains the PropertyValue object returned by getScalarValue().
The interface ReflectiveAadlPropertyValue extends AadlPropertyValue and adds the method Map getModeBinding(). This method returns the mode binding for which the value is associated with the property. The Map is in the same format as required by ModalPropertyValue.getValue().
Finally, the interface ModeContext is used to abstract whether the modes relevant to a ModalPropertyValue come from a ComponentImpl, as they will if we are looking up properties on a component of a declarative model, or a SystemInstance, as they will if we are looking up properties on a component of an instance model. The difference is that in the first case we use Mode objects, and in the second case we need to use objects of type SystemOperationMode (which is a subclass of Mode). The ModeContext interface hides this problem from the plug-in writer. The interface declares two methods:
    • The method String getName() returns the name of the object providing the modes. This exists mainly to support the AADL Properties view plug-in.
    • The method List getModes() returns a List of Mode objects provided by the context.
Most of the time you can avoid having to deal with ModeContext objects by simply using the ModalPropertyValue.getAllValues() method. But to better explain the relationship among ModalPropertyValue, AadlPropertyValue, and ModeContext objects we now present an example based on the specification of ModalSubcomponents.Impl used in Nonexistent Property Values.
Suppose that sub2 refers the Subcomponent object that models subcomponent sub2 of ModalSubcomponents.Impl. Let us consider the following code fragment:
  • ModalPropertyValue mpv = sub2.getPropertyValue("PS", "x");
  • List contexts = mpv.getModeContexts();
  • ModeContext mc = (ModeContext) contexts.get(0);
  • List modes = mc.getModes();
  • Map bindings = new HashMap();
  • for (Iterator i = modes.iterator(); i.hasNext();) {
  • Mode mode = (Mode) i.next();
  • bindings.put(mc, mode);
  • AadlPropertyValue apv = mpv.getValue(bindings);
  • System.out.println("In mode " + mode.getName());
  • if (!apv.exists()) {
  • System.out.println(" nonexistent");
  • } else {
  • if (apv.isNotPresent()) System.out.println(" not present");
  • else System.out.println(apv.getScalarValue().getValueAsString());
  • }
  • }
This code fragment is tightly coupled to knowledge that (1) the value does depend on the mode, and (2) there is exactly one mode context relevant to the property value. In general, it is hard to know this, and this is why ModalPropertyValue provides the methods getAllModeBindings and getAllValues. But this code fragment is useful because it explicates all the steps necessary to get the value of a modal property, even though in general most of these steps will be performed for you by getAllValues. Before examining the code, we provide an example output of the fragment:
In mode M1
1
In mode M2
nonexistent
In mode M3
not present
This is only a sample of the output, because the exact order in which the results of looking up in modes M1, M2, and M3 are printed depends on the order in which the modes are returned by ModeContents.getModes.
While not exercised in this example, executing mpv.isModal() would return true. The ModeContext object referenced by mc represents the ComponentImpl object that models ModalSubcomponents.Impl. Invoking getModes() on that object returns a List containing three Mode objects, one each modeling the modes M1, M2, and M3 declared in ModalSubcomponents.Impl. To get the value for a particular mode, we must create a Map to use with ModalPropertyValue.getValue. We do this by iterating over the Mode objects, see line (6), and putting the specific mode binding into the Map referenced by bindings on line (8). Were there additional ModeContext objects whose modes influenced the value, we would have to make sure to bind them to a particular mode object in bindings as well. On line (9) we finally get the AadlPropertyValue that represents the value for the particular mode. Once we have an AadlPropertyValue object we can test whether the value exists, line (11), whether it is not present, line (14), and get the value, line (15). On line (15) we convert the property value to a String for output using the method getValueAsString().
5.8.5 Modifying Property Associations
Through the PropertyHolder interface, OSATE also provides a family of methods for setting and clearing property associations. It is preferable to use these methods instead of directly manipulating the model because they make sure the resulting model is still legal AADL by, for example, removing pre-existing property associations for the same property, checking that the property applies to the component, and checking that the property value is of the appropriate type.
Setting Property Associations
There are four different property setting methods positioned along two axes:
    • Whether the property value is a list or not.
    • Whether the association is modal or not.
The property setting methods ensure that a property lookup rooted at the given component will obtain the specified value for the given property in the given modes. Whether this value affects the property value obtained from a descendent component depends on the property associations present in the component’s descendents. Each method returns the PropertyAssociation object that is created.
The method setPropertyValue(PropertyDefinition pd, PropertyValue value), which is used above in Section 5.4.2 Class ComponentSecuritySwitch, creates a new association for the given property with the given value. The property association applies to all modes, and any existing property associations for the given property are removed from the component. The method throws an IllegalArgumentException and leaves the component unchanged if the property does not apply to the given component or if the property value is inappropriate for the type of the property. When used with a list-valued property, this method associates the property with a list whose single value is the given value.
To associate a general list of values with a list-valued property use the method setPropertyValue(PropertyDefinition pd, List value), which creates a new association for the given property with the given list of PropertyValues. The property association applies to all modes, and any existing property associations for the given property are removed from the component. The method throws an IllegalArgumentException and leaves the component unchanged if the property does not apply to the given component, if the property is not list- valued, or if one of the PropertyValue objects in the list is inappropriate for the type of the property.
To associate a value with a property in certain modes only, use the methods setPropertyValue(PropertyDefinition pd, PropertyValue value, List modes) and setPropertyValue(PropertyDefinition pd, List value, List modes), where modes is a List of Mode objects. It only makes sense to invoke this method on instances of ComponentImpl, Subcomponent, and InstanceObject, although this is not checked. When invoked on a ComponentImpl the Mode objects are restricted to be from the set of modes returned by that component’s getAllModes method. When invoked on a Subcomponent, the Mode objects are restricted to be from the set of modes returned by that subcomponent’s containing component’s getAllModes method. When invoked on an InstanceObject, the modes are restricted to be SystemOperationMode objects from the root SystemInstance. Currently, these restrictions are unchecked. In addition to creating a new property association, these methods may result in changes to the inModes attribute of other property associations for the same property, to ensure that the property only has one association in the given component for the given set of modes. These methods throw an IllegalArgumentException under the same circumstances described above.
These methods all return a PropertyAssociation whose derived attribute is false. For list- valued properties, the append attribute is always set to false. If desired, these attributes can be set to true by manipulating the returned PropertyAssociation object directly.
A separate set of methods exists for creating contained property associations. These setContainedPropertyValue methods are like those described above except they have an additional List parameter that is a list of PropertyHolder objects. This list is used to initialize the appliesTo attribute of the property association, and enumerates a path to a specific subcomponent or feature. It is checked that this list has at least one element, but it is not checked whether the path described in the list identifies an actual subcomponent or feature that makes sense in the given context.
The complete set of methods for setting property values is shown in the table below.
Operation
Method
Set property for all modes
setPropertyValue(PropertyDefinition pd,
PropertyValue value)
Set list-valued property for all modes
setPropertyValue(PropertyDefinition pd, List value)
Set property for the given modes
setPropertyValue(PropertyDefinition pd,
PropertyValue value, List modes)
Set list-valued property for the given modes
setPropertyValue(PropertyDefinition pd, List value,
List modes)
Set property for the contained component for all modes
setContainedPropertyValue(PropertyDefinition pd,
List appliesTo, PropertyValue value)
Set list-valued property for the contained component for all modes
setContainedPropertyValue(PropertyDefinition pd,
List appliesTo, List value)
Set property for the contained component for the given modes
setContainedPropertyValue(PropertyDefinition pd,
List appliesTo, PropertyValue value, List modes)
Set list-valued property for the contained component for the given modes
setContainedPropertyValue(PropertyDefinition pd,
List appliesTo, List value, List modes)
Removing Property Associations
The PropertyHolder interface also contains a set of methods for removing property associations for a given property from the component. The method removePropertyAssociations(PropertyDefinition pd) removes all the property associations for the given property from the component. The method removePropertyAssociations(PropertyDefinition pd, List modes) removes all the property associations for the given property for the given modes from the component. The List of Mode objects has the same constraints as described for setPropertyValue. This method may remove PropertyAssociation objects from the model, but it may also modify the inModes attribute of PropertyAssociation objects as well, in the case where the association’s modes are not completely contained in the list of modes to removed.
A parallel set of methods exists for removing contained property associations. The complete set of methods for removing property associations and contained property associations from a component is shown below.
Operation
Method
Remove all property associations
removePropertyAssociations(PropertyDefinition pd,
List appliesTo)
Remove property associations for the given modes
removePropertyAssociations(PropertyDefinition pd,
List appliesTo, List modes)
Remove all property associations from the contained component
removeContainedPropertyAssociations(
PropertyDefinition pd, List appliesTo)
Remove property associations for the given modes from the contained component
removeContainedPropertyAssociations(
PropertyDefinition pd, List appliesTo, List modes)