package org.obeonetwork.dsl.entityrelation.spec; import java.util.ArrayList; import java.util.Collection; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.obeonetwork.dsl.entityrelation.Attribute; import org.obeonetwork.dsl.entityrelation.Cardinality; import org.obeonetwork.dsl.entityrelation.Entity; import org.obeonetwork.dsl.entityrelation.EntityRelationFactory; import org.obeonetwork.dsl.entityrelation.EntityRelationPackage; import org.obeonetwork.dsl.entityrelation.Identifier; import org.obeonetwork.dsl.entityrelation.RelationElement; import org.obeonetwork.dsl.entityrelation.impl.RelationImpl; public class RelationSpec extends RelationImpl { @Override public void setSourceCardinality(Cardinality newSourceCardinality) { Cardinality oldSourceCardinality = getSourceCardinality(); // TODO fix this super.setSourceCardinality(newSourceCardinality == null ? Cardinality.ZERO_STAR : newSourceCardinality); if (newSourceCardinality != oldSourceCardinality) { // Cardinality has changed if (oldSourceCardinality.isStarCardinality() == false && newSourceCardinality.isStarCardinality() == true) { // Cardinality was 0.1 or 1..1 and now is 0..* or 1..* // Then the source can not be set as composite setSourceIsComposite(false); // And the other side can not be 0..* or 1..* if (getTargetCardinality() == Cardinality.ZERO_STAR) { setTargetCardinality(Cardinality.ZERO_ONE); } else if (getTargetCardinality() == Cardinality.ONE_STAR) { setTargetCardinality(Cardinality.ONE_ONE); } } else if (oldSourceCardinality.isStarCardinality() == true && newSourceCardinality.isStarCardinality() == false) { // Cardinality was 0.* or 1..* and now is 0..1 or 1..1 // Checks if the identifier is still consistent with the cardinality if (getTargetCardinality().isStarCardinality() == true) { // the previous identifier can not be used anymore setIdentifier(pickBestIdentifier(getTarget())); } } } if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, EntityRelationPackage.RELATION__SOURCE_CARDINALITY, oldSourceCardinality, newSourceCardinality)); } @Override public void setSourceIsComposite(boolean newSourceIsComposite) { if (newSourceIsComposite == true && getSourceCardinality() != Cardinality.ONE_ONE && getSourceCardinality() != Cardinality.ZERO_ONE) { // Only roles with 1 as upper cardinality can be set as composite return; } boolean oldSourceIsComposite = isSourceIsComposite(); super.setSourceIsComposite(newSourceIsComposite); if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, EntityRelationPackage.RELATION__SOURCE_IS_COMPOSITE, oldSourceIsComposite, newSourceIsComposite)); if (newSourceIsComposite == true && isTargetIsComposite() == true) { // Only one role can be set as composite setTargetIsComposite(false); } } @Override public void setTargetCardinality(Cardinality newTargetCardinality) { Cardinality oldTargetCardinality = getTargetCardinality(); // TODO fix this code super.setTargetCardinality(newTargetCardinality == null ? Cardinality.ZERO_ONE : newTargetCardinality); if (newTargetCardinality != oldTargetCardinality) { // Cardinality has changed if (oldTargetCardinality.isStarCardinality() == false && newTargetCardinality.isStarCardinality() == true) { // Cardinality was 0.1 or 1..1 and now is 0..* or 1..* // Then the target can not be set as composite setTargetIsComposite(false); // And the other side can not be 0..* or 1..* if (getSourceCardinality() == Cardinality.ZERO_STAR) { setSourceCardinality(Cardinality.ZERO_ONE); } else if (getSourceCardinality() == Cardinality.ONE_STAR) { setSourceCardinality(Cardinality.ONE_ONE); } } else if (oldTargetCardinality.isStarCardinality() == true && newTargetCardinality.isStarCardinality() == false) { // Cardinality was 0.* or 1..* and now is 0..1 or 1..1 // Checks if the identifier is still consistent with the cardinality if (getSourceCardinality().isStarCardinality() == true) { // the previous identifier can not be used anymore setIdentifier(pickBestIdentifier(getSource())); } } } if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, EntityRelationPackage.RELATION__TARGET_CARDINALITY, oldTargetCardinality, newTargetCardinality)); } @Override public void setTargetIsComposite(boolean newTargetIsComposite) { if (newTargetIsComposite == true && getTargetCardinality() != Cardinality.ONE_ONE && getTargetCardinality() != Cardinality.ZERO_ONE) { // Only roles with 1 as upper cardinality can be set as composite return; } boolean oldTargetIsComposite = isTargetIsComposite(); super.setTargetIsComposite(newTargetIsComposite); if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, EntityRelationPackage.RELATION__TARGET_IS_COMPOSITE, oldTargetIsComposite, newTargetIsComposite)); if (isTargetIsComposite() == true && isSourceIsComposite() == true) { // Only one role can be set as composite setSourceIsComposite(false); } } @Override public void setIdentifier(Identifier newIdentifier) { Identifier oldIdentifier = getIdentifier(); super.setIdentifier(newIdentifier); // We may have to delete and recreate RelationElement instances if ((newIdentifier == null && oldIdentifier != null) || (newIdentifier != null && oldIdentifier == null) || (newIdentifier.equals(oldIdentifier) == false)) { // Delete existing RelationElement instances Collection<RelationElement> relationsElements = new ArrayList<RelationElement>(getElements()); for (RelationElement relationElement : relationsElements) { EcoreUtil.delete(relationElement); } // Create new RelationElement instances if (newIdentifier != null) { if (getSource().equals(newIdentifier.eContainer())) { // Identifier is attached to the source for (Attribute identifierAttribute : newIdentifier.getAttributes()) { Attribute otherAttribute = getOrCreateCorrespondingAttribute(getTarget(), identifierAttribute); RelationElement relationElt = EntityRelationFactory.eINSTANCE.createRelationElement(); relationElt.setSourceAttribute(identifierAttribute); relationElt.setTargetAttribute(otherAttribute); getElements().add(relationElt); } } else if (getTarget().equals(newIdentifier.eContainer())) { // Identifier is attached to the target for (Attribute identifierAttribute : newIdentifier.getAttributes()) { Attribute otherAttribute = getOrCreateCorrespondingAttribute(getSource(), identifierAttribute); RelationElement relationElt = EntityRelationFactory.eINSTANCE.createRelationElement(); relationElt.setSourceAttribute(otherAttribute); relationElt.setTargetAttribute(identifierAttribute); getElements().add(relationElt); } } } } if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, EntityRelationPackage.RELATION__IDENTIFIER, oldIdentifier, newIdentifier)); } private Attribute getOrCreateCorrespondingAttribute(Entity entity, Attribute reference) { if (reference.getName() != null) { for (Attribute attribute : entity.getAttributes()) { if (reference.getName().equalsIgnoreCase(attribute.getName())) { return attribute; } } } if (entity != null) { // No attribute found, we have to create a new one Attribute newAttribute = EntityRelationFactory.eINSTANCE.createAttribute(); entity.getAttributes().add(newAttribute); newAttribute.setName(reference.getName()); newAttribute.setType(EcoreUtil.copy(reference.getType())); return newAttribute; } return null; } private Identifier pickBestIdentifier(Entity entity) { if (entity != null) { if (entity.getPrimaryIdentifier() != null) { return entity.getPrimaryIdentifier(); } if (entity.getIdentifiers().isEmpty() == false) { return entity.getIdentifiers().get(0); } } return null; } }