blob: 827dbbf736ce0b64b3f157e450aff7239c3d2456 [file] [log] [blame]
/*
* 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")));
}
}
}