use of org.osate.aadl2.contrib.modeling.ClassifierMatchingRule in project osate2 by osate.
the class Aadl2Validator method checkParameterConnectionClassifiers.
/**
* Checks legality rule L4 for section 9.3 (Parameter Connections) "The data
* classifier of the source and destination must match. The matching rules
* as specified by the Classifier_Matching_Rule property apply (see Section
* 9.2 (L13)). By default the data classifiers must be match."
*/
private void checkParameterConnectionClassifiers(ParameterConnection connection) {
ConnectionEnd source = connection.getAllLastSource();
ConnectionEnd destination = connection.getAllLastDestination();
if (source instanceof ParameterConnectionEnd && destination instanceof ParameterConnectionEnd) {
Classifier sourceClassifier;
Classifier destinationClassifier;
final boolean sourceIsSubcomponent = source instanceof DataSubcomponent;
final boolean destIsSubcomponent = destination instanceof DataSubcomponent;
if (sourceIsSubcomponent) {
sourceClassifier = ((DataSubcomponent) source).getAllClassifier();
} else {
sourceClassifier = ((Feature) source).getAllClassifier();
}
if (destIsSubcomponent) {
destinationClassifier = ((DataSubcomponent) destination).getAllClassifier();
} else {
destinationClassifier = ((Feature) destination).getAllClassifier();
}
if (sourceClassifier == null && destinationClassifier != null) {
warning("Expected " + (sourceIsSubcomponent ? "subcomponent" : "feature") + " \'" + source.getName() + "' to have classifier '" + destinationClassifier.getQualifiedName() + '\'', connection, Aadl2Package.eINSTANCE.getConnection_Source());
} else if (sourceClassifier != null && destinationClassifier == null) {
warning("Expected " + (destIsSubcomponent ? "subcomponent" : "feature") + " \'" + destination.getName() + "' to have classifier '" + sourceClassifier.getQualifiedName() + '\'', connection, Aadl2Package.eINSTANCE.getConnection_Destination());
} else if (sourceClassifier != null && destinationClassifier != null) {
final ClassifierMatchingRule classifierMatchingRuleValue = org.osate.aadl2.contrib.modeling.ModelingProperties.getClassifierMatchingRule(connection).orElse(ClassifierMatchingRule.CLASSIFIER_MATCH);
if (classifierMatchingRuleValue == ClassifierMatchingRule.CLASSIFIER_MATCH) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier)) {
error(connection, '\'' + source.getName() + "' and '" + destination.getName() + "' have incompatible classifiers.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.EQUIVALENCE) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedClassifierEquivalenceMatchesProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_EQUIVALENCE_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.SUBSET) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedClassifierSubsetMatchesProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_SUBSET_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.CONVERSION) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedTypeConversionsProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_TYPE_CONVERSIONS + "'.");
}
}
}
}
}
use of org.osate.aadl2.contrib.modeling.ClassifierMatchingRule in project osate2 by osate.
the class Aadl2Validator method checkPortConnectionClassifiers.
/**
* Checks legality rule L13 for section 9.2 (Port Connections) "For
* connections between data ports, event data ports, and data access, the
* data classifier of the source port must match the data type of the
* destination port. The Classifier_Matching_Rule property specifies the
* rule to be applied to match the data classifier of a connection source to
* the data classifier of a connection destination."
*
* Checks legality rule L14 for section 9.2 (Port Connections) "The
* following rules are supported:
*
* -Classifier_Match: The source data type and data implementation must be
* identical to the data type or data implementation of the destination. If
* the destination classifier is a component type, then any implementation
* of the source matches. This is the default rule.
*
* -Equivalence: An indication that the two classifiers of a connection are
* considered to match if they are listed in the
* Supported_Classifier_Equivalence_Matches property. Acceptable data
* classifiers matches are specified as
* Supported_Classifier_Equivalence_Matches property with pairs of
* classifier values representing acceptable matches. Either element of the
* pair can be the source or destination classifier. Equivalence is intended
* to be used when the data types are considered to be identical, i.e., no
* conversion is necessary. The Supported_Classifier_Equivalence_Matches
* property is declared globally as a property constant.
*
* -Subset: A mapping of (a subset of) data elements of the source port data
* type to all data elements of the destination port data type. Acceptable
* data classifier matches are specified as
* Supported_Classifier_Subset_Matches property with pairs of classifier
* values representing acceptable matches. The first element of each pair
* specifies the acceptable source classifier, while the second element
* specifies the acceptable destination classifier. The
* Supported_Classifier_Subset_Matches property is declared globally as a
* property constant. A virtual bus or bus must represent a protocol that
* supports subsetting, such as OMG DDS.
*
* -Conversion: A mapping of the source port data type to the destination
* port data type, where the source port data type requires a conversion to
* the destination port data type. Acceptable data classifier matches are
* specified as Supported_Type_Conversions property with pairs of classifier
* values representing acceptable matches. The first element of each pair
* specifies the acceptable source classifier, while the second element
* specifies the acceptable destination classifier. The
* Supported_Type_Conversions property may be declared globally as a
* property constant. A virtual bus or bus must support the conversion from
* the source data classifier to the destination classifier."
*/
private void checkPortConnectionClassifiers(PortConnection connection) {
ConnectionEnd source = connection.getAllLastSource();
ConnectionEnd destination = connection.getAllLastDestination();
if ((source instanceof DataAccess || source instanceof DataSubcomponent || source instanceof DataPort || source instanceof EventDataPort) && (destination instanceof DataAccess || destination instanceof DataSubcomponent || destination instanceof DataPort || destination instanceof EventDataPort)) {
Classifier sourceClassifier;
Classifier destinationClassifier;
final boolean sourceIsSubcomponent = source instanceof DataSubcomponent;
final boolean destIsSubcomponent = destination instanceof DataSubcomponent;
if (sourceIsSubcomponent) {
sourceClassifier = ((DataSubcomponent) source).getAllClassifier();
} else {
sourceClassifier = ((Feature) source).getAllClassifier();
}
if (destIsSubcomponent) {
destinationClassifier = ((DataSubcomponent) destination).getAllClassifier();
} else {
destinationClassifier = ((Feature) destination).getAllClassifier();
}
if (sourceClassifier == null && destinationClassifier != null) {
warning("Expected " + (sourceIsSubcomponent ? "subcomponent" : "feature") + " \'" + source.getName() + "' to have classifier '" + destinationClassifier.getQualifiedName() + '\'', connection, Aadl2Package.eINSTANCE.getConnection_Source());
} else if (sourceClassifier != null && destinationClassifier == null) {
warning("Expected " + (destIsSubcomponent ? "subcomponent" : "feature") + " \'" + destination.getName() + "' to have classifier '" + sourceClassifier.getQualifiedName() + '\'', connection, Aadl2Package.eINSTANCE.getConnection_Destination());
} else if (sourceClassifier != null && destinationClassifier != null) {
try {
final ClassifierMatchingRule classifierMatchingRuleValue = org.osate.aadl2.contrib.modeling.ModelingProperties.getClassifierMatchingRule(connection).orElse(ClassifierMatchingRule.CLASSIFIER_MATCH);
if (classifierMatchingRuleValue == ClassifierMatchingRule.CLASSIFIER_MATCH) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier)) {
error(connection, '\'' + source.getName() + "' and '" + destination.getName() + "' have incompatible classifiers.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.EQUIVALENCE) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedClassifierEquivalenceMatchesProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_EQUIVALENCE_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.SUBSET) {
if (!classifiersFoundInSupportedClassifierSubsetMatchesProperty(connection, sourceClassifier, destinationClassifier) && !isDataSubset(sourceClassifier, destinationClassifier)) {
error(connection, "The data type of '" + source.getName() + "' ('" + sourceClassifier.getQualifiedName() + "') is not a subset of the data type of '" + destination.getName() + "' ('" + destinationClassifier.getQualifiedName() + "') based on name matching or the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_SUBSET_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.CONVERSION) {
if (!testClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedTypeConversionsProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_TYPE_CONVERSIONS + "'.");
}
}
} catch (PropertyIsModalException e) {
// ignored exception. handled in separate validation method checkConnectionPropertyIsModal(Connection connection)
}
}
}
}
use of org.osate.aadl2.contrib.modeling.ClassifierMatchingRule in project osate2 by osate.
the class Aadl2Validator method checkFeatureGroupConnectionDirection.
/**
* Check category of source and destination Section 9.5 Legality rules L5-8
*/
private void checkFeatureGroupConnectionDirection(Connection connection) {
if (connection.isAllBidirectional()) {
// this is checked separately
return;
}
final ClassifierMatchingRule classifierMatchingRuleValue = org.osate.aadl2.contrib.modeling.ModelingProperties.getClassifierMatchingRule(connection).orElse(ClassifierMatchingRule.CLASSIFIER_MATCH);
if (classifierMatchingRuleValue == ClassifierMatchingRule.SUBSET) {
// in case of subset if the connection is directional we do not have to match
return;
}
ConnectionEnd source = connection.getAllLastSource();
ConnectionEnd destination = connection.getAllLastDestination();
if (source instanceof FeatureGroupConnectionEnd && destination instanceof FeatureGroupConnectionEnd) {
Context srccxt = connection.getAllSourceContext();
Context dstcxt = connection.getAllDestinationContext();
DirectionType sourceDirection = ((FeatureGroup) source).getDirection();
List<NamedElement> sourceChain = getConnectionChain(connection.getRootConnection().getSource());
if (isInvertNeeded(sourceChain.subList(0, sourceChain.size() - 1))) {
sourceDirection = sourceDirection.getInverseDirection();
}
DirectionType destinationDirection = ((FeatureGroup) destination).getDirection();
List<NamedElement> destinationChain = getConnectionChain(connection.getRootConnection().getDestination());
if (isInvertNeeded(destinationChain.subList(0, destinationChain.size() - 1))) {
destinationDirection = destinationDirection.getInverseDirection();
}
checkThroughConnection(connection);
if (srccxt instanceof Subcomponent && dstcxt instanceof Subcomponent) {
// sibling to sibling
if (sourceDirection.equals(DirectionType.IN)) {
error("The direction of the source " + source.getName() + " of a directional feature group connection must not be in", connection, Aadl2Package.eINSTANCE.getConnection_Source(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (sourceDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(sourceChain, DirectionType.IN, connection, Aadl2Package.eINSTANCE.getConnection_Source());
}
if (destinationDirection.equals(DirectionType.OUT)) {
error("The direction of the destination " + destination.getName() + " of a directional feature group connection must not be out", connection, Aadl2Package.eINSTANCE.getConnection_Destination(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (destinationDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(destinationChain, DirectionType.OUT, connection, Aadl2Package.eINSTANCE.getConnection_Destination());
}
} else if (!(srccxt instanceof Subcomponent)) {
// going down
if (sourceDirection.equals(DirectionType.OUT)) {
error("The direction of the source " + source.getName() + " of this incoming directional feature group connection must not be out", connection, Aadl2Package.eINSTANCE.getConnection_Source(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (sourceDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(sourceChain, DirectionType.OUT, connection, Aadl2Package.eINSTANCE.getConnection_Source());
}
if (destinationDirection.equals(DirectionType.OUT)) {
error("The direction of the destination " + destination.getName() + " of this incoming directional feature group connection must not be out", connection, Aadl2Package.eINSTANCE.getConnection_Destination(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (destinationDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(destinationChain, DirectionType.OUT, connection, Aadl2Package.eINSTANCE.getConnection_Destination());
}
} else if (!(dstcxt instanceof Subcomponent)) {
// going up
if (sourceDirection.equals(DirectionType.IN)) {
error("The direction of the source " + source.getName() + " of this outgoing directional feature group connection must not be in", connection, Aadl2Package.eINSTANCE.getConnection_Destination(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (sourceDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(sourceChain, DirectionType.IN, connection, Aadl2Package.eINSTANCE.getConnection_Source());
}
if (destinationDirection.equals(DirectionType.IN)) {
error("The direction of the destination " + destination.getName() + " of this outgoing directional feature group connection must not be in", connection, Aadl2Package.eINSTANCE.getConnection_Destination(), MAKE_CONNECTION_BIDIRECTIONAL);
} else if (destinationDirection.equals(DirectionType.IN_OUT)) {
checkDirectionOfFeatureGroupMembers(destinationChain, DirectionType.IN, connection, Aadl2Package.eINSTANCE.getConnection_Destination());
}
}
}
}
use of org.osate.aadl2.contrib.modeling.ClassifierMatchingRule in project osate2 by osate.
the class Aadl2Validator method checkAccessConnectionClassifiers.
/**
* Checks legality rule L9 for section 9.4 (Access Connections) "For access
* connections the classifier of the provider access must match to the
* classifier of the requires access according to the
* Classifier_Matching_Rules property. By default the classifiers must be
* the same (see Section 9.1)."
*/
private void checkAccessConnectionClassifiers(AccessConnection connection) {
/*
* Bug 2362: Source and destination with respect to the classifier type is determined by
* direction of travel away from the provider and towards the requirer.
*/
final ConnectionEnd conSrc = connection.getAllLastSource();
final ConnectionEnd conDest = connection.getAllLastDestination();
boolean switched = false;
if (conSrc instanceof AccessConnectionEnd && conDest instanceof AccessConnectionEnd) {
ConnectionEnd source;
ConnectionEnd destination;
if (isOutgoingAccessConnection(conSrc, connection.getAllSourceContext(), conDest, connection.getAllDestinationContext())) {
source = conSrc;
destination = conDest;
} else if (isOutgoingAccessConnection(conDest, connection.getAllDestinationContext(), conSrc, connection.getAllSourceContext())) {
source = conDest;
destination = conSrc;
switched = true;
} else {
// shouldn't ever get here -- set up a null pointer exception
source = null;
destination = null;
}
Classifier sourceClassifier = null;
Classifier destinationClassifier = null;
// for type extension
boolean sourceIsSubcomponent = false;
boolean destIsSubcomponent = false;
if (source instanceof Access) {
sourceClassifier = ((Access) source).getAllClassifier();
} else if (source instanceof Subcomponent) {
sourceClassifier = ((Subcomponent) source).getAllClassifier();
sourceIsSubcomponent = true;
} else if (source instanceof SubprogramProxy) {
sourceClassifier = ((SubprogramProxy) source).getSubprogramClassifier();
sourceIsSubcomponent = true;
}
if (destination instanceof Access) {
destinationClassifier = ((Access) destination).getAllClassifier();
} else if (destination instanceof Subcomponent) {
destinationClassifier = ((Subcomponent) destination).getAllClassifier();
destIsSubcomponent = true;
} else if (destination instanceof SubprogramProxy) {
destinationClassifier = ((SubprogramProxy) destination).getSubprogramClassifier();
destIsSubcomponent = true;
}
if (sourceClassifier == null && destinationClassifier != null) {
warning(switched ? connection.getDestination() : connection.getSource(), "Expected " + (sourceIsSubcomponent ? "subcomponent" : "feature") + " \'" + source.getName() + "' to have classifier '" + destinationClassifier.getQualifiedName() + '\'');
} else if (sourceClassifier != null && destinationClassifier == null) {
warning(switched ? connection.getSource() : connection.getDestination(), "Expected " + (destIsSubcomponent ? "subcomponent" : "feature") + " \'" + destination.getName() + "' to have classifier '" + sourceClassifier.getQualifiedName() + '\'');
} else if (sourceClassifier != null && destinationClassifier != null) {
final ClassifierMatchingRule classifierMatchingRuleValue = org.osate.aadl2.contrib.modeling.ModelingProperties.getClassifierMatchingRule(connection).orElse(ClassifierMatchingRule.CLASSIFIER_MATCH);
if (classifierMatchingRuleValue == ClassifierMatchingRule.CLASSIFIER_MATCH) {
if (!testAccessClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier)) {
error(connection, '\'' + source.getName() + "' and '" + destination.getName() + "' have incompatible classifiers.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.EQUIVALENCE) {
if (!testAccessClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedClassifierEquivalenceMatchesProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_EQUIVALENCE_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.SUBSET) {
if (!testAccessClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedClassifierSubsetMatchesProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_CLASSIFIER_SUBSET_MATCHES + "'.");
}
} else if (classifierMatchingRuleValue == ClassifierMatchingRule.CONVERSION) {
if (!testAccessClassifierMatchRule(connection, source, sourceClassifier, destination, destinationClassifier) && !classifiersFoundInSupportedTypeConversionsProperty(connection, sourceClassifier, destinationClassifier)) {
error(connection, "The types of '" + source.getName() + "' and '" + destination.getName() + "' ('" + sourceClassifier.getQualifiedName() + "' and '" + destinationClassifier.getQualifiedName() + "') are incompatible and they are not listed as matching classifiers in the property constant '" + AadlProject.SUPPORTED_TYPE_CONVERSIONS + "'.");
}
}
}
}
}
use of org.osate.aadl2.contrib.modeling.ClassifierMatchingRule in project osate2 by osate.
the class ModelingProperties method getClassifierMatchingRule.
public static Optional<ClassifierMatchingRule> getClassifierMatchingRule(NamedElement lookupContext, Optional<Mode> mode) {
Property property = getClassifierMatchingRule_Property(lookupContext);
try {
PropertyExpression value = CodeGenUtil.lookupProperty(property, lookupContext, mode);
PropertyExpression resolved = CodeGenUtil.resolveNamedValue(value, lookupContext, mode);
return Optional.of(ClassifierMatchingRule.valueOf(resolved));
} catch (PropertyNotPresentException e) {
return Optional.empty();
}
}
Aggregations