-
Notifications
You must be signed in to change notification settings - Fork 0
#683 Add activity constraints #684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
12cb8f6
58705a8
6fe4ef6
212a07b
3bb41f9
0fa177a
a468205
19fa69f
6b5dc4d
8a1f8c1
ee430c6
3127da1
5aa521f
ab173a0
549e163
8cd8aac
f689a77
686be24
281f185
1c52cc8
49a6a8e
3312f5d
e623614
0487e95
2f63429
f0ba3f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,15 +21,18 @@ | |
| import org.eclipse.uml2.uml.Constraint; | ||
| import org.eclipse.uml2.uml.ControlFlow; | ||
| import org.eclipse.uml2.uml.DataType; | ||
| import org.eclipse.uml2.uml.DurationConstraint; | ||
| import org.eclipse.uml2.uml.Element; | ||
| import org.eclipse.uml2.uml.Enumeration; | ||
| import org.eclipse.uml2.uml.EnumerationLiteral; | ||
| import org.eclipse.uml2.uml.InteractionConstraint; | ||
| import org.eclipse.uml2.uml.IntervalConstraint; | ||
| import org.eclipse.uml2.uml.Model; | ||
| import org.eclipse.uml2.uml.NamedElement; | ||
| import org.eclipse.uml2.uml.OpaqueBehavior; | ||
| import org.eclipse.uml2.uml.PrimitiveType; | ||
| import org.eclipse.uml2.uml.Property; | ||
| import org.eclipse.uml2.uml.TimeConstraint; | ||
|
|
||
| import com.github.tno.synthml.uml.profile.util.PokaYokeTypeUtil; | ||
|
|
||
|
|
@@ -276,6 +279,16 @@ public static boolean isPrimitiveTypeConstraint(Constraint constraint) { | |
| return constraint.getContext() instanceof PrimitiveType; | ||
| } | ||
|
|
||
| public static boolean isActivityRequirement(Constraint constraint) { | ||
|
||
| return constraint.getContext() instanceof Activity activity | ||
| // It is the correct type of constraint. | ||
|
||
| && !(constraint instanceof DurationConstraint) && !(constraint instanceof InteractionConstraint) | ||
| && !(constraint instanceof IntervalConstraint) && !(constraint instanceof TimeConstraint) | ||
| // It is neither a precondition nor a postcondition. | ||
| && !activity.getPreconditions().contains(constraint) | ||
|
||
| && !activity.getPostconditions().contains(constraint); | ||
| } | ||
|
|
||
| default boolean hasAbstractActivities() { | ||
| return getDeclaredElements().stream().anyMatch(e -> e instanceof Activity a && a.isAbstract()); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,7 +82,7 @@ public class PokaYokeUmlProfileUtil { | |
|
|
||
| private static final String ST_FORMAL_CONSTRAINT = SynthMLPackage.Literals.FORMAL_CONSTRAINT.getName(); | ||
|
|
||
| public static final String ST_CLASS_REQUIREMENT = SynthMLPackage.Literals.REQUIREMENT.getName(); | ||
| public static final String ST_REQUIREMENT = SynthMLPackage.Literals.REQUIREMENT.getName(); | ||
|
|
||
| public static final String ST_SYNTHESIS_PRECONDITION = SynthMLPackage.Literals.SYNTHESIS_PRECONDITION.getName(); | ||
|
|
||
|
|
@@ -112,8 +112,7 @@ public class PokaYokeUmlProfileUtil { | |
| + ST_FORMAL_CONSTRAINT; | ||
|
|
||
| /** Qualified name for the {@link Requirement} stereotype. */ | ||
| public static final String REQUIREMENT_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR | ||
| + ST_CLASS_REQUIREMENT; | ||
| public static final String REQUIREMENT_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR + ST_REQUIREMENT; | ||
|
|
||
| /** Qualified name for the {@link SynthesisPrecondition} stereotype. */ | ||
| public static final String SYNTHESIS_PRECONDITION_STEREOTYPE = POKA_YOKE_PROFILE + NamedElement.SEPARATOR | ||
|
|
@@ -529,7 +528,7 @@ public static List<Stereotype> getSupportedConstraintStereotypes(Constraint cons | |
| } else if (isPostconditionConstraint(constraint)) { | ||
| return List.of(getStereotype(constraint, ST_POSTCONDITION)); | ||
| } else if (isClassRequirement(constraint)) { | ||
|
||
| return List.of(getStereotype(constraint, ST_CLASS_REQUIREMENT)); | ||
| return List.of(getStereotype(constraint, ST_REQUIREMENT)); | ||
| } else { | ||
| return List.of(); | ||
| } | ||
|
|
@@ -592,7 +591,7 @@ public static void setConstraintStereotype(Constraint constraint, Stereotype ste | |
| } | ||
|
|
||
| private static String getQualifiedStereotypeName(String stereotypeName) { | ||
| if (ST_CLASS_REQUIREMENT.equals(stereotypeName)) { | ||
| if (ST_REQUIREMENT.equals(stereotypeName)) { | ||
| return REQUIREMENT_STEREOTYPE; | ||
| } else if (ST_SYNTHESIS_PRECONDITION.equals(stereotypeName)) { | ||
| return SYNTHESIS_PRECONDITION_STEREOTYPE; | ||
|
|
@@ -616,7 +615,7 @@ public static void setConstraintExpression(Constraint constraint, String newValu | |
|
|
||
| public static String getStereotypeName(Stereotype st) { | ||
| // Returns a slightly better formatted name for the preconditions. | ||
| if (st.getName().equals(ST_CLASS_REQUIREMENT)) { | ||
| if (st.getName().equals(ST_REQUIREMENT)) { | ||
| return "Requirement"; | ||
| } else if (st.getName().equals(ST_SYNTHESIS_PRECONDITION)) { | ||
| return "Synthesis precondition"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -544,8 +544,12 @@ private void checkValidActivity(Activity activity) { | |
| .filter(IntervalConstraint.class::isInstance).map(IntervalConstraint.class::cast) | ||
| .collect(Collectors.toCollection(LinkedHashSet::new)); | ||
|
|
||
| if (!members.equals(Sets.union(preAndPostconditions, intervalConstraints))) { | ||
| error("Activity should contain only precondition, postcondition, and interval constraint members.", | ||
| Set<Constraint> activityRequirements = activity.getOwnedRules().stream() | ||
| .filter(r -> CifContext.isActivityRequirement(r)).map(Constraint.class::cast) | ||
| .collect(Collectors.toCollection(LinkedHashSet::new)); | ||
|
|
||
| if (!members.equals(Sets.union(Sets.union(preAndPostconditions, intervalConstraints), activityRequirements))) { | ||
|
||
| error("Activity should contain only precondition, postcondition, constraints and interval constraint members.", | ||
| UMLPackage.Literals.NAMESPACE__MEMBER); | ||
| } | ||
|
|
||
|
|
@@ -1003,8 +1007,8 @@ private void checkValidConstraint(Constraint constraint) { | |
|
|
||
| if (CifContext.isActivityPrePostconditionConstraint(constraint)) { | ||
| checkValidActivityPrePostconditionConstraint(constraint); | ||
| } else if (CifContext.isClassConstraint(constraint)) { | ||
| checkValidClassConstraint(constraint); | ||
| } else if (CifContext.isClassConstraint(constraint) || (CifContext.isActivityRequirement(constraint))) { | ||
|
||
| checkValidClassOrActivityConstraint(constraint); | ||
| } else if (CifContext.isOccurrenceConstraint(constraint)) { | ||
| checkValidOccurrenceConstraint((IntervalConstraint)constraint); | ||
| } else if (CifContext.isPrimitiveTypeConstraint(constraint)) { | ||
|
|
@@ -1058,7 +1062,7 @@ private void checkValidActivityPrePostconditionConstraint(Constraint constraint) | |
| } | ||
| } | ||
|
|
||
| private void checkValidClassConstraint(Constraint constraint) { | ||
| private void checkValidClassOrActivityConstraint(Constraint constraint) { | ||
|
||
| // Check that the constraint has the right stereotype applied. | ||
| List<Stereotype> stereotypes = constraint.getAppliedStereotypes(); | ||
|
|
||
|
|
@@ -1068,7 +1072,7 @@ private void checkValidClassConstraint(Constraint constraint) { | |
| return; | ||
| } | ||
|
|
||
| if (!stereotypes.get(0).getName().equals(PokaYokeUmlProfileUtil.ST_CLASS_REQUIREMENT)) { | ||
| if (!stereotypes.get(0).getName().equals(PokaYokeUmlProfileUtil.ST_REQUIREMENT)) { | ||
| error(String.format("Constraint '%s' must have a requirement stereotype applied.", constraint.getName()), | ||
| UMLPackage.Literals.CONSTRAINT__SPECIFICATION); | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it sufficient to translate the requirements like this? Should we also include all requirements of other activities that we call, etc? (all other 'relevant' activities)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this to be consistent with the occurrence constraints: these are considered only during the activity synthesis, not when an activity is called. Better to have a conversation offline about this.