com.intellij.testIntegration.createTest.CreateTestDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.testIntegration.createTest.CreateTestDialog.java

Source

/*
 * Copyright 2000-2011 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.testIntegration.createTest;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mustbe.consulo.roots.ContentFolderScopes;
import org.mustbe.consulo.roots.impl.TestContentFolderTypeProvider;
import com.intellij.CommonBundle;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.PackageUtil;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ContentFolder;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiJavaPackage;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiNameHelper;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil;
import com.intellij.refactoring.ui.MemberSelectionTable;
import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.classMembers.MemberInfo;
import com.intellij.testIntegration.TestFramework;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.RecentsManager;
import com.intellij.ui.ReferenceEditorComboWithBrowseButton;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.IncorrectOperationException;

public class CreateTestDialog extends DialogWrapper {
    private static final String RECENTS_KEY = "CreateTestDialog.RecentsKey";
    private static final String RECENT_SUPERS_KEY = "CreateTestDialog.Recents.Supers";
    private static final String DEFAULT_LIBRARY_NAME_PROPERTY = CreateTestDialog.class.getName()
            + ".defaultLibrary";
    private static final String SHOW_INHERITED_MEMBERS_PROPERTY = CreateTestDialog.class.getName()
            + ".includeInheritedMembers";

    private final Project myProject;
    private final PsiClass myTargetClass;
    private final Module myTargetModule;

    private PsiDirectory myTargetDirectory;
    private TestFramework mySelectedFramework;

    private final List<JRadioButton> myLibraryButtons = new ArrayList<JRadioButton>();
    private EditorTextField myTargetClassNameField;
    private ReferenceEditorComboWithBrowseButton mySuperClassField;
    private ReferenceEditorComboWithBrowseButton myTargetPackageField;
    private JCheckBox myGenerateBeforeBox;
    private JCheckBox myGenerateAfterBox;
    private JCheckBox myShowInheritedMethodsBox;
    private MemberSelectionTable myMethodsTable;
    private JButton myFixLibraryButton;
    private JPanel myFixLibraryPanel;
    private JLabel myFixLibraryLabel;

    private JRadioButton myDefaultLibraryButton;

    public CreateTestDialog(@NotNull Project project, @NotNull String title, PsiClass targetClass,
            PsiJavaPackage targetPackage, Module targetModule) {
        super(project, true);
        myProject = project;

        myTargetClass = targetClass;
        myTargetModule = targetModule;

        initControls(targetClass, targetPackage);
        setTitle(title);
        init();

        myDefaultLibraryButton.doClick();
    }

    private void initControls(PsiClass targetClass, PsiJavaPackage targetPackage) {
        ButtonGroup group = new ButtonGroup();

        Map<String, JRadioButton> nameToButtonMap = new HashMap<String, JRadioButton>();
        List<Pair<String, JRadioButton>> attachedLibraries = new ArrayList<Pair<String, JRadioButton>>();

        for (final TestFramework descriptor : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) {
            final JRadioButton b = new JRadioButton(descriptor.getName());
            myLibraryButtons.add(b);
            group.add(b);

            nameToButtonMap.put(descriptor.getName(), b);
            if (descriptor.isLibraryAttached(myTargetModule)) {
                attachedLibraries.add(Pair.create(descriptor.getName(), b));
            }

            b.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (b.isSelected())
                        onLibrarySelected(descriptor);
                }
            });
        }

        String defaultLibrary = getDefaultLibraryName();
        if (attachedLibraries.isEmpty()) {
            if (defaultLibrary != null) {
                myDefaultLibraryButton = nameToButtonMap.get(defaultLibrary);
            }
        } else {
            if (defaultLibrary != null) {
                for (Pair<String, JRadioButton> each : attachedLibraries) {
                    if (each.first.equals(defaultLibrary)) {
                        myDefaultLibraryButton = each.second;
                    }
                }
            }
            if (myDefaultLibraryButton == null) {
                myDefaultLibraryButton = attachedLibraries.get(0).second;
            }
        }
        if (myDefaultLibraryButton == null) {
            myDefaultLibraryButton = myLibraryButtons.get(0);
        }

        myFixLibraryButton = new JButton(CodeInsightBundle.message("intention.create.test.dialog.fix.library"));
        myFixLibraryButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ApplicationManager.getApplication().runWriteAction(new Runnable() {
                    public void run() {
                        OrderEntryFix.addJarToRoots(mySelectedFramework.getLibraryPath(), myTargetModule, null);
                    }
                });
                myFixLibraryPanel.setVisible(false);
            }
        });

        myTargetClassNameField = new EditorTextField(targetClass.getName() + "Test");
        myTargetClassNameField.getDocument().addDocumentListener(new DocumentAdapter() {
            @Override
            public void documentChanged(DocumentEvent e) {
                getOKAction().setEnabled(PsiNameHelper.getInstance(myProject).isIdentifier(getClassName()));
            }
        });

        mySuperClassField = new ReferenceEditorComboWithBrowseButton(new MyChooseSuperClassAction(), null,
                myProject, true, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE, RECENT_SUPERS_KEY);
        mySuperClassField.setMinimumSize(mySuperClassField.getPreferredSize());

        String targetPackageName = targetPackage != null ? targetPackage.getQualifiedName() : "";
        myTargetPackageField = new PackageNameReferenceEditorCombo(targetPackageName, myProject, RECENTS_KEY,
                CodeInsightBundle.message("dialog.create.class.package.chooser.title"));

        new AnAction() {
            public void actionPerformed(AnActionEvent e) {
                myTargetPackageField.getButton().doClick();
            }
        }.registerCustomShortcutSet(
                new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK)),
                myTargetPackageField.getChildComponent());

        myGenerateBeforeBox = new JCheckBox("setUp/@Before");
        myGenerateAfterBox = new JCheckBox("tearDown/@After");

        myShowInheritedMethodsBox = new JCheckBox(
                CodeInsightBundle.message("intention.create.test.dialog.show.inherited"));
        myShowInheritedMethodsBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateMethodsTable();
            }
        });
        restoreShowInheritedMembersStatus();
        myMethodsTable = new MemberSelectionTable(Collections.<MemberInfo>emptyList(), null);
        updateMethodsTable();
    }

    private void onLibrarySelected(TestFramework descriptor) {
        String text = CodeInsightBundle.message("intention.create.test.dialog.library.not.found",
                descriptor.getName());
        myFixLibraryLabel.setText(text);
        myFixLibraryPanel.setVisible(!descriptor.isLibraryAttached(myTargetModule));

        String superClass = descriptor.getDefaultSuperClass();
        mySuperClassField.appendItem(superClass == null ? "" : superClass);
        mySelectedFramework = descriptor;
    }

    private void updateMethodsTable() {
        List<MemberInfo> methods = TestIntegrationUtils.extractClassMethods(myTargetClass,
                myShowInheritedMethodsBox.isSelected());

        Set<PsiMember> selectedMethods = new HashSet<PsiMember>();
        for (MemberInfo each : myMethodsTable.getSelectedMemberInfos()) {
            selectedMethods.add(each.getMember());
        }
        for (MemberInfo each : methods) {
            each.setChecked(selectedMethods.contains(each.getMember()));
        }

        myMethodsTable.setMemberInfos(methods);
    }

    private String getDefaultLibraryName() {
        return getProperties().getValue(DEFAULT_LIBRARY_NAME_PROPERTY);
    }

    private void saveDefaultLibraryName() {
        getProperties().setValue(DEFAULT_LIBRARY_NAME_PROPERTY, mySelectedFramework.getName());
    }

    private void restoreShowInheritedMembersStatus() {
        String v = getProperties().getValue(SHOW_INHERITED_MEMBERS_PROPERTY);
        myShowInheritedMethodsBox.setSelected(v != null && v.equals("true"));
    }

    private void saveShowInheritedMembersStatus() {
        boolean v = myShowInheritedMethodsBox.isSelected();
        getProperties().setValue(SHOW_INHERITED_MEMBERS_PROPERTY, Boolean.toString(v));
    }

    private PropertiesComponent getProperties() {
        return PropertiesComponent.getInstance(myProject);
    }

    @Override
    protected String getDimensionServiceKey() {
        return getClass().getName();
    }

    @NotNull
    protected Action[] createActions() {
        return new Action[] { getOKAction(), getCancelAction(), getHelpAction() };
    }

    public JComponent getPreferredFocusedComponent() {
        return myTargetClassNameField;
    }

    protected JComponent createCenterPanel() {
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints constr = new GridBagConstraints();

        constr.fill = GridBagConstraints.HORIZONTAL;
        constr.anchor = GridBagConstraints.WEST;

        JPanel librariesPanel = new JPanel();
        BoxLayout l = new BoxLayout(librariesPanel, BoxLayout.X_AXIS);
        librariesPanel.setLayout(l);

        for (JRadioButton b : myLibraryButtons) {
            librariesPanel.add(b);
        }

        int gridy = 1;

        constr.insets = insets(4);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        panel.add(new JLabel(CodeInsightBundle.message("intention.create.test.dialog.testing.library")), constr);

        constr.gridx = 1;
        constr.weightx = 1;
        constr.gridwidth = GridBagConstraints.REMAINDER;
        panel.add(librariesPanel, constr);

        myFixLibraryPanel = new JPanel(new BorderLayout());
        myFixLibraryLabel = new JLabel();
        myFixLibraryLabel.setIcon(AllIcons.Actions.IntentionBulb);
        myFixLibraryPanel.add(myFixLibraryLabel, BorderLayout.CENTER);
        myFixLibraryPanel.add(myFixLibraryButton, BorderLayout.EAST);

        constr.insets = insets(1);
        constr.gridy = gridy++;
        constr.gridx = 0;
        panel.add(myFixLibraryPanel, constr);

        constr.gridheight = 1;

        constr.insets = insets(6);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        constr.gridwidth = 1;
        panel.add(new JLabel(CodeInsightBundle.message("intention.create.test.dialog.class.name")), constr);

        constr.gridx = 1;
        constr.weightx = 1;
        panel.add(myTargetClassNameField, constr);

        constr.insets = insets(1);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        panel.add(new JLabel(CodeInsightBundle.message("intention.create.test.dialog.super.class")), constr);

        constr.gridx = 1;
        constr.weightx = 1;
        panel.add(mySuperClassField, constr);

        constr.insets = insets(1);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        panel.add(new JLabel(CodeInsightBundle.message("dialog.create.class.destination.package.label")), constr);

        constr.gridx = 1;
        constr.weightx = 1;

        JPanel targetPackagePanel = new JPanel(new BorderLayout());
        targetPackagePanel.add(myTargetPackageField, BorderLayout.CENTER);
        panel.add(targetPackagePanel, constr);

        constr.insets = insets(6);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        panel.add(new JLabel(CodeInsightBundle.message("intention.create.test.dialog.generate")), constr);

        constr.gridx = 1;
        constr.weightx = 1;
        panel.add(myGenerateBeforeBox, constr);

        constr.insets = insets(1);
        constr.gridy = gridy++;
        panel.add(myGenerateAfterBox, constr);

        constr.insets = insets(6);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.weightx = 0;
        panel.add(new JLabel(CodeInsightBundle.message("intention.create.test.dialog.select.methods")), constr);

        constr.gridx = 1;
        constr.weightx = 1;
        panel.add(myShowInheritedMethodsBox, constr);

        constr.insets = insets(1, 8);
        constr.gridy = gridy++;
        constr.gridx = 0;
        constr.gridwidth = GridBagConstraints.REMAINDER;
        constr.fill = GridBagConstraints.BOTH;
        constr.weighty = 1;
        panel.add(ScrollPaneFactory.createScrollPane(myMethodsTable), constr);

        return panel;
    }

    private static Insets insets(int top) {
        return insets(top, 0);
    }

    private static Insets insets(int top, int bottom) {
        return new Insets(top, 8, bottom, 8);
    }

    public String getClassName() {
        return myTargetClassNameField.getText();
    }

    @Nullable
    public String getSuperClassName() {
        String result = mySuperClassField.getText().trim();
        if (result.length() == 0)
            return null;
        return result;
    }

    public PsiDirectory getTargetDirectory() {
        return myTargetDirectory;
    }

    public Collection<MemberInfo> getSelectedMethods() {
        return myMethodsTable.getSelectedMemberInfos();
    }

    public boolean shouldGeneratedAfter() {
        return myGenerateAfterBox.isSelected();
    }

    public boolean shouldGeneratedBefore() {
        return myGenerateBeforeBox.isSelected();
    }

    public TestFramework getSelectedTestFrameworkDescriptor() {
        return mySelectedFramework;
    }

    protected void doOKAction() {
        RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, myTargetPackageField.getText());
        RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_SUPERS_KEY, mySuperClassField.getText());

        String errorMessage;
        try {
            myTargetDirectory = selectTargetDirectory();
            if (myTargetDirectory == null)
                return;
            errorMessage = RefactoringMessageUtil.checkCanCreateClass(myTargetDirectory, getClassName());
        } catch (IncorrectOperationException e) {
            errorMessage = e.getMessage();
        }

        if (errorMessage != null) {
            Messages.showMessageDialog(myProject, errorMessage, CommonBundle.getErrorTitle(),
                    Messages.getErrorIcon());
        }

        saveDefaultLibraryName();
        saveShowInheritedMembersStatus();
        super.doOKAction();
    }

    @Nullable
    private PsiDirectory selectTargetDirectory() throws IncorrectOperationException {
        final String packageName = getPackageName();
        final PackageWrapper targetPackage = new PackageWrapper(PsiManager.getInstance(myProject), packageName);

        final VirtualFile selectedRoot = new ReadAction<VirtualFile>() {
            protected void run(Result<VirtualFile> result) throws Throwable {
                final HashSet<VirtualFile> testFolders = new HashSet<VirtualFile>();
                CreateTestAction.checkForTestRoots(myTargetModule, testFolders);
                VirtualFile[] roots;
                if (testFolders.isEmpty()) {
                    roots = ModuleRootManager.getInstance(myTargetModule).getSourceRoots();
                    if (roots.length == 0)
                        return;
                } else {
                    roots = testFolders.toArray(new VirtualFile[testFolders.size()]);
                }

                if (roots.length == 1) {
                    result.setResult(roots[0]);
                } else {
                    PsiDirectory defaultDir = chooseDefaultDirectory(packageName);
                    result.setResult(MoveClassesOrPackagesUtil.chooseSourceRoot(targetPackage, roots, defaultDir));
                }
            }
        }.execute().getResultObject();

        if (selectedRoot == null)
            return null;

        return new WriteCommandAction<PsiDirectory>(myProject,
                CodeInsightBundle.message("create.directory.command")) {
            protected void run(Result<PsiDirectory> result) throws Throwable {
                result.setResult(RefactoringUtil.createPackageDirectoryInSourceRoot(targetPackage, selectedRoot));
            }
        }.execute().getResultObject();
    }

    @Nullable
    private PsiDirectory chooseDefaultDirectory(String packageName) {
        List<PsiDirectory> dirs = new ArrayList<PsiDirectory>();
        for (ContentEntry e : ModuleRootManager.getInstance(myTargetModule).getContentEntries()) {
            for (ContentFolder f : e
                    .getFolders(ContentFolderScopes.of(TestContentFolderTypeProvider.getInstance()))) {
                final VirtualFile file = f.getFile();
                if (file != null) {
                    final PsiDirectory dir = PsiManager.getInstance(myProject).findDirectory(file);
                    if (dir != null) {
                        dirs.add(dir);
                    }
                }
            }
        }
        if (!dirs.isEmpty()) {
            for (PsiDirectory dir : dirs) {
                final String dirName = dir.getVirtualFile().getPath();
                if (dirName.contains("generated"))
                    continue;
                return dir;
            }
            return dirs.get(0);
        }
        return PackageUtil.findPossiblePackageDirectoryInModule(myTargetModule, packageName);
    }

    private String getPackageName() {
        String name = myTargetPackageField.getText();
        return name != null ? name.trim() : "";
    }

    @Override
    protected void doHelpAction() {
        HelpManager.getInstance().invokeHelp("reference.dialogs.createTest");
    }

    private class MyChooseSuperClassAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            TreeClassChooserFactory f = TreeClassChooserFactory.getInstance(myProject);
            TreeClassChooser dialog = f.createAllProjectScopeChooser(
                    CodeInsightBundle.message("intention.create.test.dialog.choose.super.class"));
            dialog.showDialog();
            PsiClass aClass = dialog.getSelected();
            if (aClass != null) {
                mySuperClassField.setText(aClass.getQualifiedName());
            }
        }
    }
}