- 1 Introduction
- 2 Description
- 2.1 Profile Identifier
- 2.2 Model Requirements
- 2.3 How Profiling Works
- 2.4 Additional Behavior
- 3 Keeping an Association As Is
- 4 Configuration
The Profiler creates a subset of a given model. It does so by comparing the profile information of a given model element with the profile provided via a configuration parameter. Profiling is supported for classes (also association classes), and properties (attributes and association roles). Profile information for packages and on a generalization relationship is not considered. However, the Profiler can remove packages from the model in case they are empty after profiling of model elements has been completed.
NOTE: In case that the transformation process defined by the ShapeChange configuration includes both profiling and flattening (see Flattener) of a model, profiling should be applied first. The reverse order may lead to unexpected results. The reason for this is that the Flattener currently does not support specific handling of profile information (e.g. when flattening types).
The following sections describe how profiling works by default, and specifies the configuration of a Profiler.
NOTE: the default profiling behavior with respect to model elements that do not have profile information can be altered by including the rule rule-trf-profiling-explicit-profile-settings. How profiling works with this rule enabled is described on a separate page.
A model element can belong to one or more profiles. The identifier of a profile is structured as follows: profile name, followed by an optional version indicator. If a model element belongs to multiple profiles, the profile identifiers are defined in a comma-separated list.
The regular expression for a profile name is: (\w|-)+
Examples: A, Core, X-Y
The profiler distinguishes between two types of version indicators: strict and loose. The strict type is used for the profile parameter in the Profiler configuration. It is used to identify exactly one version of a profile. The loose type can be used in the profile information of a model element, to define to which specific version or version ranges the element belongs.
The regular expressions for strict and loose version indicators are as follows:
- strict (with a single version number): \[[0-9]+(\.[0-9]+)*\]
- loose (with a list of version numbers, closed version ranges, or open version ranges): \[(-[0-9]+(\.[0-9]+)*|[0-9]+(\.[0-9]+)*-[0-9]+(\.[0-9]+)*|[0-9]+(\.[0-9]+)*-|[0-9]+(\.[0-9]+)*)(;(-[0-9]+(\.[0-9]+)*|[0-9]+(\.[0-9]+)*-[0-9]+(\.[0-9]+)*|[0-9]+(\.[0-9]+)*-|[0-9]+(\.[0-9]+)*))*\]
Examples: [4.7], [1-2;4-5.5], [-3;4], [5-]
Some definitions regarding version indicators:
- The start of a version range is inclusive, while the end is exclusive. [4-5.5], for example, specifies that the model element belongs to all versions from version 4.0 up to version 5.5.
- Version indicators are treated like time instants/periods including the computation of relative position (see ISO 19108 TM_RelativePosition). A single version number thereby can in fact be treated like a version range. For example, the version indicator [1.1.3] has a single version number. The Profiler treats this like the version range [1.1.3-1.1.4].
- The profile range [1.1-1.1.3] is treated like the range [1.1.0-1.1.3].
- If the begin of a version range is undefined (example: [-3]) then it is assumed to be 0, i.e. “zero” or “null”.
- If the end of a version range is undefined (example: [1-]) then it is assumed to be unlimited (more specifically, java.lang.Integer.MAX_VALUE)
- The version ranges [1.1.1-1.1], [1.1-1.1], [2-1], [1.2-1.1] are invalid because the begin of each version range is not before its end.
Profile information for a model element is given via the tagged value “profiles”. The value is a comma-separated list of profile identifiers. If the tagged value is missing or empty, then properties (attributes and association roles) “inherit” the profile information from the class they belong to. If the tagged value is missing for a class then the class is assumed to belong to all possible profiles. This will be explained via examples later on.
How Profiling Works
Containment of Profile Identifiers
To determine whether the profile information of a model element contains a given (set of) profile information, the profiler first determines if all profile names of the given profile information are contained in the profile information of the model element. “A,B”, for example, contains “A”, “B”, and “A,B” but not “C”.
Then the Profiler determines if the version indicators for each profile identifier match up. In order to do so, the profiler checks the relative position of the version ranges that the two version indicators represent. The Profiler uses an OR combination of ISO 19108 BegunBy, Contains and EndedBy: self.begin <= other.begin AND self.end >= other.end. If this relationship is true, then the version indicators match up, i.e. the given version indicator (other) is contained in this version indicator (self).
P[0-MAX_INTEGER] cont P[1-2]: true
P[1-2] cont P[0-MAX_INTEGER] : false
P[1-2] cont P[2-3]: false
P[1-2] cont P[1.1-1.2]: true
P[1.2-5] cont P[1.1.9-3]: false
P[1.2-5] cont P[2-5]: true
As described before, a version indicator can contain a list of version numbers and version ranges. The Profiler automatically merges this information into disjoint version ranges. Example: [1-2.0;1.5-2;0.4-10] is automatically converted to [0.4-10].
Profiling of Model Elements
The following subsections describe how the Profiler handles different model elements: generalization relationships, attributes, associations, and association classes. For a better understanding, the profile identifiers in these examples do not contain version indicators. This is explained via a separate example at the end of this section.
The following figure shows how the Profiler handles a generalization relationship between two model classes.
The following diagram shows invalid profile configurations. They are invalid because the profile set of ClassA does not contain the profile set of ClassB.
This can cause unexpected behavior, when the subtype remains in the model but its supertype has been removed by the profiler. ShapeChange reports an error when it encounters such invalid profile configurations.
The following two figures show how the Profiler handles attributes.
The next diagram shows invalid profile configurations. They are invalid because the profile set of ClassA does not contain the (complete) profile set of attribute3.
When ShapeChange encounters such an invalid profile configuration, it logs a warning.
The following figure shows how the Profiler handles associations.
The next diagram shows an invalid profile configuration. It is invalid because the profile set of ClassA does not contain the (complete) profile set of propCA.
When ShapeChange encounters such an invalid profile configuration, it logs a warning.
The following figure shows how the Profiler handles association classes.
Note: if an association is removed, the association class is removed as well – and vice versa.
Taking Into Account Version Indicators
The following figure shows how the Profiler handles version indicator information. The example is for attributes and classes but the same mechanism applies for other model elements.
The next diagram shows an invalid profile configuration. It is invalid because the profile set of Class1 does not contain the (complete) profile set of attribute3 (where B is unlimited, while for the class it is not).
The Profiler supports a number of optional processing tasks. They are described in the following sections.
The profiler can remove class constraints from the model during the profiling process. The following behaviors are defined:
|constraintHandling Parameter Value||Resulting Behavior|
|keep(this is the default behavior)||Keep all class constraints.|
|remove||Remove all class constraints.|
|removeByPropertyNameInConstraintName||Remove a class constraint if its name contains the name of a property (with the suffix “_Type”) that is being removed through profiling. For example, if the attribute “att” is removed from a class during profiling, then any constraint of that class whose name contains “att_Type” is removed by the Profiler.|
Removal of Residual Types
Profiling may result in object, data and union type classes to no longer be used as the type of a feature type property. The Profiler can remove such residual classes from the model.
Removal of Empty Packages
Profiling can result in all classes of a package to be removed. The Profiler can remove such empty packages. It can also check if a parent package only contains empty packages and remove such (parent) packages as well.
The following diagram shows an example how this works.
Removal of a Class and all its Subtypes
A class can be part of an inheritance hierarchy. Profiling may result in the removal of such a class. If the class is not a leaf in the inheritance tree, the model semantics could be broken. By default the profiler simply removes the class, which leads to a disconnect in the inheritance tree. By enabling rule-trf-profiling-processing-classRemovalIncludesAllSubtypes the profiler can be instructed to not only remove the class but also all its (direct and indirect) subtypes. The following figure illustrates this behavior:
Keeping an Association As Is
The profiler processes properties not only in case they are modelled as class attributes but also if modelled as association roles. If a property represented by an association role is removed by the profiler, the default profiling behavior would lead to a modification or even to the removal of the association. In specific circumstances this may not be desired; instead, associations should be kept as-is. This can be achieved by enabling rule-trf-profiling-processing-keepAssociationAsIs. The following figure illustrates the changed profiling behavior under this rule:
NOTE: if a class is removed then all associations that have this class as source or as target are still removed during profiling.
The following sections specifiy the configuration options for a Profiler.
The class for the Profiler implementation is de.interactive_instruments.ShapeChange.Transformation.Profiling.Profiler.
The following Parameters are supported by the Profiler.
|Parameter Name||Required / Optional||Default Value||Explanation|
|profiles||Required||–||Contains a comma-separated list of profile identifiers (with optional strict version indicator). The Profiler will check if a model element contains this list of profile identifiers, and remove the element if this is not the case.|
|constraintHandling||Optional||keep||Specifies how the Profiler should handle class constraints. See Constraint Handling for further information.|
|residualTypeRemoval_includeSubtypesFor||Optional||–||Regular expression that identifies the non feature type classes of the model for which – if used (directly or indirectly) by feature types – direct subtypes shall not be removed during residual type removal (a postprocessing step available for the profiler).For example, if feature type FT_A has an attribute of type T_B, and T_B has the specializations / subtypes T_B1 and T_B2, which are never used as type in the model, then usually residual type removal would remove T_B1 and T_B2. However, if the residualTypeRemoval_includeSubtypesFor parameter is set to “T_B”, then T_B1 and T_B2 are not removed. However, their subtypes would be removed. If that shall not happen, the regular expression needs to be constructed accordingly, for example: “^T_B\w*”|
The following optional rules are supported by the Profiler.
|Rule Name||Required / Optional||Explanation|
|rule-trf-profiling-preprocessing-profilesValueConsistencyCheck||Optional||Checks that the values of the ‘profiles’ tagged value in model elements are well-formed. If an inconsistent value is found, a warning will be logged.|
|rule-trf-profiling-preprocessing-modelConsistencyCheck||Optional||Checks that the values of the ‘profiles’ tagged value is consistent regarding the model (i.e., the profile sets of a class contains the profile sets of all its subclasses and properties). If an invalid profile configuration is found, an error or warning will be logged.|
|rule-trf-profiling-processing-classRemovalIncludesAllSubtypes||Optional||If this rule is enabled, the profiler does not only remove individual classes if their profiles do not match, but also all their (direct and indirect) subclasses.|
|rule-trf-profiling-processing-explicitProfileSettings||Optional||If this rule is enabled, model elements without profile information are treated as if they belonged to no profile (which overrides the default behavior that classes belong to all profiles and properties inherit profiles from their class).The profiling behavior under this rule is described on a separate page.|
|rule-trf-profiling-processing-keepAssociationAsIs||Optional||If this rule is enabled, the profiler ignores association roles while profiling individual properties. If profiling would normally result in an association role to be removed (and thus the association modified or also removed), it will be kept as is. Note that associations with association class are still removed if the association class is removed.|
|rule-trf-profiling-postprocessing-removeResidualTypes||Optional||The Profiler removes all non feature type classes from the model that are not used directly or indirectly by feature types of the model.More specifically, the Profiler looks for data types, object types, unions etc.: any of these non feature types that is not directly (through attributes, associations, and supertypes) or indirectly (e.g. through other non feature type classes of the model) used by model feature types is removed.Subtypes of non feature types that are not directly or indirectly used are also removed, unless the parameter residualTypeRemoval_includeSubtypesFor is set accordingly.|
|rule-trf-profiling-postprocessing-removeEmptyPackages||Optional||The Profiler removes all empty packages from the model (including parent packages whose child packages are empty).|
At the moment no map entries are defined for the Profiler.
<Transformer class="de.interactive_instruments.ShapeChange.Transformation.Profiling.Profiler" mode="enabled" id="A"> <parameters> <ProcessParameter name="profiles" value="A"/> <ProcessParameter name="constraintHandling" value="remove"/> </parameters> <rules> <ProcessRuleSet name="profiler"> <rule name="rule-trf-profiling-preprocessing-profilesValueConsistencyCheck"/> <rule name="rule-trf-profiling-preprocessing-modelConsistencyCheck"/> <rule name="rule-trf-profiling-postprocessing-removeEmptyPackages"/> </ProcessRuleSet> </rules> </Transformer>