diff --git a/src/main/jastadd/Constraints.jrag b/src/main/jastadd/Constraints.jrag new file mode 100644 index 0000000000000000000000000000000000000000..f713c77bc4faad5090def9447b155f98b5e12452 --- /dev/null +++ b/src/main/jastadd/Constraints.jrag @@ -0,0 +1,91 @@ +aspect Constraints { + + coll Set<ConstraintViolation> PetriNet.constraintViolations() [new java.util.HashSet()] root PetriNet; + +} + +aspect ConstraintViolations { + + abstract class ConstraintViolation { + + + public String toString() { + return "Constraint " + getTitle() + " violated in object " + id() + ": " + getMessage(); + } + + protected ASTNode location; + + public String id() { + if (location instanceof PnObject) return ((PnObject) location).getId(); + if (location instanceof PetriNet) return ((PetriNet) location).getId(); + return location.toString(); + } + + protected String title; + protected String description; + protected String message; + + public String getTitle() { return title; } + public String getDescription() { return description; } + public String getMessage() { return message; } + + } + + class CheckIdsConstraint extends ConstraintViolation { + public CheckIdsConstraint(ASTNode location) { + this.location = location; + this.title = "CheckIds"; + this.description = "Checks id attribute existence"; + this.message = "A node of type '" + location.getClass().getSimpleName() + "' must have an id attribute."; + } + } + + class CheckIdUniquenessConstraint extends ConstraintViolation { + public CheckIdUniquenessConstraint(ASTNode location) { + this.location = location; + this.title = "CheckIdUniquess"; + this.description = "Checks id attribute uniqueness"; + this.message = "The id attribute value " + id() + " of the node of type '" + location.getClass().getSimpleName() + "' is not unique."; + } + } + + PetriNet contributes new CheckIdsConstraint(this) + when checkIdsConstraintViolated() + to PetriNet.constraintViolations(); + PnObject contributes new CheckIdsConstraint(this) + when checkIdsConstraintViolated() + to PetriNet.constraintViolations(); +} + +aspect CoreModelConstraints { + + syn boolean PetriNet.checkIdsConstraintViolated() = getId() == null || getId().equals(""); + syn boolean PnObject.checkIdsConstraintViolated() = getId() == null || getId().equals(""); + + coll List<String> PetriNet.ids() [new ArrayList()] root PetriNet; + PnObject contributes getId() to PetriNet.ids(); + + syn Map<String, Long> PetriNet.idCount() = + ids().stream().collect(Collectors.groupingBy(java.util.function.Function.identity(), Collectors.counting())); + + syn boolean PetriNet.uniqueId(String id) = idCount().get(id) <= 1; + syn boolean PnObject.uniqueId(String id) = petriNet().idCount().get(id) <= 1; + + syn Optional<CheckIdUniquenessConstraint> PetriNet.checkIdUniqueness() { + if(uniqueId(getId())) return Optional.empty(); + else return Optional.of(new CheckIdUniquenessConstraint(this)); + } + syn Optional<CheckIdUniquenessConstraint> PnObject.checkIdUniqueness() { + if(petriNet().uniqueId(getId())) return Optional.empty(); + else return Optional.of(new CheckIdUniquenessConstraint(this)); + } + + PetriNet contributes checkIdUniqueness().get() + when checkIdUniqueness().isPresent() + to PetriNet.constraintViolations(); + PnObject contributes checkIdUniqueness().get() + when checkIdUniqueness().isPresent() + to PetriNet.constraintViolations(); + + +}