/***************************************************************************** * Copyright (c) 2010 Atos Origin * * * 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: * Atos Origin - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.commands; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest; /** * This destroy command uses the first generic cross referencer founded instead * of using only the GMF one. This is useful because elements that don't have a * corresponding GMF type (like MOS in the sequence diagram) don't have the GMF * cross referencer registered after a reload. * * @author mvelten * */ public class DestroyElementPapyrusCommand extends DestroyElementCommand { public DestroyElementPapyrusCommand(DestroyElementRequest request) { super(request); getAffectedFiles().addAll(fileOfIncomingReferences(request.getElementToDestroy())); } /** * Compute list of affected files affected by the tear donw methods * @param destructee * @return */ protected List fileOfIncomingReferences(EObject destructee) { if (destructee != null){ Collection<Setting> usages = getUsages(destructee); List<Object> result =new ArrayList<Object>(); for(Setting setting : usages) { EReference eRef = (EReference)setting.getEStructuralFeature(); if(eRef.isChangeable() && (eRef.isDerived() == false) && (eRef.isContainment() == false) && (eRef.isContainer() == false)) { List files = getWorkspaceFiles(setting.getEObject()); if (files != null){ result.addAll(files); } } } return result; } return Collections.emptyList(); } @Override protected void tearDownIncomingReferences(EObject destructee) { Collection<Setting> usages = getUsages(destructee); for(Setting setting : usages) { EReference eRef = (EReference)setting.getEStructuralFeature(); if(eRef.isChangeable() && (eRef.isDerived() == false) && (eRef.isContainment() == false) && (eRef.isContainer() == false)) { EcoreUtil.remove(setting.getEObject(), eRef, destructee); } } } /** * Gets the usages. * * @param source * the source * * @return the usages or null if there is no usages */ public static Collection<Setting> getUsages(EObject source) { if(source == null) { return Collections.emptyList(); } ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(source); if (crossReferencer == null) { // try to register a cross referencer at the highest level crossReferencer = new ECrossReferenceAdapter(); if (source.eResource() != null) { if (source.eResource().getResourceSet() != null) { crossReferencer.setTarget(source.eResource().getResourceSet()); } else { crossReferencer.setTarget(source.eResource()); } } else { crossReferencer.setTarget(source); } } return crossReferencer.getInverseReferences(source, true); } }