com.theoryinpractice.testng.configuration.TestNGConfigurationEditor.java Source code

Java tutorial

Introduction

Here is the source code for com.theoryinpractice.testng.configuration.TestNGConfigurationEditor.java

Source

/*
 * 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.
 */

/*
 * Created by IntelliJ IDEA.
 * User: amrk
 * Date: Jul 3, 2005
 * Time: 6:15:22 PM
 */
package com.theoryinpractice.testng.configuration;

import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configuration.BrowseModuleValueActionListener;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.execution.ui.AlternativeJREPanel;
import com.intellij.execution.ui.CommonJavaParametersPanel;
import com.intellij.execution.ui.ConfigurationModuleSelector;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.ui.table.TableView;
import com.intellij.util.IconUtil;
import com.intellij.util.TextFieldCompletionProvider;
import com.theoryinpractice.testng.MessageInfoException;
import com.theoryinpractice.testng.configuration.browser.*;
import com.theoryinpractice.testng.model.*;
import com.theoryinpractice.testng.util.TestNGUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Map;

public class TestNGConfigurationEditor extends SettingsEditor<TestNGConfiguration> implements PanelWithAnchor {
    //private static final Logger LOGGER = Logger.getInstance("TestNG Runner");
    private final Project project;

    private JPanel panel;

    private LabeledComponent<EditorTextFieldWithBrowseButton> classField;
    private LabeledComponent<JComboBox> moduleClasspath;
    private AlternativeJREPanel alternateJDK;
    private final ConfigurationModuleSelector moduleSelector;
    private JRadioButton suiteTest;
    private JRadioButton packageTest;
    private JRadioButton classTest;
    private JRadioButton methodTest;
    private JRadioButton groupTest;
    private JRadioButton patternTest;
    private final TestNGConfigurationModel model;
    private LabeledComponent<EditorTextFieldWithBrowseButton> methodField;
    private LabeledComponent<EditorTextFieldWithBrowseButton> packageField;
    private LabeledComponent<TextFieldWithBrowseButton.NoPathCompletion> groupField;
    private LabeledComponent<TextFieldWithBrowseButton> suiteField;
    private JComponent anchor;
    private JRadioButton packagesInProject;
    private JRadioButton packagesInModule;
    private JRadioButton packagesAcrossModules;
    private JPanel packagePanel;
    private TestNGParametersTableModel propertiesTableModel;
    private LabeledComponent<TextFieldWithBrowseButton> propertiesFile;
    private LabeledComponent<TextFieldWithBrowseButton> outputDirectory;
    private TableView propertiesTableView;
    private JPanel commonParametersPanel;//temp compilation problems
    private JList myListenersList;
    private JCheckBox myUseDefaultReportersCheckBox;
    private LabeledComponent<JPanel> myPattern;
    private JPanel myPropertiesPanel;
    private JPanel myListenersPanel;
    TextFieldWithBrowseButton myPatternTextField;
    private final CommonJavaParametersPanel commonJavaParameters = new CommonJavaParametersPanel();
    private ArrayList<Map.Entry> propertiesList;
    private TestNGListenersTableModel listenerModel;

    private TestNGConfiguration config;

