/* license-start
*
* Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
*
* Contributors:
* Crispico - Initial API and implementation
*
* license-end
*/
package org.flowerplatform.codesync.processor;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.ChangeKind;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.ListChange;
import org.flowerplatform.codesync.remote.CodeSyncDiagramOperationsService;
import org.flowerplatform.editor.model.change_processor.IDiagrammableElementFeatureChangesProcessor;
import org.flowerplatform.editor.model.remote.DiagramEditorStatefulService;
import org.flowerplatform.emf_model.notation.Diagram;
import org.flowerplatform.emf_model.notation.Edge;
import org.flowerplatform.emf_model.notation.View;
import com.crispico.flower.mp.model.codesync.CodeSyncElement;
import com.crispico.flower.mp.model.codesync.CodeSyncPackage;
import com.crispico.flower.mp.model.codesync.Relation;
/**
* Processes changes in the relations containment feature; adds/removes edge views.
*
* @author Mariana Gheorghe
*/
public class CodeSyncElementRelationsChangesProcessor implements IDiagrammableElementFeatureChangesProcessor {
@Override
public void processFeatureChanges(EObject object, List<FeatureChange> featureChanges, View associatedViewOnOpenDiagram, Map<String, Object> context) {
if (featureChanges == null) {
// new element added to diagram; do not add new edges for existing relations if this is the first time the diagram was open
Boolean isInitialContent = (Boolean) context.get(DiagramEditorStatefulService.ADDITIONAL_DATA_INITIAL_FULL_CONTENT);
if (isInitialContent == null || !isInitialContent) {
getService().addEdgesForRelations(object, ((CodeSyncElement) object).getRelations(), associatedViewOnOpenDiagram, false, context);
getService().addEdgesForRelationsWithTarget(object, getService().getViewsForElement((CodeSyncElement) object), false, context);
}
} else {
for (FeatureChange featureChange : featureChanges) {
if (CodeSyncPackage.eINSTANCE.getCodeSyncElement_Relations().equals(featureChange.getFeature())) {
processRelationsChanges(object, featureChange, associatedViewOnOpenDiagram, context);
}
}
}
}
protected void processRelationsChanges(EObject object, FeatureChange featureChange, View associatedViewOnOpenDiagram, Map<String, Object> context) {
if (featureChange.getListChanges().isEmpty()) {
getService().addEdgesForRelations(object, ((CodeSyncElement) object).getRelations(), associatedViewOnOpenDiagram, false, context);
} else {
for (ListChange listChange : featureChange.getListChanges()) {
if (listChange.getKind().equals(ChangeKind.ADD_LITERAL)) {
// removed a relation
// removeEdgesForRelations(object, listChange.getValues(), associatedViewOnOpenDiagram, context);
} else {
if (listChange.getKind().equals(ChangeKind.REMOVE_LITERAL)) {
// send the full list of relations for now, because we've noticed an issue with the indexes from the listChange
getService().addEdgesForRelations(object, ((CodeSyncElement) object).getRelations(), associatedViewOnOpenDiagram, false, context);
}
}
}
}
}
/**
* Removes all {@link Edge}s for the deleted {@link Relation}s.
*/
protected void removeEdgesForRelations(EObject object, EList<Object> relations, View associatedViewOnOpenDiagram, Map<String, Object> context) {
Diagram diagram = getService().getDiagram(context);
for (Object relation : relations) {
for (View target : getService().getViewsForElement(((Relation) relation).getTarget())) {
Edge edge = getService().getEdge(associatedViewOnOpenDiagram, target);
if (edge != null) {
associatedViewOnOpenDiagram.getSourceEdges().remove(edge);
target.getTargetEdges().remove(edge);
diagram.getPersistentEdges().remove(edge);
}
}
}
}
private CodeSyncDiagramOperationsService getService() {
return CodeSyncDiagramOperationsService.getInstance();
}
}