/******************************************************************************* * 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.ArrayList; import java.util.Collection; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.grails.ide.eclipse.core.GrailsCoreActivator; import org.grails.ide.eclipse.editor.groovy.elements.GrailsWorkspaceCore; import org.grails.ide.eclipse.editor.groovy.elements.IGrailsElement; /** * Abstraction to encapsulate the method to compute extra renamings for a given renaming. * * @author Kris De Volder * @since 2.7 */ public abstract class ExtraRenamingsComputer { final public static boolean DEBUG = false; void debug(String string) { if (DEBUG) { System.out.println(this.getClass().getSimpleName()+": " +string); } } private final ITypeRenaming org; private final IJavaProject javaProject; private Collection<ITypeRenaming> extra = null; private ArrayList<ITypeRenaming> result; public ExtraRenamingsComputer(ITypeRenaming org) { Assert.isNotNull(org); this.org = org; this.javaProject = org.getTarget().getJavaProject(); } protected IJavaProject getJavaProject() { return javaProject; } /** * This method should be called before using the extra renamings computer. It may * return an error / warning etc. status if, for some reason the original renaming * violates a naming convention. */ public RefactoringStatus checkPreconditions() { return new RefactoringStatus(); } /** * Create appropriate renamings computer based on the original renaming. * @return An applicable {@link ExtraRenamingsComputer} or null (if not applicable). */ public static ExtraRenamingsComputer create(ITypeRenaming org) { IType target = org.getTarget(); IGrailsElement element = GrailsWorkspaceCore.get().create(target); if (element!=null) { return new PostfixedClassExtraRenamingsComputer(org, "ControllerTests", "ControllerTest", "Controller", "ServiceTests", "ServiceTest", "Service", "TagLibTests", "TagLibTest", "TagLib", "Tests", "Test", "" ); } return null; } public ITypeRenaming getOrginalRenaming() { return org; } public Collection<ITypeRenaming> getExtraRenamings(IProgressMonitor pm) { if (this.extra==null) { this.extra = computeExtraRenamings(pm); Assert.isNotNull(this.extra, "ExtraRenamingsComputer.computeExtraRenamings must not return null"); } return this.extra; } protected String simpleName(String fqBaseName) { int split = fqBaseName.lastIndexOf('.'); if (split>=0) { return fqBaseName.substring(split+1); } return fqBaseName; } protected String packageName(String fqBaseName) { int split = fqBaseName.lastIndexOf('.'); if (split>=0) { return fqBaseName.substring(0,split); } return ""; } protected Collection<ITypeRenaming> computeExtraRenamings(IProgressMonitor pm) { if (result==null) { result = new ArrayList<ITypeRenaming>(); computeDefaultRenamings(getPackageName(), getBaseName(), getNewBaseName()); } return result; } protected abstract String getBaseName(); protected abstract String getNewBaseName(); protected void computeDefaultRenamings(String pkgName, String domainClassName, String newDomainClassName) { if (domainClassName==null || newDomainClassName==null) { return; // without base names to generate the naming patterns we can't do anything, so no extra renamings are generated } debug("Computing additional renamings for '"+pkgName+"."+domainClassName+"' => '"+newDomainClassName+"'"); renamingCandidate(pkgName, domainClassName, newDomainClassName); renamingCandidate(pkgName, domainClassName + "Controller", newDomainClassName+"Controller"); renamingCandidate(pkgName, domainClassName + "TagLib", newDomainClassName+"TagLib" ); renamingCandidate(pkgName, domainClassName + "Service", newDomainClassName+"Service" ); } protected String getOrgFullyQualifiedName() { return getOrginalRenaming().getTarget().getFullyQualifiedName('.'); } private String getPackageName() { return packageName(getOrgFullyQualifiedName()); } /** * Add an extra renaming candidate to the list of results if it is a reasonable * candidate. Some checks are performed to determine whether a candidate is reasonable. * <p> * This will also automatically add derived "XXXTest" and "XXXTests" candidates. */ protected void renamingCandidate(String pkgName, String targetName, String newName) { boolean isTest = targetName.endsWith("Test") || targetName.endsWith("Tests"); if (!isTest) { renamingCandidate(pkgName, targetName+"Test", newName+"Test"); renamingCandidate(pkgName, targetName+"Tests", newName+"Tests"); } String fqTargetName = pkgName+"."+targetName; String orgFqName = getOrgFullyQualifiedName(); if (orgFqName.equals(fqTargetName)) { return; //Skip if the name is the same as the original renaming that triggered the additional renamings } try { IJavaProject javaProject = getJavaProject(); IType targetType = javaProject.findType(fqTargetName); if (targetType!=null) { result.add(new TypeRenaming(targetType, newName)); } } catch (JavaModelException e) { GrailsCoreActivator.log(e); } } }