    public TestNGConfigurationEditor(Project project) {
        this.project = project;
        BrowseModuleValueActionListener[] browseListeners = new BrowseModuleValueActionListener[] {
                new PackageBrowser(project), new TestClassBrowser(project, this), new MethodBrowser(project, this),
                new GroupBrowser(project, this), new SuiteBrowser(project), new TestClassBrowser(project, this) {
                    @Override
                    protected void onClassChoosen(PsiClass psiClass) {
                        final JTextField textField = myPatternTextField.getTextField();
                        final String text = textField.getText();
                        textField.setText(text + (text.length() > 0 ? "||" : "") + psiClass.getQualifiedName());
                    }

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        showDialog();
                    }
                } };
        model = new TestNGConfigurationModel(project);
        model.setListener(this);
        createView();
        moduleSelector = new ConfigurationModuleSelector(project, getModulesComponent());
        commonJavaParameters.setModuleContext(moduleSelector.getModule());
        moduleClasspath.getComponent().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                commonJavaParameters.setModuleContext(moduleSelector.getModule());
            }
        });

        final JPanel panel = myPattern.getComponent();
        panel.setLayout(new BorderLayout());
        myPatternTextField = new TextFieldWithBrowseButton();
        myPatternTextField.setButtonIcon(IconUtil.getAddIcon());
        panel.add(myPatternTextField, BorderLayout.CENTER);
        final FixedSizeButton editBtn = new FixedSizeButton();
        editBtn.setIcon(AllIcons.Actions.ShowViewer);
        editBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Messages.showTextAreaDialog(myPatternTextField.getTextField(), "Configure suite tests",
                        "EditParametersPopupWindow");
            }
        });
        panel.add(editBtn, BorderLayout.EAST);

        registerListener(
                new JRadioButton[] { packageTest, classTest, methodTest, groupTest, suiteTest, patternTest },
                new ChangeListener() {
                    public void stateChanged(ChangeEvent e) {
                        ButtonModel buttonModel = (ButtonModel) e.getSource();
                        if (buttonModel.isSelected()) {
                            if (buttonModel == packageTest.getModel()) {
                                model.setType(TestType.PACKAGE);
                            } else if (buttonModel == classTest.getModel()) {
                                model.setType(TestType.CLASS);
                            } else if (buttonModel == methodTest.getModel()) {
                                model.setType(TestType.METHOD);
                            } else if (buttonModel == groupTest.getModel()) {
                                model.setType(TestType.GROUP);
                            } else if (buttonModel == suiteTest.getModel()) {
                                model.setType(TestType.SUITE);
                            } else if (buttonModel == patternTest.getModel()) {
                                model.setType(TestType.PATTERN);
                            }
                            redisplay();
                        }
                    }
                });
        registerListener(new JRadioButton[] { packagesInProject, packagesInModule, packagesAcrossModules }, null);
        packagesInProject.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                evaluateModuleClassPath();
            }
        });

        LabeledComponent[] components = new LabeledComponent[] { packageField, classField, methodField, groupField,
                suiteField, myPattern };
        for (int i = 0; i < components.length; i++) {
            JComponent field = components[i].getComponent();
            Object document = model.getDocument(i);
            if (field instanceof TextFieldWithBrowseButton) {
                ((TextFieldWithBrowseButton) field).getTextField().setDocument((PlainDocument) document);
            } else if (field instanceof EditorTextFieldWithBrowseButton) {
                final com.intellij.openapi.editor.Document componentDocument = ((EditorTextFieldWithBrowseButton) field)
                        .getChildComponent().getDocument();
                model.setDocument(i, componentDocument);
            } else {
                field = myPatternTextField;
                document = new PlainDocument();
                ((TextFieldWithBrowseButton) field).getTextField().setDocument((Document) document);
                model.setDocument(i, document);
            }

            browseListeners[i].setField((ComponentWithBrowseButton) field);
        }
        model.setType(TestType.CLASS);
        propertiesFile.getComponent().getTextField().setDocument(model.getPropertiesFileDocument());
        outputDirectory.getComponent().getTextField().setDocument(model.getOutputDirectoryDocument());

        commonJavaParameters.setProgramParametersLabel(
                ExecutionBundle.message("junit.configuration.test.runner.parameters.label"));

        setAnchor(outputDirectory.getLabel());
        alternateJDK.setAnchor(moduleClasspath.getLabel());
        commonJavaParameters.setAnchor(moduleClasspath.getLabel());
    }

    private void evaluateModuleClassPath() {
        moduleClasspath.setEnabled(!packagesInProject.isSelected());
    }

    private void redisplay() {
        if (packageTest.isSelected()) {
            packagePanel.setVisible(true);
            classField.setVisible(false);
            methodField.setVisible(false);
            groupField.setVisible(false);
            suiteField.setVisible(false);
            myPattern.setVisible(false);
        } else if (classTest.isSelected()) {
            packagePanel.setVisible(false);
            classField.setVisible(true);
            methodField.setVisible(false);
            groupField.setVisible(false);
            suiteField.setVisible(false);
            myPattern.setVisible(false);
        } else if (methodTest.isSelected()) {
            packagePanel.setVisible(false);
            classField.setVisible(true);
            methodField.setVisible(true);
            groupField.setVisible(false);
            suiteField.setVisible(false);
            myPattern.setVisible(false);
        } else if (groupTest.isSelected()) {
            packagePanel.setVisible(false);
            classField.setVisible(false);
            methodField.setVisible(false);
            groupField.setVisible(true);
            suiteField.setVisible(false);
            myPattern.setVisible(false);
        } else if (suiteTest.isSelected()) {
            packagePanel.setVisible(false);
            classField.setVisible(false);
            methodField.setVisible(false);
            groupField.setVisible(false);
            suiteField.setVisible(true);
            myPattern.setVisible(false);
        } else if (patternTest.isSelected()) {
            packagePanel.setVisible(false);
            classField.setVisible(false);
            methodField.setVisible(false);
            groupField.setVisible(false);
            suiteField.setVisible(false);
            myPattern.setVisible(true);
        }
    }

    public String getClassName() {
        return classField.getComponent().getText();
    }

    public JComboBox getModulesComponent() {
        return moduleClasspath.getComponent();
    }

    @Override
    protected void resetEditorFrom(TestNGConfiguration config) {
        this.config = config;
        model.reset(config);
        commonJavaParameters.reset(config);
        getModuleSelector().reset(config);
        TestData data = config.getPersistantData();
        TestSearchScope scope = data.getScope();
        if (scope == TestSearchScope.SINGLE_MODULE) {
            packagesInModule.setSelected(true);
        } else if (scope == TestSearchScope.MODULE_WITH_DEPENDENCIES) {
            packagesAcrossModules.setSelected(true);
        } else {
            packagesInProject.setSelected(true);
        }
        alternateJDK.init(config.ALTERNATIVE_JRE_PATH, config.ALTERNATIVE_JRE_PATH_ENABLED);
        propertiesList = new ArrayList<Map.Entry>();
        propertiesList.addAll(data.TEST_PROPERTIES.entrySet());
        propertiesTableModel.setParameterList(propertiesList);

        listenerModel.setListenerList(data.TEST_LISTENERS);
        myUseDefaultReportersCheckBox.setSelected(data.USE_DEFAULT_REPORTERS);
    }

    @Override
    public void applyEditorTo(TestNGConfiguration config) {
        model.apply(getModuleSelector().getModule(), config);
        getModuleSelector().applyTo(config);
        TestData data = config.getPersistantData();
        if (packageTest.isSelected()) {
            if (packagesInProject.isSelected()) {
                data.setScope(TestSearchScope.WHOLE_PROJECT);
            } else if (packagesInModule.isSelected()) {
                data.setScope(TestSearchScope.SINGLE_MODULE);
            } else if (packagesAcrossModules.isSelected())
                data.setScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
        } else {
            data.setScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
        }
        commonJavaParameters.applyTo(config);
        config.ALTERNATIVE_JRE_PATH = alternateJDK.getPath();
        config.ALTERNATIVE_JRE_PATH_ENABLED = alternateJDK.isPathEnabled();

        data.TEST_PROPERTIES.clear();
        for (Map.Entry<String, String> entry : propertiesList) {
            data.TEST_PROPERTIES.put(entry.getKey(), entry.getValue());
        }

        data.TEST_LISTENERS.clear();
        data.TEST_LISTENERS.addAll(listenerModel.getListenerList());

        data.USE_DEFAULT_REPORTERS = myUseDefaultReportersCheckBox.isSelected();
    }

    public ConfigurationModuleSelector getModuleSelector() {
        return moduleSelector;
    }

    @NotNull
    @Override
    protected JComponent createEditor() {
        return panel;
    }

    @Override
    public JComponent getAnchor() {
        return anchor;
    }

    @Override
    public void setAnchor(JComponent anchor) {
        this.anchor = anchor;
        methodField.setAnchor(anchor);
        packageField.setAnchor(anchor);
        groupField.setAnchor(anchor);
        suiteField.setAnchor(anchor);
        outputDirectory.setAnchor(anchor);
        classField.setAnchor(anchor);
        myPattern.setAnchor(anchor);
    }

    private static void registerListener(JRadioButton[] buttons, ChangeListener changelistener) {
        ButtonGroup buttongroup = new ButtonGroup();
        for (JRadioButton button : buttons) {
            button.getModel().addChangeListener(changelistener);
            buttongroup.add(button);
        }

        if (buttongroup.getSelection() == null)
            buttongroup.setSelected(buttons[0].getModel(), true);
    }

    private void createView() {
        commonParametersPanel.add(commonJavaParameters, BorderLayout.CENTER);

        packageTest.setSelected(false);
        suiteTest.setSelected(false);
        suiteTest.setEnabled(true);
        groupTest.setSelected(false);
        groupTest.setEnabled(true);
        classTest.setSelected(false);
        classTest.setEnabled(true);
        patternTest.setSelected(false);
        patternTest.setEnabled(true);

        classField.setComponent(
                new EditorTextFieldWithBrowseButton(project, true, new JavaCodeFragment.VisibilityChecker() {
                    @Override
                    public Visibility isDeclarationVisible(PsiElement declaration, PsiElement place) {
                        try {
                            if (declaration instanceof PsiClass
                                    && new TestClassBrowser(project, TestNGConfigurationEditor.this).getFilter()
                                            .isAccepted((PsiClass) declaration)) {
                                return Visibility.VISIBLE;
                            }
                        } catch (MessageInfoException e) {
                            return Visibility.NOT_VISIBLE;
                        }
                        return Visibility.NOT_VISIBLE;
                    }
                }));

        final EditorTextFieldWithBrowseButton methodEditorTextField = new EditorTextFieldWithBrowseButton(project,
                true, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE,
                PlainTextLanguage.INSTANCE.getAssociatedFileType());
        new TextFieldCompletionProvider() {
            @Override
            protected void addCompletionVariants(@NotNull String text, int offset, @NotNull String prefix,
                    @NotNull CompletionResultSet result) {
                final String className = getClassName();
                if (className.trim().length() == 0) {
                    return;
                }
                final PsiClass testClass = getModuleSelector().findClass(className);
                if (testClass == null)
                    return;
                for (PsiMethod psiMethod : testClass.getAllMethods()) {
                    if (TestNGUtil.hasTest(psiMethod)) {
                        result.addElement(LookupElementBuilder.create(psiMethod.getName()));
                    }
                }
            }
        }.apply(methodEditorTextField.getChildComponent());
        methodField.setComponent(methodEditorTextField);

        groupField.setComponent(new TextFieldWithBrowseButton.NoPathCompletion());
        suiteField.setComponent(new TextFieldWithBrowseButton());
        packageField.setVisible(true);
        packageField.setEnabled(true);
        packageField.setComponent(new EditorTextFieldWithBrowseButton(project, false));

        TextFieldWithBrowseButton outputDirectoryButton = new TextFieldWithBrowseButton();
        outputDirectory.setComponent(outputDirectoryButton);
        outputDirectoryButton.addBrowseFolderListener("TestNG", "Select test output directory", project,
                FileChooserDescriptorFactory.createSingleFolderDescriptor());
        moduleClasspath.setEnabled(true);
        moduleClasspath.setComponent(new JComboBox());

        propertiesTableModel = new TestNGParametersTableModel();
        listenerModel = new TestNGListenersTableModel();

        TextFieldWithBrowseButton textFieldWithBrowseButton = new TextFieldWithBrowseButton();
        propertiesFile.setComponent(textFieldWithBrowseButton);

        FileChooserDescriptor propertiesFileDescriptor = new FileChooserDescriptor(true, false, false, false, false,
                false) {
            @Override
            public boolean isFileVisible(VirtualFile virtualFile, boolean showHidden) {
                if (!showHidden && virtualFile.getName().charAt(0) == '.')
                    return false;
                return virtualFile.isDirectory() || "properties".equals(virtualFile.getExtension());
            }
        };

        textFieldWithBrowseButton.addBrowseFolderListener("TestNG", "Select .properties file for test properties",
                project, propertiesFileDescriptor);

        propertiesTableView = new TableView();
        propertiesTableView.setModelAndUpdateColumns(propertiesTableModel);
        propertiesTableView.setShowGrid(true);

        myPropertiesPanel.add(
                ToolbarDecorator.createDecorator(propertiesTableView).setAddAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        propertiesTableModel.addParameter();
                        int index = propertiesTableModel.getRowCount() - 1;
                        propertiesTableView.setRowSelectionInterval(index, index);
                    }
                }).setRemoveAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        int idx = propertiesTableView.getSelectedRow() - 1;
                        for (int row : propertiesTableView.getSelectedRows()) {
                            propertiesTableModel.removeProperty(row);
                        }
                        if (idx > -1)
                            propertiesTableView.setRowSelectionInterval(idx, idx);
                    }
                }).disableUpDownActions().createPanel(), BorderLayout.CENTER);

        myListenersList = new JBList(listenerModel);
        myListenersPanel.add(ToolbarDecorator.createDecorator(myListenersList)
                .setAddAction(new AddActionButtonRunnable()).setRemoveAction(new AnActionButtonRunnable() {
                    @Override
                    public void run(AnActionButton button) {
                        int idx = myListenersList.getSelectedIndex() - 1;
                        for (int row : myListenersList.getSelectedIndices()) {
                            listenerModel.removeListener(row);
                        }
                        if (idx > -1)
                            myListenersList.setSelectedIndex(idx);
                    }
                }).setAddActionUpdater(new AnActionButtonUpdater() {
                    @Override
                    public boolean isEnabled(AnActionEvent e) {
                        return !project.isDefault();
                    }
                }).disableUpDownActions().createPanel(), BorderLayout.CENTER);
    }

    @Override
    protected void disposeEditor() {
    }

    public void onTypeChanged(TestType type) {
        //LOGGER.info("onTypeChanged with " + type);
        if (type != TestType.PACKAGE && type != TestType.SUITE) {
            moduleClasspath.setEnabled(true);
        } else {
            evaluateModuleClassPath();
        }
        if (type == TestType.PACKAGE) {
            packageTest.setSelected(true);
            packageField.setEnabled(true);
            classField.setEnabled(false);
            methodField.setEnabled(false);
            groupField.setEnabled(false);
            suiteField.setEnabled(false);
            myPattern.setEnabled(false);
        } else if (type == TestType.CLASS) {
            classTest.setSelected(true);
            packageField.setEnabled(false);
            classField.setEnabled(true);
            methodField.setEnabled(false);
            groupField.setEnabled(false);
            suiteField.setEnabled(false);
            myPattern.setEnabled(false);
        } else if (type == TestType.METHOD) {
            methodTest.setSelected(true);
            packageField.setEnabled(false);
            classField.setEnabled(true);
            methodField.setEnabled(true);
            groupField.setEnabled(false);
            suiteField.setEnabled(false);
            myPattern.setEnabled(false);
        } else if (type == TestType.GROUP) {
            groupTest.setSelected(true);
            groupField.setEnabled(true);
            packageField.setEnabled(false);
            classField.setEnabled(false);
            methodField.setEnabled(false);
            suiteField.setEnabled(false);
            myPattern.setEnabled(false);
        } else if (type == TestType.SUITE) {
            suiteTest.setSelected(true);
            suiteField.setEnabled(true);
            packageField.setEnabled(false);
            classField.setEnabled(false);
            methodField.setEnabled(false);
            groupField.setEnabled(false);
            myPattern.setEnabled(false);
        } else if (type == TestType.PATTERN) {
            patternTest.setSelected(true);
            myPattern.setEnabled(true);
            suiteField.setEnabled(false);
            packageField.setEnabled(false);
            classField.setEnabled(false);
            methodField.setEnabled(false);
            groupField.setEnabled(false);
        }
    }

    private class AddActionButtonRunnable implements AnActionButtonRunnable {
        private final Logger LOGGER = Logger.getInstance("TestNG Runner");

        @Nullable
        protected GlobalSearchScope getSearchScope(Module[] modules) {
            if (modules == null || modules.length == 0)
                return null;
            GlobalSearchScope scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(modules[0]);
            for (int i = 1; i < modules.length; i++) {
                scope.uniteWith(GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(modules[i]));
            }
            return scope;
        }

        @Nullable
        protected String selectListenerClass() {
            GlobalSearchScope searchScope = getSearchScope(config.getModules());
            if (searchScope == null) {
                searchScope = GlobalSearchScope.allScope(project);
            }
            final TestListenerFilter filter = new TestListenerFilter(searchScope, project);

            TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
                    .createWithInnerClassesScopeChooser("Choose Listener Class", filter.getScope(), filter, null);
            chooser.showDialog();
            PsiClass psiclass = chooser.getSelected();
            if (psiclass == null) {
                return null;
            } else {
                return JavaExecutionUtil.getRuntimeQualifiedName(psiclass);
            }
        }

        @Override
        public void run(AnActionButton button) {
            final String className = selectListenerClass();
            if (className != null) {
                listenerModel.addListener(className);
                LOGGER.info("Adding listener " + className + " to configuration.");
            }
        }
    }
}