| /* |
| * 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.ui; |
| |
| import com.intellij.execution.ExecutionBundle; |
| import com.intellij.execution.JavaExecutionUtil; |
| import com.intellij.execution.configuration.BrowseModuleValueActionListener; |
| import com.intellij.execution.configurations.ConfigurationUtil; |
| import com.intellij.ide.util.ClassFilter; |
| import com.intellij.ide.util.TreeClassChooser; |
| import com.intellij.ide.util.TreeClassChooserFactory; |
| import com.intellij.openapi.application.ReadAction; |
| import com.intellij.openapi.application.Result; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.ex.MessagesEx; |
| import com.intellij.psi.JavaPsiFacade; |
| import com.intellij.psi.PsiClass; |
| import com.intellij.psi.PsiDirectory; |
| import com.intellij.psi.PsiMethod; |
| import com.intellij.psi.search.GlobalSearchScope; |
| import com.intellij.psi.util.PsiMethodUtil; |
| import org.jetbrains.annotations.Nullable; |
| |
| public abstract class ClassBrowser extends BrowseModuleValueActionListener { |
| private final String myTitle; |
| |
| public ClassBrowser(final Project project, final String title) { |
| super(project); |
| myTitle = title; |
| } |
| |
| @Nullable |
| protected String showDialog() { |
| final ClassFilter.ClassFilterWithScope classFilter; |
| try { |
| classFilter = getFilter(); |
| } |
| catch (NoFilterException e) { |
| final MessagesEx.MessageInfo info = e.getMessageInfo(); |
| info.showNow(); |
| return null; |
| } |
| final TreeClassChooser dialog = createClassChooser(classFilter); |
| configureDialog(dialog); |
| dialog.showDialog(); |
| final PsiClass psiClass = dialog.getSelected(); |
| if (psiClass == null) return null; |
| onClassChoosen(psiClass); |
| return JavaExecutionUtil.getRuntimeQualifiedName(psiClass); |
| } |
| |
| protected TreeClassChooser createClassChooser(ClassFilter.ClassFilterWithScope classFilter) { |
| return TreeClassChooserFactory.getInstance(getProject()) |
| .createWithInnerClassesScopeChooser(myTitle, classFilter.getScope(), classFilter, null); |
| } |
| |
| protected abstract ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException; |
| |
| protected void onClassChoosen(final PsiClass psiClass) { |
| } |
| |
| private void configureDialog(final TreeClassChooser dialog) { |
| final String className = getText(); |
| final PsiClass psiClass = findClass(className); |
| if (psiClass == null) return; |
| final PsiDirectory directory = psiClass.getContainingFile().getContainingDirectory(); |
| if (directory != null) dialog.selectDirectory(directory); |
| dialog.select(psiClass); |
| } |
| |
| protected abstract PsiClass findClass(String className); |
| |
| public static ClassBrowser createApplicationClassBrowser(final Project project, |
| final ConfigurationModuleSelector moduleSelector) { |
| final ClassFilter applicationClass = new ClassFilter() { |
| @Override |
| public boolean isAccepted(final PsiClass aClass) { |
| return ConfigurationUtil.MAIN_CLASS.value(aClass) && findMainMethod(aClass) != null; |
| } |
| |
| @Nullable |
| private PsiMethod findMainMethod(final PsiClass aClass) { |
| return new ReadAction<PsiMethod>() { |
| @Override |
| protected void run(Result<PsiMethod> result) throws Throwable { |
| result.setResult(PsiMethodUtil.findMainMethod(aClass)); |
| } |
| }.execute().getResultObject(); |
| } |
| }; |
| return new MainClassBrowser(project, moduleSelector, ExecutionBundle.message("choose.main.class.dialog.title")) { |
| @Override |
| protected ClassFilter createFilter(final Module module) { |
| return applicationClass; |
| } |
| }; |
| } |
| |
| public static ClassBrowser createAppletClassBrowser(final Project project, |
| final ConfigurationModuleSelector moduleSelector) { |
| final String title = ExecutionBundle.message("choose.applet.class.dialog.title"); |
| return new MainClassBrowser(project, moduleSelector, title) { |
| |
| @Override |
| protected TreeClassChooser createClassChooser(ClassFilter.ClassFilterWithScope classFilter) { |
| final Module module = moduleSelector.getModule(); |
| final GlobalSearchScope scope = |
| module == null ? GlobalSearchScope.allScope(myProject) : GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module); |
| final PsiClass appletClass = JavaPsiFacade.getInstance(project).findClass("java.applet.Applet", scope); |
| return TreeClassChooserFactory.getInstance(getProject()) |
| .createInheritanceClassChooser(title, classFilter.getScope(), appletClass, false, false, |
| ConfigurationUtil.PUBLIC_INSTANTIATABLE_CLASS); |
| } |
| }; |
| } |
| |
| private abstract static class MainClassBrowser extends ClassBrowser { |
| protected final Project myProject; |
| private final ConfigurationModuleSelector myModuleSelector; |
| |
| public MainClassBrowser(final Project project, |
| final ConfigurationModuleSelector moduleSelector, |
| final String title) { |
| super(project, title); |
| myProject = project; |
| myModuleSelector = moduleSelector; |
| } |
| |
| protected PsiClass findClass(final String className) { |
| return myModuleSelector.findClass(className); |
| } |
| |
| protected ClassFilter.ClassFilterWithScope getFilter() throws NoFilterException { |
| final Module module = myModuleSelector.getModule(); |
| final GlobalSearchScope scope; |
| if (module == null) { |
| scope = GlobalSearchScope.allScope(myProject); |
| } |
| else { |
| scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module); |
| } |
| final ClassFilter filter = createFilter(module); |
| return new ClassFilter.ClassFilterWithScope() { |
| public GlobalSearchScope getScope() { |
| return scope; |
| } |
| |
| public boolean isAccepted(final PsiClass aClass) { |
| return filter == null || filter.isAccepted(aClass); |
| } |
| }; |
| } |
| |
| protected ClassFilter createFilter(final Module module) { |
| return null; |
| } |
| } |
| |
| public static class NoFilterException extends Exception { |
| private final MessagesEx.MessageInfo myMessageInfo; |
| |
| public NoFilterException(final MessagesEx.MessageInfo messageInfo) { |
| super(messageInfo.getMessage()); |
| myMessageInfo = messageInfo; |
| } |
| |
| public MessagesEx.MessageInfo getMessageInfo() { |
| return myMessageInfo; |
| } |
| |
| public static NoFilterException noJUnitInModule(final Module module) { |
| return new NoFilterException(new MessagesEx.MessageInfo( |
| module.getProject(), |
| ExecutionBundle.message("junit.not.found.in.module.error.message", module.getName()), |
| ExecutionBundle.message("cannot.browse.test.inheritors.dialog.title"))); |
| } |
| |
| public static NoFilterException moduleDoesntExist(final ConfigurationModuleSelector moduleSelector) { |
| final Project project = moduleSelector.getProject(); |
| final String moduleName = moduleSelector.getModuleName(); |
| return new NoFilterException(new MessagesEx.MessageInfo( |
| project, |
| moduleName.isEmpty() ? "No module selected" : ExecutionBundle.message("module.does.not.exists", moduleName, project.getName()), |
| ExecutionBundle.message("cannot.browse.test.inheritors.dialog.title"))); |
| } |
| } |
| } |