| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.execution.junit; |
| |
| import com.intellij.execution.JavaExecutionUtil; |
| import com.intellij.execution.SingleClassConfiguration; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.psi.*; |
| import com.intellij.psi.search.GlobalSearchScope; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import com.intellij.refactoring.listeners.RefactoringElementAdapter; |
| import com.intellij.refactoring.listeners.RefactoringElementListener; |
| import com.intellij.refactoring.listeners.UndoRefactoringElementListener; |
| import org.jetbrains.annotations.NotNull; |
| |
| public class RefactoringListeners { |
| public static RefactoringElementListener getListener(final PsiPackage psiPackage, final Accessor<PsiPackage> accessor) { |
| final StringBuilder path = new StringBuilder(); |
| for (PsiPackage parent = accessor.getPsiElement(); parent != null; parent = parent.getParentPackage()) { |
| if (parent.equals(psiPackage)) return new RefactorPackage(accessor, path.toString()); |
| if (path.length() > 0) path.insert(0, '.'); |
| path.insert(0, parent.getName()); |
| } |
| return null; |
| } |
| |
| public static RefactoringElementListener getListeners(final PsiClass psiClass, final Accessor<PsiClass> accessor) { |
| final PsiClass aClass = accessor.getPsiElement(); |
| if (aClass == null) return null; |
| final StringBuilder path = new StringBuilder(); |
| for (PsiClass parent = aClass; parent != null; parent = PsiTreeUtil.getParentOfType(parent, PsiClass.class, true)) { |
| if (parent.equals(psiClass)) return new RefactorClass(accessor, path.toString()); |
| if (path.length() > 0) path.insert(0, '$'); |
| path.insert(0, parent.getName()); |
| } |
| return null; |
| } |
| |
| public static RefactoringElementListener getClassOrPackageListener(final PsiElement element, final Accessor<PsiClass> accessor) { |
| if (element instanceof PsiClass) return getListeners((PsiClass)element, accessor); |
| if (element instanceof PsiPackage) { |
| final PsiClass aClass = accessor.getPsiElement(); |
| if (aClass == null) return null; |
| return getListener((PsiPackage)element, new ClassPackageAccessor(accessor)); |
| } |
| return null; |
| |
| } |
| |
| public interface Accessor<T extends PsiElement> { |
| void setName(String qualifiedName); |
| T getPsiElement(); |
| void setPsiElement(T psiElement); |
| } |
| |
| public static class SingleClassConfigurationAccessor implements Accessor<PsiClass> { |
| private final SingleClassConfiguration myConfiguration; |
| |
| public SingleClassConfigurationAccessor(final SingleClassConfiguration configuration) { |
| myConfiguration = configuration; |
| } |
| |
| public PsiClass getPsiElement() { |
| return myConfiguration.getMainClass(); |
| } |
| |
| public void setPsiElement(final PsiClass psiClass) { |
| myConfiguration.setMainClass(psiClass); |
| } |
| |
| public void setName(final String qualifiedName) { |
| myConfiguration.setMainClassName(qualifiedName); |
| } |
| } |
| |
| private static abstract class RenameElement<T extends PsiElement> extends RefactoringElementAdapter |
| implements UndoRefactoringElementListener{ |
| private final Accessor<T> myAccessor; |
| private final String myPath; |
| |
| public RenameElement(final Accessor<T> accessor, final String path) { |
| myAccessor = accessor; |
| myPath = path; |
| } |
| |
| public void elementRenamedOrMoved(@NotNull final PsiElement newElement) { |
| T newElement1 = (T)newElement; |
| String qualifiedName = getQualifiedName(newElement1); |
| if (myPath.length() > 0) { |
| qualifiedName = qualifiedName + "." + myPath; |
| newElement1 = findNewElement(newElement1, qualifiedName); |
| } |
| if (newElement1 != null) { |
| myAccessor.setPsiElement(newElement1); |
| } |
| else { |
| myAccessor.setName(qualifiedName); |
| } |
| } |
| |
| protected abstract T findNewElement(T newParent, String qualifiedName); |
| |
| protected abstract String getQualifiedName(T element); |
| |
| @Override |
| public void undoElementMovedOrRenamed(@NotNull PsiElement newElement, @NotNull String oldQualifiedName) { |
| myAccessor.setName(oldQualifiedName); |
| } |
| } |
| |
| private static class RefactorPackage extends RenameElement<PsiPackage> { |
| public RefactorPackage(final Accessor<PsiPackage> accessor, final String path) { |
| super(accessor, path); |
| } |
| |
| public PsiPackage findNewElement(final PsiPackage psiPackage, final String qualifiedName) { |
| return JavaPsiFacade.getInstance(psiPackage.getProject()).findPackage(qualifiedName); |
| } |
| |
| public String getQualifiedName(final PsiPackage psiPackage) { |
| return psiPackage.getQualifiedName(); |
| } |
| } |
| |
| private static class RefactorClass extends RenameElement<PsiClass> { |
| public RefactorClass(final Accessor<PsiClass> accessor, final String path) { |
| super(accessor, path); |
| } |
| |
| public PsiClass findNewElement(final PsiClass psiClass, final String qualifiedName) { |
| return JavaPsiFacade.getInstance(psiClass.getProject()) |
| .findClass(qualifiedName.replace('$', '.'), GlobalSearchScope.moduleScope(JavaExecutionUtil.findModule(psiClass))); |
| } |
| |
| public String getQualifiedName(final PsiClass psiClass) { |
| return psiClass.getQualifiedName(); |
| } |
| } |
| |
| private static class ClassPackageAccessor implements RefactoringListeners.Accessor<PsiPackage> { |
| private final PsiPackage myContainingPackage; |
| private final Module myModule; |
| private final RefactoringListeners.Accessor<PsiClass> myAccessor; |
| private final String myInpackageName; |
| |
| public ClassPackageAccessor(final RefactoringListeners.Accessor<PsiClass> accessor) { |
| myAccessor = accessor; |
| PsiClass aClass = myAccessor.getPsiElement(); |
| aClass = (PsiClass)aClass.getOriginalElement(); |
| myContainingPackage = JavaDirectoryService.getInstance().getPackage(aClass.getContainingFile().getContainingDirectory()); |
| myModule = JavaExecutionUtil.findModule(aClass); |
| final String classQName = aClass.getQualifiedName(); |
| final String classPackageQName = myContainingPackage.getQualifiedName(); |
| if (classQName.startsWith(classPackageQName)) { |
| final String inpackageName = classQName.substring(classPackageQName.length()); |
| if (StringUtil.startsWithChar(inpackageName, '.')) { |
| myInpackageName = inpackageName.substring(1); |
| } |
| else { |
| myInpackageName = inpackageName; |
| } |
| } |
| else { |
| myInpackageName = null; |
| } |
| } |
| |
| public PsiPackage getPsiElement() { |
| return myContainingPackage; |
| } |
| |
| public void setPsiElement(final PsiPackage psiPackage) { |
| if (myInpackageName == null) return; //we can do nothing |
| final String classQName = getClassQName(psiPackage.getQualifiedName()); |
| final PsiClass newClass = JUnitUtil.findPsiClass(classQName, myModule, psiPackage.getProject()); |
| if (newClass != null) { |
| myAccessor.setPsiElement(newClass); |
| } |
| else { |
| myAccessor.setName(classQName); |
| } |
| } |
| |
| public void setName(final String qualifiedName) { |
| myAccessor.setName(getClassQName(qualifiedName)); |
| } |
| |
| private String getClassQName(final String packageQName) { |
| if (packageQName.length() > 0) { |
| return packageQName + '.' + myInpackageName; |
| } |
| else { |
| return myInpackageName; |
| } |
| } |
| } |
| } |