net.sf.logsupport.ui.AbstractProcessingDialog.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.logsupport.ui.AbstractProcessingDialog.java

Source

/*
 * Copyright 2010, Juergen Kellerer and other contributors.
 *
 * 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 net.sf.logsupport.ui;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiMethodCallExpression;
import net.sf.logsupport.util.LogPsiUtil;
import net.sf.logsupport.util.VirtualFileUtil;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;

public abstract class AbstractProcessingDialog extends DialogWrapper {

    private JPanel centerPane;

    protected JRadioButton wholeProject;
    protected JRadioButton module;
    protected JRadioButton file;
    protected JRadioButton allFiles;
    protected JCheckBox recursion;

    protected JPanel optionsPanel;

    private final Project project;

    private Set<Module> moduleSelection;
    private List<VirtualFile> allFilesSelection;

    private final List<VirtualFile> sourceSelection;

    public AbstractProcessingDialog(Project project, List<VirtualFile> sources) {
        super(project, false);
        if (sources == null)
            sources = Collections.emptyList();

        this.project = project;
        sourceSelection = sources;

        allFiles.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (recursion.isVisible())
                    recursion.setEnabled(allFiles.isSelected());
            }
        });

        wholeProject.setVisible(sources.isEmpty());
        module.setVisible(false);
        recursion.setEnabled(false);

        setOKButtonText("Run");

        init();
    }

    /**
     * Returns a callable that identifies all changeable files and return them as a list.
     *
     * @return a callable that identifies all changeable files and return them as a list.
     */
    @NotNull
    public Computable<List<PsiFile>> getReadOperation() {
        return new DefaultReadOperation();
    }

    /**
     * Returns a runnable that operates on the given files inside a write context.
     *
     * @param files the files to operate on.
     * @return a runnable that operates on the given files inside a write context.
     */
    @NotNull
    public abstract Runnable getWriteOperation(@NotNull List<PsiFile> files);

    public boolean isAllFiles() {
        return allFiles.isVisible() && allFiles.isEnabled() && allFiles.isSelected();
    }

    public boolean isRecursive() {
        return recursion.isVisible() && recursion.isEnabled() && recursion.isSelected();
    }

    public Project getProject() {
        return project;
    }

    public Set<Module> getModuleSelection() {
        return moduleSelection;
    }

    public List<VirtualFile> getSelection() {
        return isAllFiles() ? allFilesSelection : sourceSelection;
    }

    @Override
    protected JComponent createCenterPanel() {
        return centerPane;
    }

    @Override
    protected void init() {
        try {
            moduleSelection = new LinkedHashSet<Module>();
            if (sourceSelection.isEmpty()) {
                allFilesSelection = Collections.emptyList();
                allFiles.setVisible(false);
                file.setVisible(false);
            } else {
                allFilesSelection = VirtualFileUtil.toDirectories(sourceSelection, false);
                if (!allFilesSelection.isEmpty()) {
                    decorateButton(allFiles, true, allFilesSelection);
                    allFiles.setSelected(true);

                    decorateButton(file, false, "");
                } else {
                    allFilesSelection = VirtualFileUtil.toDirectories(sourceSelection, true);
                    if (!allFilesSelection.isEmpty())
                        decorateButton(allFiles, true, allFilesSelection);
                    else
                        allFiles.setVisible(false);

                    decorateButton(file, true, sourceSelection);
                    file.setSelected(true);
                }
            }

            ModuleManager manager = ModuleManager.getInstance(project);
            Module[] modules = manager.getModules();

            for (VirtualFile dir : allFilesSelection) {
                if (hasSubdirectories(project, dir))
                    recursion.setEnabled(true);

                // Resolve what path belongs to what module.
                for (Module module : modules) {
                    for (VirtualFile virtualFile : VirtualFileUtil.getSourceDirectories(module, true)) {
                        if (dir.getUrl().startsWith(virtualFile.getUrl()))
                            moduleSelection.add(module);
                    }
                }
            }

            if (!recursion.isEnabled())
                recursion.setVisible(false);
        } finally {
            super.init();
        }
    }

    public static boolean hasSubdirectories(Project project, VirtualFile directory) {
        if (directory != null) {
            ProjectRootManager prm = ProjectRootManager.getInstance(project);
            ProjectFileIndex pfi = prm.getFileIndex();

            VirtualFile[] children = directory.getChildren();
            for (VirtualFile aChildren : children)
                if (aChildren.isDirectory() && !pfi.isIgnored(aChildren))
                    return true;
        }

        return false;
    }

    protected void decorateModuleButton() {
        boolean enabled = !moduleSelection.isEmpty();
        if (enabled) {
            StringBuffer b = new StringBuffer();
            for (Module m : moduleSelection) {
                if (b.length() > 0)
                    b.append(", ");
                b.append('"').append(m.getName()).append('"');
            }

            decorateButton(module, enabled, b.toString());
        } else
            decorateButton(module, enabled, "");
    }

    protected void decorateButton(AbstractButton button, boolean enabled, List<VirtualFile> files) {
        if (enabled) {
            decorateButton(button, enabled,
                    "'" + files.get(0).getPresentableUrl() + "'" + (files.size() > 1 ? ", ..." : ""));
        } else
            decorateButton(button, enabled, "");
    }

    protected void decorateButton(AbstractButton button, boolean enabled, String descriptiveText) {
        button.setEnabled(enabled);

        if (enabled)
            button.setText(button.getText() + ' ' + descriptiveText);
    }

    protected class DefaultReadOperation implements Computable<List<PsiFile>> {

        boolean wholeProjectSelected = wholeProject.isSelected();
        boolean moduleSelected = module.isSelected();
        boolean allFiles = isAllFiles();
        boolean recursive = isRecursive();

        public List<PsiFile> compute() {
            List<VirtualFile> files;

            if (wholeProjectSelected) {
                files = VirtualFileUtil.toFiles(project, VirtualFileUtil.getSourceDirectories(project, true), true);
            } else if (moduleSelected) {
                files = new ArrayList<VirtualFile>();
                for (Module module : moduleSelection) {
                    files.addAll(VirtualFileUtil.toFiles(project,
                            VirtualFileUtil.getSourceDirectories(module, true), true));
                }
            } else if (allFiles) {
                files = VirtualFileUtil.toFiles(project, allFilesSelection, recursive);
            } else {
                files = VirtualFileUtil.toFiles(project, sourceSelection, false);
            }

            PsiManager manager = PsiManager.getInstance(project);
            List<PsiFile> sourceFiles = new ArrayList<PsiFile>(files.size());

            for (VirtualFile file : files) {
                if (!VirtualFileUtil.isSupportedFile(file))
                    continue;

                PsiFile pf = manager.findFile(file);
                if (pf == null || !acceptFile(pf, LogPsiUtil.findSupportedLoggerCalls(pf)))
                    continue;

                sourceFiles.add(pf);
            }
            return sourceFiles;
        }

        protected boolean acceptFile(PsiFile file, List<PsiMethodCallExpression> loggerCalls) {
            return !loggerCalls.isEmpty();
        }
    }
}