6.2.5.32. Architecture-EdgeInterpretation¶
Replace each non-hierarchical edge in a view by a (possibly empty) set of edges, depending on the edge type, its stereotype, and its target multiplicity
Required inputs: RFG
Summary
Replaces edges A->B in an RFG view by edges of other edge type. These replacement edges
also have the form A->B, or, if specified, B->A (see is_reversed option later).
Such an edge replacement is also called interpretation.
The configuration of these replacements can be set via two options simple_interpretations and interpretations. simple_interpretations is less flexible but simpler to use. This configuration can modified directly from the axivion_config GUI. However, for complex use cases, interpretations exists and can be set via Python. use_simple_interpretations determines which of the two options should be used. See the configuration description of simple_interpretations for details about it. The remainder of this text describes interpretations.
The way in which the interpretation is carried out is specified by config option
interpretations.
In most cases the replaced edges are of type UML Relation and originate
from an import of a UML-based CASE tool model (like Enterprise Architect or Rhapsody). In order to be processed
in the architecture check, these relations have to be interpreted as dependencies that occur in the source code (source
dependencies), like e.g.
dependencies of type
Source_Dependency, which represent arbitrary source dependencies, or
-
Call, which represent calls in the code, but e.g. do not include dependencies originating from variable accesses.
source_view) and an input target_view_name (the resulting interpreted architecture view target_view).
After invocation, the view named target_view_name contains all nodes already contained in source_view,
and the edges created by the interpretation; the originating edges are removed.
Default Interpretation
The default value of interpretations handles edge types which are subtypes of UML Relation
and which occur often in common CASE tool imports. It
replaces then by edges of type Source_Dependency in the target view. Edges of type
Rhapsody To/From/ToPort/FromPort/AllTag/Stereotype are removed from the target view (no replacement given).
Example Interpretations
A simple and common interpretation is to replace all edges of type UML Dependency by Source Dependency.
This can be done by the following interpretations setting:
{
'UML Dependency': [
(
{},
[
('.*', [{'edge_type': 'Source_Dependency'}]),
],
)
}
One can restrict the edge type to Call - then other source accesses between two software components
only connected by a UML Dependency in the originating model are reported as divergences:
{
'UML Dependency': [
(
{},
[
('.*', [{'edge_type': 'Call '}]),
],
)
]
}
It is possible to make the dependencies optional (resulting edges have the Architecture.Is_Optional attribute set):
{
'UML Dependency': [
(
{},
[
('.*', [{'edge_type': 'Call ', 'is_optional': True}]),
],
)
]
}
It is also possible to generate more than one edge (or no edge at all):
{
'UML Dependency': [
(
{},
[
('.*', [{'edge_type' : 'Call ', 'is_optional ': True}, {'edge_type ': 'Use_Of_Type ', 'is_optional ': True}]),
],
)
]
}
and to give interpretations for different edge types:
{
'UML Dependency': [
(
{},
[
('.*', [{'edge_type': 'Source_Dependency', 'is_optional': True}]),
],
)
],
'UML InformationFlow': [
(
{},
[
('.*', [{'edge_type': 'Call ', 'is_optional': True, 'is_reversed' : True}]),
],
)
],
}
Here the rule given for edge type UML InformationFlow generates edges of type Call that are
reversed (i.e., source and target nodes are swapped), by specifying a true value for the option is_reversed.
Details of interpretation specifications
Besides discriminating by edge types, the format of interpretations allows to distinguish further between multiplicity and stereotype information. In the following this is explained by a more complex example: an architecture model is chosen that uses the UML relations Dependency and Realisation for modeling relations between architectural entities of a C++ or C# system:
- An edge A -> B of type
UML Dependencywithout annotated stereotypes shall represent that a source code element mapped to entity A is allowed to access each source code element in entity B in any possible way (including calls, reading and setting members, including files, using types etc.). -
An edge A -> B of type
UML Dependencyannotated with the stereotypeClientshall represent that entities in A are allowed to call routines in B and are allowed to read global variables defined in B; no other source relations are allowed. -
If the multiplicity of an edge A -> B of type
UML Dependencyis given as 1 for the source and 0..* for the target, there does not necessarily have to be a corresponding actual dependency between entities mapped to A and entities mapped to B in the code. - An edge A -> B of type
UML Realisationshall represent that A is an instance of B, i.e., A and B are mapped to classes such that the class corresponding to A inherits from B.
{
'UML Dependency': [
(
{'source': ['1'], 'target': ['0..*']}, # multiplicity constraint
[ # list for different stereotype conditions
(None, [{'edge_type ': 'Source_Dependency', 'is_optional': True}]), # no stereotype
(
'Client ', # stereoype Client
[ # list of dictionaries describing edge types and attributes
{'edge_type': 'Call', 'is_optional': True},
{'edge_type': 'Variable_Use', 'is_optional': True},
],
),
],
),
(
{}, # empty multiplicity. constraint
[
(None, [{'edge_type': 'Source_Dependency', 'is_optional': False}]),
(
'Client',
[
{'edge_type': 'Call', 'is_optional': False},
{'edge_type': 'Variable_Use', 'is_optional': False},
],
),
],
),
],
'UML Realisation': [
(
{},
[
(
'.*',
[
{'edge_type': 'Extend'},
{'edge_type': 'Override'},
],
)
],
)
],
}
In general, interpretations represents a decision tree: the rule chooses the concrete
interpretation for a given architecture edge by checking the type of the edge, then
potential multiplicity conditions, then potential annotated stereotypes.
-
A multiplicity condition is given as a dictionary with potential keys
'source'and'target', having a list of strings as values; see comment# multiplicity constraintin the example. If one (or both) of these conditions is given, the tool checks whether the multiplicities of the architectural edge (given by the attributesUML.Source_Multiplicityresp.UML.Target_Multiplicityin the RFG) matches one of the elements in the corresponding list. If an empty dictionary is given (see line with '# empty mult. constraint' comment in the example), no check takes place and the edge automatically satisfies the condition. -
The stereotype conditions are given as the
first components of a list, see comment
#list for different stereotype conditionsin the example. Each of the components of such a list is processed in sequence. The value None for a stereotype condition matches only for edges having no stereotype attached. The wildcard '.*' matches all edges (with or without attached stereotype). All other values (like'Client'in our example) match every edge having the stereotype with exactly the same name attached (regular expressions can also be used). -
Each dictionary following in the nested list (see
# list of dictionaries describing edge types and attributesin the example) corresponds to an edge of the interpretation that has to be created. Therefore they require the key'edge_type'to be defined; optionally, boolean values for the keys'is_optional'and'is_reversed'can be given (all other keys are ignored). If'is_optional'is specified, the attributeArchitecture.Is_Optionalis attached to the newly created edge; if'is_reversed'is specified, the direction of the edge is reversed (i.e., it points from B to A, see example before).
Possible Messages
This rule has no predefined messages.
Options¶
This rule shares the following common options: exclude_messages_in_system_headers, excludes, includes, justification_checker, post_processing, provider, severity
The following places define options that affect this rule: Analysis-GlobalOptions
export_warnings¶
export_warnings : bool = True
interpretations¶
interpretations
More powerful version of the simple_interpretations attribute. use_simple_interpretations must beType: typing.Any
Default:
{ 'Rhapsody AllTag': [({}, [(None, []), ('.*', [])])], 'Rhapsody From': [({}, [(None, []), ('.*', [])])], 'Rhapsody FromPort': [({}, [(None, []), ('.*', [])])], 'Rhapsody Stereotype': [({}, [(None, []), ('.*', [])])], 'Rhapsody To': [({}, [(None, []), ('.*', [])])], 'Rhapsody ToPort': [({}, [(None, []), ('.*', [])])], 'UML Aggregation': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Association': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Composition': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Delegate': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Dependency': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Generalisation': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Generalization': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML InformationFlow': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Instance': [({}, [(None, []), ('.*', [])])], 'UML Nesting': [({}, [(None, []), ('.*', [])])], 'UML Realisation': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Realization': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])], 'UML Usage': [({}, [(None, [{ 'edge_type': 'Source_Dependency' }]), ('.*', [{ 'edge_type': 'Source_Dependency' }])])] }
False for
interpretations to have any effect.
loglevel¶
loglevel : LogLevel = 'WARNING'
simple_interpretations¶
simple_interpretations
Simplified version of the interpretations attribute that can be edited directly in the GUI. use_simple_interpretations must beType: dict[str, EdgeMapping]
Default:
{ 'Rhapsody AllTag': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'Rhapsody From': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'Rhapsody FromPort': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'Rhapsody Stereotype': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'Rhapsody To': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'Rhapsody ToPort': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'UML Aggregation': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Association': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Composition': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Delegate': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Dependency': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Generalisation': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Generalization': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML InformationFlow': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Instance': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'UML Nesting': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with=None, report_absence=False, reverse=False ), 'UML Realisation': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Realization': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ), 'UML Usage': bauhaus.rules.axivion.architecture.edge_interpretation.EdgeMapping( match_with='Source_Dependency', report_absence=False, reverse=False ) }
True for
simple_interpretations to have any effect
source_view_name¶
source_view_name : str = 'EA Architecture'
target_view_name¶
target_view_name : str = 'Architecture'
use_simple_interpretations¶
use_simple_interpretations : bool = False
Option Types¶
These types are used by options listed above:
AxivionEdge¶
An enumeration.Call
Communication
Declare
Extend
Grant_Friendship_To
Implementation_Of
Include
Inheritance
Override
Source_Dependency
Variable_Use
EdgeMapping¶
EdgeMapping(match_with: Union[bauhaus.rules.axivion.architecture.edge_interpretation.AxivionEdge, str, NoneType] = None, report_absence: bool = False, reverse: bool = False)match_with : AxivionEdge | str | None = None
report_absence : bool = False
reverse : bool = False
LogLevel¶
An enumeration.WARNING
INFO
DEBUG