All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tools.vitruv.dsls.demo.familiespersons.families2persons.FamiliesToPersons.reactions Maven / Gradle / Ivy

import static tools.vitruv.dsls.demo.familiespersons.families2persons.FamiliesToPersonsHelper.assertFemale
import static tools.vitruv.dsls.demo.familiespersons.families2persons.FamiliesToPersonsHelper.assertMale
import static tools.vitruv.dsls.demo.familiespersons.families2persons.FamiliesToPersonsHelper.assertValidFirstname
import static extension tools.vitruv.dsls.demo.familiespersons.families2persons.FamiliesToPersonsHelper.getPersonName
import static extension edu.kit.ipd.sdq.metamodels.families.FamiliesUtil.getMembers
import static extension edu.kit.ipd.sdq.metamodels.families.FamiliesUtil.getRegister

import "edu.kit.ipd.sdq.metamodels.persons" as persons
import "edu.kit.ipd.sdq.metamodels.families" as families

reactions: familiesToPersons
in reaction to changes in families
execute actions in persons

//========== FAMILY-REGISTER ==========
//Creation of a {@link PersonRegister} after a {@link FamilyRegister} was created.
reaction InsertedFamilyRegister {
	after element families::FamilyRegister inserted as root
	call createPersonRegister(newValue)
}

routine createPersonRegister(families::FamilyRegister familyRegister) {
	match {
		require absence of persons::PersonRegister corresponding to familyRegister
	}
	create {
		val personRegister = new persons::PersonRegister
	}
	update {
		persistProjectRelative(familyRegister, personRegister, "model/persons.persons")
		addCorrespondenceBetween(personRegister, familyRegister)
	}
}

//Deletion of a {@link PersonRegister} after a {@link FamilyRegister} was deleted.
reaction DeletedFamilyRegister {
	after element families::FamilyRegister deleted
	call deletePersonRegister(affectedEObject)
}

routine deletePersonRegister(families::FamilyRegister familyRegister) {
	match {
		val personRegister = retrieve persons::PersonRegister corresponding to familyRegister
	}
	update {
		removeObject(personRegister)
		removeCorrespondenceBetween(personRegister, familyRegister)
	}
}

//========== FAMILY ==========
reaction DeletedFamily {
	after element families::Family deleted
	call affectedEObject.members.forEach[deletePerson()]
}

//Lastname of {@link Family} changed.
reaction ChangedLastName {
	after attribute replaced at families::Family[lastName]
	call affectedEObject.members.forEach[updatePersonName(it)]
}

reaction CreatedFather {
	after element families::Member replaced at families::Family[father]
	with newValue !== null
	call {
		updateNameAndCorrespondencesAfterMemberBecameFather(newValue, affectedEObject)
		createMaleFromNewMember(newValue, affectedEObject)
	}
}

reaction CreatedMother {
	after element families::Member replaced at families::Family[mother]
	with newValue !== null
	call {
		updateNameAndCorrespondencesAfterMemberBecameMother(newValue, affectedEObject)
		createFemaleFromNewMember(newValue, affectedEObject)
	}
}

//New member for the position of the son was inserted. Create new son if not existed before, and update correspondences.
reaction InsertedSon {
	after element families::Member inserted in families::Family[sons]
	call {
		createOrFindMale(newValue, affectedEObject)
		existingMemberBecameSon_updateNameAndCorrespondencesOfCorrespondingMale(newValue, affectedEObject)
	}
}

//New member for the position of the daughter was inserted. Create new daughter if not existed before, and update correspondences.
reaction InsertedDaughter {
	after element families::Member inserted in families::Family[daughters]
	call {
		createOrFindFemale(newValue, affectedEObject)
		existingMemberBecameDaughter_updateNameAndCorrespondencesOfCorrespondingFemale(newValue, affectedEObject)
	}
}

routine createOrFindMale(families::Member newMember, families::Family family) {
	match {
		require absence of persons::Male corresponding to newMember
	}
	update {
		createMale(newMember, family)
	}
}

//Checks whether the newFather was actually just created (has no corresponding person) or not.
//Only continues if newFather is a newly created member.
routine createMaleFromNewMember(families::Member newFather, families::Family family) {
	match {
		require absence of persons::Person corresponding to newFather
	}
	update {
		createMale(newFather, family)
	}
}

//Creates corresponding male person for fathers, sons, sets up correspondences
routine createMale(families::Member newMember, families::Family family) {
	match {
		check {
			assertValidFirstname(newMember)
			true
		}
		val personsRegister = retrieve persons::PersonRegister corresponding to family.register
	}
	create {
		val person = new persons::Male
	}
	update {
		person.fullName = newMember.getPersonName
		personsRegister.persons += person
		addCorrespondenceBetween(newMember, person)
		addCorrespondenceBetween(family, person)
	}
}

routine createOrFindFemale(families::Member newMember, families::Family family) {
	match {
		require absence of persons::Female corresponding to newMember
	}
	update {
		createFemale(newMember, family)
	}
}

