/** * Copyright (c) 2013 committers of YAKINDU and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * Contributors: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.compare.postprocessor; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.DifferenceKind; import org.eclipse.emf.compare.ReferenceChange; import org.eclipse.emf.compare.diagram.internal.extensions.EdgeChange; import org.eclipse.emf.compare.postprocessor.IPostProcessor; import org.yakindu.sct.model.sgraph.SGraphPackage; /** * Postprocessor for adjusting dependencies between {@link EdgeChange} diffs and * {@link ReferenceChange}s for incoming/outgoing transitions. * * @author thomas kutz - Initial contribution * */ @SuppressWarnings("restriction") public class EdgeChangePostProcessor implements IPostProcessor { public EdgeChangePostProcessor() { // TODO Auto-generated constructor stub } @Override public void postMatch(Comparison comparison, Monitor monitor) { } @Override public void postDiff(Comparison comparison, Monitor monitor) { } @Override public void postRequirements(Comparison comparison, Monitor monitor) { } @Override public void postEquivalences(Comparison comparison, Monitor monitor) { } @Override public void postConflicts(Comparison comparison, Monitor monitor) { } @Override public void postComparison(Comparison comparison, Monitor monitor) { for (Diff diff : comparison.getDifferences()) { if (diff instanceof EdgeChange) { EdgeChange edgeChange = (EdgeChange) diff; switch (edgeChange.getKind()) { case ADD: postProcessEdgeAddition(edgeChange); break; case DELETE: postProcessEdgeDeletion(edgeChange); break; default: // do nothing } } } } /** * In this case by default following dependencies are created:<br> * <br> * EdgeDeletion --requires-> OutgoingTransitionDeletion <-requires-- * IncomingTransitionDeletion<br> * <br> * Needs to be changed into:<br> * <br> * EdgeDeletion --requires-> IncomingTransitionDeletion --requires-> * OutgoingTransitionDeletion<br> * * @param edgeChange */ private void postProcessEdgeAddition(EdgeChange edgeChange) { Set<Diff> requiredIncomingTransitionAdditions = new HashSet<Diff>(); for (Diff requireds : edgeChange.getRequires()) { if (requireds instanceof ReferenceChange) { ReferenceChange requiredRefChange = (ReferenceChange) requireds; // for required changes in outgoing transition refs we also need // to add the corresponding change in incoming transition refs if (requiredRefChange.getReference() == SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS && requiredRefChange.getKind() == DifferenceKind.ADD) { requiredIncomingTransitionAdditions .addAll(findRequiredIncomingTransitionRefChange( requiredRefChange, DifferenceKind.ADD)); } } } edgeChange.getRequires().addAll(requiredIncomingTransitionAdditions); } private Collection<Diff> findRequiredIncomingTransitionRefChange( ReferenceChange requiredRefChange, DifferenceKind changeKind) { for (Diff requiredBy : requiredRefChange.getRequiredBy()) { if (requiredBy instanceof ReferenceChange) { ReferenceChange requiredByRefChange = (ReferenceChange) requiredBy; if (requiredByRefChange.getReference() == SGraphPackage.Literals.VERTEX__INCOMING_TRANSITIONS && requiredByRefChange.getKind() == changeKind) { return Collections .<Diff> singletonList(requiredByRefChange); // FIXME: // collect // all // and // return // set? // Are // there // cases // where // more // than // one // should // be // returned? } } } return Collections.emptyList(); } /** * In this case by default following dependencies are created:<br> * <br> * EdgeDeletion <-requires-- OutgoingTransitionDeletion --requires-> * IncomingTransitionDeletion<br> * <br> * Needs to be changed into:<br> * <br> * EdgeDeletion --requires-> OutgoingTransitionDeletion --requires-> * IncomingTransitionDeletion<br> * * @param edgeChange */ private void postProcessEdgeDeletion(EdgeChange edgeChange) { Set<Diff> requiredOutgoingTransitionDeletions = new HashSet<Diff>(); for (Diff requireds : edgeChange.getRequiredBy()) { if (requireds instanceof ReferenceChange) { ReferenceChange requiredRefChange = (ReferenceChange) requireds; // for required changes in outgoing transition refs we also need // to add the corresponding change in incoming transition refs if (requiredRefChange.getReference() == SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS && requiredRefChange.getKind() == DifferenceKind.DELETE) { requiredOutgoingTransitionDeletions.add(requiredRefChange); } } } edgeChange.getRequires().addAll(requiredOutgoingTransitionDeletions); } }