com.atlassian.theplugin.idea.ThePluginProjectComponent.java Source code

Java tutorial

Introduction

Here is the source code for com.atlassian.theplugin.idea.ThePluginProjectComponent.java

Source

/**
 * Copyright (C) 2008 Atlassian
 *
 * 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.atlassian.theplugin.idea;

import com.atlassian.connector.cfg.ProjectCfgManager;
import com.atlassian.connector.intellij.bamboo.BambooBuildAdapter;
import com.atlassian.connector.intellij.bamboo.BambooPopupInfo;
import com.atlassian.connector.intellij.bamboo.BambooStatusChecker;
import com.atlassian.connector.intellij.bamboo.BambooStatusDisplay;
import com.atlassian.connector.intellij.bamboo.BambooStatusListener;
import com.atlassian.connector.intellij.bamboo.BambooStatusTooltipListener;
import com.atlassian.connector.intellij.bamboo.IntelliJBambooServerFacade;
import com.atlassian.connector.intellij.bamboo.StatusIconBambooListener;
import com.atlassian.connector.intellij.crucible.IntelliJCrucibleServerFacade;
import com.atlassian.connector.intellij.tasks.PluginTaskManager;
import com.atlassian.theplugin.commons.UIActionScheduler;
import com.atlassian.theplugin.commons.bamboo.BuildStatus;
import com.atlassian.theplugin.commons.cfg.ConfigurationListenerAdapter;
import com.atlassian.theplugin.commons.cfg.ProjectConfiguration;
import com.atlassian.theplugin.commons.configuration.PluginConfiguration;
import com.atlassian.theplugin.commons.util.LoggerImpl;
import com.atlassian.theplugin.configuration.JiraWorkspaceConfiguration;
import com.atlassian.theplugin.configuration.WorkspaceConfigurationBean;
import com.atlassian.theplugin.idea.action.issues.activetoolbar.tasks.PluginTaskManagerHelper;
import com.atlassian.theplugin.idea.action.issues.activetoolbar.tasks.TaskActionOrganizer;
import com.atlassian.theplugin.idea.autoupdate.ConfirmPluginUpdateHandler;
import com.atlassian.theplugin.idea.autoupdate.PluginUpdateIcon;
import com.atlassian.theplugin.idea.bamboo.BambooStatusIcon;
import com.atlassian.theplugin.idea.bamboo.BuildListModelImpl;
import com.atlassian.theplugin.idea.bamboo.BuildStatusChangedToolTip;
import com.atlassian.theplugin.idea.config.MissingPasswordHandler;
import com.atlassian.theplugin.idea.crucible.CruciblePatchSubmitExecutor;
import com.atlassian.theplugin.idea.jira.IssueListToolWindowPanel;
import com.atlassian.theplugin.idea.ui.InformationDialogWithCheckBox;
import com.atlassian.theplugin.idea.ui.linkhiglighter.FileEditorListenerImpl;
import com.atlassian.theplugin.jira.model.JIRAIssueListModelBuilder;
import com.atlassian.theplugin.remoteapi.MissingPasswordHandlerQueue;
import com.atlassian.theplugin.util.InfoServer;
import com.atlassian.theplugin.util.PluginUtil;
import com.atlassian.theplugin.util.UsageStatisticsGenerator;
import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.ContentManagerAdapter;
import com.intellij.ui.content.ContentManagerEvent;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.util.Collection;

/**
 * Per-project plugin component.
 */

public class ThePluginProjectComponent implements ProjectComponent {
    private static final String THE_PLUGIN_TOOL_WINDOW_ICON = "/icons/ico_plugin_13.png";

    private final WorkspaceConfigurationBean projectConfigurationBean;
    private final Project project;

    public ProjectCfgManager getCfgManager() {
        return projectCfgManager;
    }

    private final ProjectCfgManager projectCfgManager;
    private final UIActionScheduler actionScheduler;
    private BambooStatusIcon statusBarBambooIcon;

    private PluginUpdateIcon statusPluginUpdateIcon;
    private BambooStatusChecker bambooStatusChecker;
    private final BuildListModelImpl bambooModel;

    private BambooStatusTooltipListener tooltipBambooStatusListener;
    private final IntelliJCrucibleServerFacade crucibleServerFacade;

    private final ToolWindowManager toolWindowManager;
    private boolean created;
    private final JIRAIssueListModelBuilder jiraIssueListModelBuilder;
    private final PluginConfiguration pluginConfiguration;

    private final IssueListToolWindowPanel issuesToolWindowPanel;

    private final PluginToolWindow toolWindow;

    //   public static final Key<ReviewActionEventBroker> BROKER_KEY = Key.create("thePlugin.broker");
    private ConfigurationListenerImpl configurationListener;

