/** * 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.refactoring.refactor.impl; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.EcoreUtil2; import org.yakindu.base.base.NamedElement; import org.yakindu.base.expressions.expressions.ElementReferenceExpression; import org.yakindu.base.expressions.expressions.FeatureCall; import org.yakindu.sct.model.sgraph.SpecificationElement; import org.yakindu.sct.model.sgraph.resource.AbstractSCTResource; import org.yakindu.sct.refactoring.refactor.AbstractRefactoring; import com.google.common.collect.Sets; /** * Renames the context object and all references to it. * <br><br> * Context: * <ul> * <li>A {@link NamedElement}.</li> * </ul> * Preconditions: * <ul> * <li>None.</li> * </ul> * * @author thomas kutz - Initial contribution and API * */ public class RenameRefactoring extends AbstractRefactoring<NamedElement> { String newName; public void setNewName(String newName) { this.newName = newName; } @Override public void setContextObjects(List<NamedElement> contextObject) { this.newName = null; super.setContextObjects(contextObject); } @Override public boolean isExecutable() { return (getContextObject() != null); } @Override protected void internalExecute() { NamedElement element = getContextObject(); Collection<EObject> elementReferers = findReferers(element); element.setName(newName); AbstractSCTResource res = (AbstractSCTResource) getResource(); Set<SpecificationElement> specificationsToParse = Sets.newHashSet(); for (EObject referer : elementReferers) { if (referer instanceof FeatureCall) { FeatureCall featureCall = (FeatureCall) referer; featureCall.setFeature(element); SpecificationElement spec = EcoreUtil2.getContainerOfType( referer, SpecificationElement.class); specificationsToParse.add(spec); } else if (referer instanceof ElementReferenceExpression) { ElementReferenceExpression expr = (ElementReferenceExpression) referer; expr.setReference(element); SpecificationElement spec = EcoreUtil2.getContainerOfType( referer, SpecificationElement.class); specificationsToParse.add(spec); } } // TODO parsing is an workaround here for linking problem for (SpecificationElement spec : specificationsToParse) { res.parseSpecificationElement(spec); } } private Collection<EObject> findReferers(EObject referedElement) { Collection<EObject> result = new HashSet<EObject>(); Resource res = getResource(); EList<EObject> contents = res.getContents(); result = searchForReferers(referedElement, contents); return result; } private Collection<EObject> searchForReferers(EObject referedElement, EList<EObject> contents) { Collection<EObject> result = new HashSet<EObject>(); for (EObject content : contents) { for (EObject crossRef : content.eCrossReferences()) { if (crossRef.eIsProxy()) { crossRef = EcoreUtil.resolve(crossRef, content); } if (EcoreUtil.equals(crossRef, referedElement)) { result.add(content); } } result.addAll(searchForReferers(referedElement, content.eContents())); } return result; } @Override protected Resource getResource() { return getContextObject().eResource(); } }