/*******************************************************************************
* 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.type;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.grails.ide.eclipse.core.GrailsCoreActivator;
import org.grails.ide.eclipse.core.internal.plugins.GrailsElementKind;
import org.grails.ide.eclipse.core.util.GrailsNameUtils;
import org.grails.ide.eclipse.editor.groovy.elements.GrailsProject;
import org.grails.ide.eclipse.editor.groovy.elements.GrailsWorkspaceCore;
import org.grails.ide.eclipse.editor.groovy.elements.IGrailsElement;
import org.grails.ide.eclipse.editor.gsp.search.IGSPSearchRequestor;
import org.grails.ide.eclipse.editor.gsp.search.SearchInGSPs;
import org.grails.ide.eclipse.refactoring.rename.ParticipantChangeManager;
/**
* @author Kris De Volder
* @since 2.7
*/
public class GSPUpdater extends ExtraChangeComputer {
/**
* @author Kris De Volder
* @since 2.7
*/
private class GSPSearchRequestor implements IGSPSearchRequestor {
private ParticipantChangeManager changes;
private int nameLen = renaming.getTarget().getElementName().length();
public GSPSearchRequestor(ParticipantChangeManager changes) {
this.changes = changes;
}
public boolean searchForTags() {
return false;
}
public void acceptMatch(IFile file, int start, int length) {
if (start>=0) {
TextFileChange newChange = new TextFileChange("gsp reference change", file);
MultiTextEdit edits = new MultiTextEdit();
edits.addChild(new ReplaceEdit(start+length-nameLen, nameLen, renaming.getNewName()));
newChange.setEdit(edits);
// try {
changes.add(newChange);
// } catch (MalformedTreeException e) {
// // Ignore... this happens because the GSP search sometimes returns overlapping references
// // where one is qualified name and the other is unqualified
// }
}
}
public int limitTo() {
return IJavaSearchConstants.REFERENCES | IJavaSearchConstants.ALL_OCCURRENCES;
}
public IJavaElement elementToSearchFor() {
return renaming.getTarget();
}
public List<IFile> getGSPsToSearch() {
return project.getGSPFiles();
}
}
private static final boolean DEBUG = false;
private static void debug(String msg) {
if (DEBUG) {
System.out.println(msg);
}
}
private SearchInGSPs gspSearch = new SearchInGSPs();
@Override
public boolean initialize(GrailsProject project, ITypeRenaming renaming) {
return super.initialize(project, renaming);
}
@Override
protected void createChanges(ParticipantChangeManager changes, final RefactoringStatus status, IProgressMonitor pm) {
Assert.isNotNull(changes);
IType target = renaming.getTarget();
IGrailsElement elem = GrailsWorkspaceCore.get().create(target);
if (elem!=null) {
if (elem.getKind()==GrailsElementKind.CONTROLLER_CLASS) {
renameViewsFolder(changes, target);
}
}
updateReferencesInGSPFiles(changes, status, pm);
}
private void updateReferencesInGSPFiles(ParticipantChangeManager changes, RefactoringStatus status, IProgressMonitor pm) {
try {
gspSearch.performSearch(new GSPSearchRequestor(changes), pm);
} catch (CoreException e) {
status.addError("Unexpected error updating references in GSPs, see error log for details");
GrailsCoreActivator.log(e);
}
}
private void renameViewsFolder(ParticipantChangeManager changes,
IType target) {
IFolder viewsFolder = project.getViewsFolder();
if (viewsFolder.exists()) {
IFolder domainViewFolder = viewsFolder.getFolder(viewsFolderNameFor(target));
if (domainViewFolder.exists()) {
String newName = viewsFolderNameFor(renaming.getNewName());
debug("This folder should be renamed: "+domainViewFolder+" => "+newName);
changes.add(new RenameResourceChange(domainViewFolder.getFullPath(), newName));
}
}
}
private String viewsFolderNameFor(IType target) {
String controllerName = target.getElementName();
return viewsFolderNameFor(controllerName);
}
private String viewsFolderNameFor(String controllerName) {
return GrailsNameUtils.getPropertyName(GrailsNameUtils.getLogicalName(controllerName, "Controller"));
}
}