    private FileEditorListenerImpl fileEditorListener;
    private JiraWorkspaceConfiguration jiraWorkspaceConfiguration;
    private final PluginTaskManager pluginTaskManager;

    public ThePluginProjectComponent(Project project, ToolWindowManager toolWindowManager,
            PluginConfiguration pluginConfiguration, UIActionScheduler actionScheduler,
            WorkspaceConfigurationBean projectConfigurationBean,
            @NotNull IssueListToolWindowPanel issuesToolWindowPanel, @NotNull PluginToolWindow pluginToolWindow,
            @NotNull BuildListModelImpl bambooModel, @NotNull final ProjectCfgManager projectCfgManager,
            @NotNull final JIRAIssueListModelBuilder jiraIssueListModelBuilder,
            @NotNull final JiraWorkspaceConfiguration jiraWorkspaceConfiguration,
            @NotNull final PluginTaskManager pluginTaskManager) {
        this.project = project;
        this.projectCfgManager = projectCfgManager;
        this.jiraIssueListModelBuilder = jiraIssueListModelBuilder;
        this.actionScheduler = actionScheduler;
        this.toolWindowManager = toolWindowManager;
        this.pluginConfiguration = pluginConfiguration;
        this.projectConfigurationBean = projectConfigurationBean;
        this.bambooModel = bambooModel;
        this.issuesToolWindowPanel = issuesToolWindowPanel;
        this.toolWindow = pluginToolWindow;
        this.jiraWorkspaceConfiguration = jiraWorkspaceConfiguration;
        this.pluginTaskManager = pluginTaskManager;

        this.crucibleServerFacade = IntelliJCrucibleServerFacade.getInstance();
        jiraIssueListModelBuilder.setProject(project);
        //      jiraIssueListModelBuilder.setProjectCfgManager(projectCfgManager);
        /*
            
                                      WARNING!!!
          BEFORE ADDING SOME INITIALIZATION CODE TO CONSTRUCTOR THINK TWICE
                                       st
          ...MAYBE YOU SHOULD PUT IT INTO THE initializePlugin METHOD
          (WHICH IS INVOKED WHEN THE ENTIRE PLUGIN ENVIRONMENT IS SET UP)?
            
            
           */
        // make findBugs happy
        statusBarBambooIcon = null;
        statusPluginUpdateIcon = null;
        created = false;
        StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() {
            public void run() {
                LoggerImpl.getInstance().info("Start: Project initializing");
                initializePlugin();
                LoggerImpl.getInstance().info("End: Project initialized");
            }
        });

    }

    public void initComponent() {
        LoggerImpl.getInstance().info("Init ThePlugin project component.");
        this.fileEditorListener = new FileEditorListenerImpl(project, projectCfgManager);
        //ActivateJiraIssueAction.showToolbar(project);
    }

    public void disposeComponent() {
        LoggerImpl.getInstance().info("Dispose ThePlugin project component");
    }

    @NotNull
    public String getComponentName() {
        return "ThePluginProjectComponent";
    }

    private void initializePlugin() {
        // unregister changelistmanager?
        // only open tool windows for each application that's registered
        // show something nice if there are non
        // swap listener for dataretrievedlistener and datachangelisteners
        // store bamboo between runs in UDC
        // clean up object model confusion
        if (!created) {
            IconLoader.activate();
            pluginTaskManager.activateListener();

            TaskActionOrganizer.organizeTaskActionsInToolbar();
            toolWindow.register(toolWindowManager);

            ChangeListManager.getInstance(project).registerCommitExecutor(
                    new CruciblePatchSubmitExecutor(project, crucibleServerFacade, projectCfgManager));

            final MissingPasswordHandler pwdHandler = new MissingPasswordHandler(
                    IntelliJBambooServerFacade.getInstance(PluginUtil.getLogger()), projectCfgManager, project);

            this.bambooStatusChecker = new BambooStatusChecker(actionScheduler, projectCfgManager,
                    pluginConfiguration, new Runnable() {
                        public void run() {
                            MissingPasswordHandlerQueue.addHandler(pwdHandler);
                        }
                    }, IntelliJBambooServerFacade.getInstance(PluginUtil.getLogger()));

            // DependencyValidationManager.getHolder(project, "", )

            // create Atlassian tool window
            //         toolWindow = new PluginToolWindow(toolWindowManager, project, cfgManager, bambooToolWindowPanel);
            Icon toolWindowIcon = IconLoader.getIcon(THE_PLUGIN_TOOL_WINDOW_ICON);
            toolWindow.getIdeaToolWindow().setIcon(toolWindowIcon);

            // create tool window content

            //         toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.BAMBOO_OLD);

            toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.BUILDS);
            toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.ISSUES);

            IdeaHelper.getAppComponent().getSchedulableCheckers().add(bambooStatusChecker);
            // add tool window bamboo content listener to bamboo checker thread
            bambooStatusChecker.registerListener(new BambooStatusListener() {

                public void updateBuildStatuses(Collection<BambooBuildAdapter> builds,
                        Collection<Exception> generalExceptions) {
                    bambooModel.update(builds, generalExceptions);
                }

                public void resetState() {
                }
            });

            // create Bamboo status bar icon
            statusBarBambooIcon = new BambooStatusIcon(this.project, projectCfgManager, toolWindow);
            statusBarBambooIcon.updateBambooStatus(BuildStatus.UNKNOWN, new BambooPopupInfo());

            // add icon listener to bamboo checker thread
            final StatusIconBambooListener iconBambooStatusListener = new StatusIconBambooListener(
                    statusBarBambooIcon);
            bambooStatusChecker.registerListener(iconBambooStatusListener);

            // add simple bamboo listener to bamboo checker thread
            // this listener shows idea tooltip when buld failed
            final BambooStatusDisplay bambooStatusDisplay = new BuildStatusChangedToolTip(project, toolWindow);
            tooltipBambooStatusListener = new BambooStatusTooltipListener(bambooStatusDisplay, pluginConfiguration);
            bambooStatusChecker.registerListener(tooltipBambooStatusListener);
            //         bambooStatusChecker.registerListener(buildToolWindowPanel.getBuildTree());

            // add bamboo icon to status bar
            statusBarBambooIcon.showOrHideIcon();

            statusPluginUpdateIcon = new PluginUpdateIcon(project, pluginConfiguration, projectCfgManager);
            ConfirmPluginUpdateHandler.getInstance().setDisplay(statusPluginUpdateIcon);
            //statusPluginUpdateIcon.showOrHideIcon();

            toolWindow.showHidePanels();
            // focus last active panel only if it exists (do not create panel)
            toolWindow.focusPanelIfExists(projectConfigurationBean.getActiveToolWindowTab());
            toolWindow.getIdeaToolWindow().getContentManager()
                    .addContentManagerListener(new ContentManagerAdapter() {
                        @Override
                        public void selectionChanged(final ContentManagerEvent event) {
                            projectConfigurationBean.setActiveToolWindowTab(event.getContent().getDisplayName());
                        }
                    });

            IdeaHelper.getAppComponent().rescheduleStatusCheckers(false);

            configurationListener = new ConfigurationListenerImpl();
            projectCfgManager.addProjectConfigurationListener(configurationListener);
            projectCfgManager.addProjectConfigurationListener(issuesToolWindowPanel.getConfigListener());

            projectCfgManager.addProjectConfigurationListener(
                    IntelliJBambooServerFacade.getInstance(PluginUtil.getLogger()).getConfigurationListener());

            created = true;

            issuesToolWindowPanel.init();
            checkDefaultServerValues();
            // PL-2789 - task integration is busted in recent IDEAs anyway.
            //            informAboutIdea9TaskIntegrationAsExperimental();

            IdeaVersionFacade.getInstance().registerCheckinHandler(project, jiraWorkspaceConfiguration);

            issuesToolWindowPanel.refreshModels();
        }
    }

    public void projectOpened() {
        // content moved to StartupManager to wait until
        // here we have guarantee that IDEA splash screen will not obstruct our window
        askForUserStatistics();
        fileEditorListener.projectOpened();
    }

    private void informAboutIdea9TaskIntegrationAsExperimental() {
        if (!pluginConfiguration.getGeneralConfigurationData().isInformedAboutIdea9TaskExperimentalSupport()
                && PluginTaskManagerHelper.isValidIdeaVersion()) {

            final InformationDialogWithCheckBox dialog = new InformationDialogWithCheckBox(project,
                    PluginUtil.PRODUCT_NAME,
                    "Atlassian IntelliJ Connector now provides experimental<br>"
                            + "integration with IntelliJ IDEA Tasks.<br>"
                            + "Please report any inconveniences or suggestions");
            SwingUtilities.invokeLater(new Runnable() {

                public void run() {
                    dialog.show();
                    pluginConfiguration.getGeneralConfigurationData()
                            .setInformedAboutIdea9TaskExperimentalSupport(dialog.isDoNotShowChecked());

                }
            });
        }
    }

    private void checkDefaultServerValues() {
        String text = "";
        if (projectCfgManager.getDefaultJiraServer() == null && projectCfgManager.getAllJiraServerss().size() > 0) {
            text = "JIRA";
        }

        if (text.length() > 0 && !pluginConfiguration.getGeneralConfigurationData().isAskedAboutDefaultServers()) {
            final InformationDialogWithCheckBox dialog = new InformationDialogWithCheckBox(project,
                    PluginUtil.PRODUCT_NAME, "Please set up default " + text + " server in order to get all "
                            + "cool features of " + PluginUtil.PRODUCT_NAME);
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    dialog.show();
                    pluginConfiguration.getGeneralConfigurationData()
                            .setAskedAboutDefaultServers(dialog.isDoNotShowChecked());
                }
            });
        }

    }

    public FileEditorListenerImpl getFileEditorListener() {
        return fileEditorListener;
    }

    private void askForUserStatistics() {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
            public void run() {
                if (pluginConfiguration.getGeneralConfigurationData()
                        .getAnonymousEnhancedFeedbackEnabled() == null) {
                    UsageStatsDialog dlg = new UsageStatsDialog();
                    dlg.show();
                    int answer = dlg.getExitCode();
                    boolean feedbackEnabled = answer == DialogWrapper.OK_EXIT_CODE;
                    pluginConfiguration.getGeneralConfigurationData()
                            .setAnonymousEnhancedFeedbackEnabled(feedbackEnabled);
                    InfoServer.reportOptInOptOut(pluginConfiguration.getGeneralConfigurationData().getUid(),
                            feedbackEnabled);
                }
            }
        }, ModalityState.defaultModalityState());
    }

    private class UsageStatsDialog extends DialogWrapper {
        private static final String MSG_TEXT = "We would greatly appreciate it if you would allow us to collect anonymous"
                + "<br>usage statistics to help us provide a better quality product. Details"
                + "<br>of what will be tracked are given " + "<a href=\""
                + UsageStatisticsGenerator.USAGE_STATS_HREF + "\">here</a>. Is this OK?";

        protected UsageStatsDialog() {
            super((Project) null, false);
            init();
            setTitle(PluginUtil.getInstance().getName() + " Request");
            setModal(true);
            setOKButtonText("Yes");
            setCancelButtonText("No");
        }

        @Override
        protected JComponent createCenterPanel() {
            JPanel p = new JPanel(new FormLayout("3dlu, p, 3dlu, p, 3dlu", "3dlu, p, 3dlu"));
            CellConstraints cc = new CellConstraints();

            JEditorPane textPane = new JEditorPane();
            textPane.setContentType("text/html");
            textPane.setEditable(false);
            textPane.setOpaque(false);
            textPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
            textPane.setText("<html>" + MSG_TEXT);
            textPane.addHyperlinkListener(new HyperlinkListener() {
                public void hyperlinkUpdate(HyperlinkEvent e) {
                    if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                        BrowserUtil.launchBrowser(e.getURL().toString());
                    }
                }
            });

            p.add(new JLabel(Messages.getQuestionIcon()), cc.xy(2, 2));
            p.add(textPane, cc.xy(4, 2));

            return p;
        }

    }

    public void projectClosed() {
        if (created) {
            pluginTaskManager.deactivateListner();
            fileEditorListener.projectClosed();
            // remove icon from status bar
            statusBarBambooIcon.hideIcon();
            statusBarBambooIcon = null;
            statusPluginUpdateIcon.hideIcon();
            statusPluginUpdateIcon = null;

            IdeaHelper.getAppComponent().getSchedulableCheckers().remove(bambooStatusChecker);
            IdeaHelper.getAppComponent().rescheduleStatusCheckers(true);
            // unregister listeners
            //bambooStatusChecker.unregisterListener(iconBambooStatusListener);
            //bambooStatusChecker.unregisterListener(toolWindowBambooListener);
            bambooStatusChecker.unregisterListener(tooltipBambooStatusListener);
            //unregister form model
            projectCfgManager.removeProjectConfigurationListener(configurationListener);
            configurationListener = null;
            projectCfgManager.removeProjectConfigurationListener(issuesToolWindowPanel.getConfigListener());

            // remove tool window
            toolWindowManager.unregisterToolWindow(PluginToolWindow.TOOL_WINDOW_NAME);

            created = false;
        }
    }

    public WorkspaceConfigurationBean getProjectConfigurationBean() {
        return projectConfigurationBean;
    }

    public BambooStatusChecker getBambooStatusChecker() {
        return bambooStatusChecker;
    }

    public JIRAIssueListModelBuilder getJiraIssueListModelBuilder() {
        return jiraIssueListModelBuilder;
    }

    private class ConfigurationListenerImpl extends ConfigurationListenerAdapter {

        @Override
        public void configurationUpdated(final ProjectConfiguration aProjectConfiguration) {
            // show-hide icons if necessary
            statusBarBambooIcon.showOrHideIcon();
            // show-hide panels if necessary
            toolWindow.showHidePanels();
        }
    }

}