/******************************************************************************* * Copyright (c) 2012 VMWare, Inc. * 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: * VMWare, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.refactoring.rename.action; import java.util.ArrayList; import java.util.Collection; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.search.ISearchRequestor; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextChange; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; import org.eclipse.search.ui.text.Match; import org.eclipse.text.edits.ReplaceEdit; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.core.util.GrailsNameUtils; import org.grails.ide.eclipse.editor.groovy.elements.ControllerClass; import org.grails.ide.eclipse.editor.groovy.elements.GrailsProject; import org.grails.ide.eclipse.editor.groovy.elements.GrailsWorkspaceCore; import org.grails.ide.eclipse.refactoring.rename.ParticipantChangeManager; import org.grails.ide.eclipse.search.action.ControllerActionSearch; /** * @author Kris De Volder * * @since 2.8 */ public abstract class GrailsActionOrViewRenameParticipant extends RenameParticipant { public interface IActionRequestor { void add(IMember action); } protected ParticipantChangeManager changes = new ParticipantChangeManager(this); private IProject project; private GrailsProject grailsProject; private String oldActionName; private String newActionName; private String targetControllerClassName; private String targetControllerName; /** * It is assumed that this method precomputes all the changes and adds them to the {@link ParticipantChangeManager} */ @Override public abstract RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context); @Override public Change createPreChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { changes.copyExistingChangesTo(this); return changes.getNewTextChanges(); } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { return changes.getOtherChanges(); } /** * Rewrites references to 'actions' but only making those changes that the ordinary JDT rename method or field refactoring * would not automatically perform by itself. */ protected void rewriteActionReferences(RefactoringStatus status) { try { ControllerActionSearch search = new ControllerActionSearch(getGrailsProject(), targetControllerClassName, oldActionName); search.perform(new ISearchRequestor() { public void reportMatch(Match match) { Object el = match.getElement(); TextChange txtChange = changes.getTextChangeFor(el); if (txtChange!=null) { if (match.getLength()==oldActionName.length()) { //only perform edit if assumption holds final ReplaceEdit edit = new ReplaceEdit(match.getOffset(), oldActionName.length(), newActionName); txtChange.addEdit(edit); } } } }); } catch (JavaModelException e) { GrailsCoreActivator.log(e); status.addFatalError(e.getMessage()); } } public String getNewActionName() { return newActionName; } public void setNewActionName(String newActionName) { this.newActionName = newActionName; } public String getOldActionName() { return oldActionName; } public void setOldActionName(String oldActionName) { this.oldActionName = oldActionName; } public void setTargetControllerClassName(String targetControllerClassName) { this.targetControllerClassName = targetControllerClassName; this.targetControllerName = GrailsNameUtils.getLogicalPropertyName(targetControllerClassName, "Controller"); } public String getTargetControllerName() { return targetControllerName; } public void setTargetControllerName(String targetControllerName) { this.targetControllerName = targetControllerName; this.targetControllerClassName = GrailsNameUtils.getClassName(targetControllerName, "Controller"); } public ControllerClass getTargetController() { return getGrailsProject().getControllerClass(getTargetControllerClassName()); } public String getTargetControllerClassName() { return targetControllerClassName; } public IProject getProject() { return project; } public void setProject(IProject project) { this.project = project; } protected GrailsProject getGrailsProject() { if (this.grailsProject==null) { this.grailsProject = GrailsWorkspaceCore.get().create(project); } return this.grailsProject; } public static Collection<? extends IMember> getActions(IType controllerClass, String actionName) throws JavaModelException { Assert.isNotNull(controllerClass); ArrayList<IMember> actions = new ArrayList<IMember>(); IField field = controllerClass.getField(actionName); if (field.exists()) { actions.add(field); } collectMethodActions(controllerClass, actionName, actions); return actions; } public static Collection<? extends IMember> getActions(ControllerClass controllerClass, String actionName) throws JavaModelException { IType type = controllerClass.getType(); if (type!=null) { return getActions(controllerClass.getType(), actionName); } else { return new ArrayList<IMember>(); } } private static void collectMethodActions(IType controllerClass, String actionName, ArrayList<IMember> actions) throws JavaModelException { for (IMethod m : controllerClass.getMethods()) { if (m.getElementName().equals(actionName)) { actions.add(m); } } } }