//Checks whether the newMother was actually just created (has no corresponding person) or not.
//Only continues if newMother is a newly created member.
routine createFemaleFromNewMember(families::Member newMother, families::Family family) {
	match {
		require absence of persons::Person corresponding to newMother
	}
	update {
		createFemale(newMother, family)
	}
}

//Creates corresponding female person for mothers and daughters and sets up correspondences
routine createFemale(families::Member newMember, families::Family family) {
	match {
		check {
			assertValidFirstname(newMember)
			true
		}
		val personsRegister = retrieve persons::PersonRegister corresponding to family.register
	}
	create {
		val person = new persons::Female
	}
	update {
		person.fullName = newMember.getPersonName
		personsRegister.persons += person
		addCorrespondenceBetween(newMember, person)
		addCorrespondenceBetween(family, person)
	}
}

//First check if the newFather existed before (otherwise break) and if so:
// newFather is the member that existed before but now becomes the new father
// newFamily is the family in which the newFather is from now on the father
routine updateNameAndCorrespondencesAfterMemberBecameFather(families::Member newFather, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to newFather with {
			assertMale(it)
			true
		}
	}
	update {
		updateNameAndCorrespondencesOfCorrespondingPerson(newFather, newFamily)
	}
}

//First check if the newMother existed before (otherwise break) and if so:
// newMother is the member that existed before but now becomes the new mother
// newFamily is the family in which the newMother is from now on the mother
routine updateNameAndCorrespondencesAfterMemberBecameMother(families::Member newMother, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to newMother with {
			assertFemale(it)
			true
		}
	}
	update {
		updateNameAndCorrespondencesOfCorrespondingPerson(newMother, newFamily)
	}
}

//newMember is the member that existed before but now becomes the new parent
//correspondingPerson - The correspondence to the family has to change
//newFamily is the family in which the newMember will be parent from now on
//oldFamily is the family in which the newMember was until now
routine updateNameAndCorrespondencesOfCorrespondingPerson(families::Member newMember, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to newMember
		val oldFamily = retrieve families::Family corresponding to correspondingPerson
	}
	update {
		correspondingPerson.fullName = newMember.personName
		removeCorrespondenceBetween(correspondingPerson, oldFamily)
		addCorrespondenceBetween(correspondingPerson, newFamily)
		deleteFamilyIfEmpty(oldFamily)
	}
}

//First check if insertedChild is actually male which it has to be in order to become a son.
routine existingMemberBecameSon_updateNameAndCorrespondencesOfCorrespondingMale(families::Member insertedChild, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to insertedChild with {
			assertMale(it)
			true
		}
	}
	update {
		updatePersonFamilyCorrespondence(insertedChild, newFamily)
	}
}

//First check if insertedChild is actually female which it has to be in order to become a daughter.
routine existingMemberBecameDaughter_updateNameAndCorrespondencesOfCorrespondingFemale(families::Member insertedChild, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to insertedChild with {
			assertFemale(it)
			true
		}
	}
	update {
		updatePersonFamilyCorrespondence(insertedChild, newFamily)
	}
}

//insertedChild is the member that just became a son or daughter. Before, it could have been a parent as well as a child.
//correspondingPerson gets a new name (since most likely the lastname changed) and correspondences are updated.
//newFamily is the family in which the insertedChild is now contained.
//oldFamily is the family in which the insertedChild was a member before.
routine updatePersonFamilyCorrespondence(families::Member insertedChild, families::Family newFamily) {
	match {
		val correspondingPerson = retrieve persons::Person corresponding to insertedChild
		val oldFamily = retrieve families::Family corresponding to correspondingPerson
	}
	update {
		correspondingPerson.fullName = insertedChild.personName
		removeCorrespondenceBetween(correspondingPerson, oldFamily)
		addCorrespondenceBetween(correspondingPerson, newFamily)
		deleteFamilyIfEmpty(oldFamily)
	}
}

//========== MEMBER IN GENERAL ==========
//Firstname of {@link Member} changed.
reaction ChangedFirstName {
	after attribute replaced at families::Member[firstName]
	call updatePersonName(affectedEObject)
}

//Check if the new name is allowed and then update the name of the corresponding person.
routine updatePersonName(families::Member member) {
	match {
		check {
			assertValidFirstname(member)
			true
		}
		val person = retrieve persons::Person corresponding to member
	}
	update {
		person.fullName = member.getPersonName
	}
}

reaction DeletedMember {
	after element families::Member deleted
	call deletePerson(affectedEObject)
}

//Delete the corresponding person after member was deleted and
//also remove any correspondences including either the member or the person.
routine deletePerson(families::Member member) {
	match {
		val person = retrieve persons::Person corresponding to member
		val family = retrieve families::Family corresponding to person
	}
	update {
		removeObject(person)
		removeCorrespondenceBetween(member, person)
		removeCorrespondenceBetween(family, person)
	}
}

routine deleteFamilyIfEmpty(families::Family family) {
	match {
		check family.members.size == 0
	}
	update {
		family.register.families.^remove(family)
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy