/* 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.editor.model.change_processor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.change.ChangeKind;
import org.eclipse.emf.ecore.change.FeatureChange;
import org.eclipse.emf.ecore.change.ListChange;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.flowerplatform.emf_model.notation.View;
/**
* @author Mariana Gheorghe
*/
public class AbstractFeatureChangesProcessor implements IDiagrammableElementFeatureChangesProcessor {
protected List<DependentFeature> dependentFeatures = new ArrayList<DependentFeature>();
public List<DependentFeature> getDependentFeatures() {
return dependentFeatures;
}
@Override
public void processFeatureChanges(EObject object, List<FeatureChange> featureChanges,
View associatedViewOnOpenDiagram, Map<String, Object> context) {
if (featureChanges == null) {
// full content
} else {
for (FeatureChange featureChange : featureChanges) {
if (!featureChange.getListChanges().isEmpty()) {
for (ListChange listChange : featureChange.getListChanges()) {
if (listChange.getKind().equals(ChangeKind.ADD_LITERAL)) {
// delete event
for (Object deletedChild : listChange.getValues()) {
onDelete(object, featureChange.getFeature(), (EObject) deletedChild);
}
}
}
}
}
}
}
protected void onDelete(EObject parent, EStructuralFeature childrenFeature, EObject deletedChild) {
for (DependentFeature dependentFeature : dependentFeatures) {
if (dependentFeature.getKey().isAssignableFrom(deletedChild.getClass())) {
onDeleteElementRemoveInverseReferences((EObject) deletedChild, dependentFeature.getFeature());
}
}
// recurse for contents
for (Iterator it = deletedChild.eAllContents(); it.hasNext();) {
EObject object = (EObject) it.next();
onDelete(deletedChild, object.eContainingFeature(), object);
}
}
protected void onDeleteElementRemoveInverseReferences(EObject element, EStructuralFeature feature) {
ECrossReferenceAdapter adapter = ECrossReferenceAdapter.getCrossReferenceAdapter(element);
for (Setting setting : adapter.getNonNavigableInverseReferences(element)) {
if (feature.equals(setting.getEStructuralFeature())) {
EObject reference = setting.getEObject();
removeFromContainer(reference);
}
}
}
private void removeFromContainer(EObject object) {
EStructuralFeature containingFeature = object.eContainingFeature();
EObject container = object.eContainer();
if (container != null) {
if (containingFeature.isMany()) {
((List<EObject>) container.eGet(containingFeature)).remove(object);
} else {
container.eUnset(containingFeature);
}
// recurse (because the change description may not be processed for this operation)
onDelete(container, containingFeature, object);
}
}
}