View Javadoc

1   /**
2    * Copyright (C) 2008 Atlassian
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.atlassian.theplugin.idea;
18  
19  import com.atlassian.theplugin.commons.Server;
20  import com.atlassian.theplugin.commons.ServerType;
21  import com.atlassian.theplugin.commons.crucible.CrucibleServerFacade;
22  import com.atlassian.theplugin.commons.bamboo.*;
23  import com.atlassian.theplugin.commons.configuration.PluginConfiguration;
24  import com.atlassian.theplugin.commons.configuration.CrucibleTooltipOption;
25  import com.atlassian.theplugin.configuration.ProjectConfigurationBean;
26  import com.atlassian.theplugin.commons.crucible.CrucibleServerFacadeImpl;
27  import com.atlassian.theplugin.idea.autoupdate.ConfirmPluginUpdateHandler;
28  import com.atlassian.theplugin.idea.autoupdate.PluginUpdateIcon;
29  import com.atlassian.theplugin.idea.bamboo.BambooStatusIcon;
30  import com.atlassian.theplugin.idea.bamboo.BambooTableToolWindowPanel;
31  import com.atlassian.theplugin.idea.bamboo.BuildStatusChangedToolTip;
32  import com.atlassian.theplugin.idea.crucible.*;
33  import com.atlassian.theplugin.idea.crucible.comments.ReviewActionEventBroker;
34  import com.atlassian.theplugin.idea.jira.JIRAToolWindowPanel;
35  import com.atlassian.theplugin.jira.JIRAServer;
36  import com.intellij.ide.util.treeView.AbstractTreeNode;
37  import com.intellij.openapi.components.PersistentStateComponent;
38  import com.intellij.openapi.components.ProjectComponent;
39  import com.intellij.openapi.components.State;
40  import com.intellij.openapi.components.Storage;
41  import com.intellij.openapi.project.Project;
42  import com.intellij.openapi.startup.StartupManager;
43  import com.intellij.openapi.util.IconLoader;
44  import com.intellij.openapi.vcs.changes.ChangeListManager;
45  import com.intellij.openapi.wm.ToolWindowManager;
46  import com.intellij.peer.PeerFactory;
47  import com.intellij.ui.content.Content;
48  import com.intellij.ui.table.TableView;
49  import org.jetbrains.annotations.Nullable;
50  
51  import javax.swing.*;
52  import java.util.ArrayList;
53  import java.util.Collection;
54  import java.util.List;
55  
56  /**
57   * Per-project plugin component.
58   */
59  @State(name = "ThePluginSettings", storages = {@Storage(id = "thePlugin", file = "$PROJECT_FILE$") })
60  public class ThePluginProjectComponent implements
61          ProjectComponent,
62          PersistentStateComponent<ProjectConfigurationBean> {
63      private static final String THE_PLUGIN_TOOL_WINDOW_ICON = "/icons/ico_plugin_16.png";
64  
65      private final ProjectConfigurationBean projectConfigurationBean;
66  
67      private final Project project;
68      private BambooStatusIcon statusBarBambooIcon;
69  
70      private CrucibleStatusIcon statusBarCrucibleIcon;
71      private PluginUpdateIcon statusPluginUpdateIcon;
72      private final BambooStatusChecker bambooStatusChecker;
73      private StausIconBambooListener iconBambooStatusListener;
74      private BambooStatusTooltipListener tooltipBambooStatusListener;
75  	private CrucibleBottomToolWindowPanel crucibleBottomToolWindowPanel;
76  	private BambooTableToolWindowPanel bambooToolWindowPanel;
77      private CrucibleTableToolWindowPanel crucibleToolWindowPanel;
78  
79      private final CrucibleStatusChecker crucibleStatusChecker;
80      private final CrucibleServerFacade crucibleServerFacade;
81  
82      private final ToolWindowManager toolWindowManager;
83      private boolean created;
84      private CrucibleNewReviewNotifier crucibleNewReviewNotifier;
85  
86      private final PluginConfiguration pluginConfiguration;
87  
88      private JIRAToolWindowPanel jiraToolWindowPanel;
89      private JIRAServer currentJiraServer;
90  
91  	private PluginToolWindow toolWindow;
92  
93      private List<ReviewItemVirtualFile> reviewScopeFiles;
94      private String reviewId;
95  	private ReviewActionEventBroker crucibleActionBroker; // DON'T YOU DARE TO REMOVE IT!!!
96  														// (a strong reference that lives as long as the project itself)
97  
98  	public ThePluginProjectComponent(Project project,
99                                       CrucibleStatusChecker crucibleStatusChecker,
100                                      ToolWindowManager toolWindowManager,
101                                      /*BambooStatusChecker bambooStatusChecker,*/
102                                      PluginConfiguration pluginConfiguration,
103                                      /*BambooTableToolWindowPanel bambooToolWindowPanel,*/
104                                      /*CrucibleTableToolWindowPanel crucibleToolWindowPanel,*/
105                                      /*JIRAToolWindowPanel jiraToolWindowPanel,*/
106                                      ProjectConfigurationBean projectConfigurationBean
107                                      /*CrucibleServerFacade crucibleServerFacade*/) {
108 		this.project = project;
109 		this.crucibleActionBroker = ReviewActionEventBroker.getInstance();
110 		this.crucibleStatusChecker = crucibleStatusChecker;
111 		this.toolWindowManager = toolWindowManager;
112 		// todo remove that get instance as it can return null. it is better to get it from app component.
113 		this.bambooStatusChecker = BambooStatusChecker.getInstance();
114 		this.pluginConfiguration = pluginConfiguration;
115 		this.projectConfigurationBean = projectConfigurationBean;
116 		this.crucibleServerFacade = CrucibleServerFacadeImpl.getInstance();
117 		/*
118 
119 
120 										WARNING!!!
121 
122 
123 		BEFORE ADDING SOME INITIALIZATION CODE TO COSTRUCTOR THINK TWICE
124 
125 		...MAYBE YOU SHOULD PUT IT INTO THE initializePlugin METHOD
126 		(WHICH IS INVOKED WHEN THE ENTIRE PLUGIN ENVIRONMENT IS SET UP)?
127 
128 
129 		 */
130 		// make findBugs happy
131         statusBarBambooIcon = null;
132         statusBarCrucibleIcon = null;
133         statusPluginUpdateIcon = null;
134         created = false;
135         StartupManager.getInstance(project).registerPostStartupActivity(new Runnable() {
136             public void run() {
137                 System.out.println("Start: Project initializing");
138                 initializePlugin();
139                 System.out.println("End: Project initialized");
140             }
141         });
142 
143         reviewScopeFiles = new ArrayList<ReviewItemVirtualFile>();
144     }
145 
146     public void initComponent() {
147         System.out.println("Start: Init ThePlugin project component.");
148         System.out.println("End: Init ThePlugin project component.");
149         ChangeListManager.getInstance(project).registerCommitExecutor(
150                 new CruciblePatchSubmitExecutor(project, crucibleServerFacade));
151 
152     }
153 
154     public void disposeComponent() {
155         System.out.println("Start: Dispose ThePlugin project component");
156         System.out.println("End: Dispose ThePlugin project component");
157     }
158 
159     public String getComponentName() {
160         return "ThePluginProjectComponent";
161     }
162 
163     public PluginToolWindow getToolWindow() {
164         return toolWindow;
165     }
166 
167     private void initializePlugin() {
168         // unregister changelistmanager?
169         // only open tool windows for each application that's registered
170         // show something nice if there are non
171         // swap listener for dataretrievedlistener and datachangelisteners
172         // store bamboo between runs in UDC
173         // clean up object model confusion
174 
175         if (!created) {
176 
177             // DependencyValidationManager.getHolder(project, "", )
178 			this.bambooToolWindowPanel = BambooTableToolWindowPanel.getInstance(project, projectConfigurationBean);
179 			this.crucibleToolWindowPanel = CrucibleTableToolWindowPanel.getInstance(project, projectConfigurationBean);
180 			this.crucibleBottomToolWindowPanel = CrucibleBottomToolWindowPanel.getInstance(project, projectConfigurationBean);
181 			this.jiraToolWindowPanel = JIRAToolWindowPanel.getInstance(project, projectConfigurationBean);
182 
183 			// create tool window on the right
184             toolWindow = new PluginToolWindow(toolWindowManager, project);
185             Icon toolWindowIcon = IconLoader.getIcon(THE_PLUGIN_TOOL_WINDOW_ICON);
186             toolWindow.getIdeaToolWindow().setIcon(toolWindowIcon);
187 
188             // create tool window content
189             //Content bambooToolWindow = createBambooContent();
190             toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.BAMBOO);
191             toolWindow.showHidePanels();
192             TableView.restore(projectConfigurationBean.getBambooConfiguration().getTableConfiguration(),
193                     bambooToolWindowPanel.getTable());
194 
195             //Content crucibleToolWindow = createCrucibleContent();
196             toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.CRUCIBLE);
197             toolWindow.showHidePanels();
198 
199             //Content jiraToolWindow = createJiraContent();
200             toolWindow.registerPanel(PluginToolWindow.ToolWindowPanels.JIRA);
201             toolWindow.showHidePanels();
202             //PluginToolWindow.focusPanel(project, PluginToolWindow.ToolWindowPanels.JIRA);
203             //toolWindow.getIdeaToolWindow().getContentManager().setSelectedContent(jiraToolWindow);
204 
205 			toolWindow.registerBottomPanel(PluginToolWindow.ToolWindowPanels.CRUCIBLE_BOTTOM);
206 			toolWindow.showHidePanels();
207 
208 			TableView.restore(projectConfigurationBean.getJiraConfiguration().getTableConfiguration(),
209                     jiraToolWindowPanel.getTable());
210 
211             // add tool window bamboo content listener to bamboo checker thread
212             //toolWindowBambooListener = new StausIconBambooListener(bambooToolWindowPanel.getBambooContent());
213             bambooStatusChecker.registerListener(bambooToolWindowPanel);
214 
215             // create Bamboo status bar icon
216             statusBarBambooIcon = new BambooStatusIcon(this.project);
217             statusBarBambooIcon.updateBambooStatus(BuildStatus.UNKNOWN, new BambooPopupInfo());
218 
219             // add icon listener to bamboo checker thread
220             iconBambooStatusListener = new StausIconBambooListener(statusBarBambooIcon, pluginConfiguration);
221             bambooStatusChecker.registerListener(iconBambooStatusListener);
222 
223             // add simple bamboo listener to bamboo checker thread
224             // this listener shows idea tooltip when buld failed
225             BambooStatusDisplay buildFailedToolTip = new BuildStatusChangedToolTip(project);
226             tooltipBambooStatusListener = new BambooStatusTooltipListener(buildFailedToolTip, pluginConfiguration);
227             bambooStatusChecker.registerListener(tooltipBambooStatusListener);
228 
229             // add bamboo icon to status bar
230             //statusBar = WindowManager.getInstance().getStatusBar(project);
231             //statusBar.addCustomIndicationComponent(statusBarBambooIcon);
232             statusBarBambooIcon.showOrHideIcon();
233 
234             // setup Crucible status checker and listeners
235             crucibleStatusChecker.registerListener(crucibleToolWindowPanel);
236 
237             // create crucible status bar icon
238             statusBarCrucibleIcon = new CrucibleStatusIcon(project);
239 
240             crucibleNewReviewNotifier = new CrucibleNewReviewNotifier(statusBarCrucibleIcon, project);
241 			if (IdeaHelper.getPluginConfiguration().getCrucibleConfigurationData().getCrucibleTooltipOption()
242 					!= CrucibleTooltipOption.NEVER) {
243 				crucibleStatusChecker.registerListener(crucibleNewReviewNotifier);
244 			}
245 
246 			// add crucible icon to status bar
247             //statusBar.addCustomIndicationComponent(statusBarCrucibleIcon);
248             statusBarCrucibleIcon.showOrHideIcon();
249 
250             statusPluginUpdateIcon = new PluginUpdateIcon(project, pluginConfiguration);
251             ConfirmPluginUpdateHandler.getInstance().setDisplay(statusPluginUpdateIcon);
252             //statusPluginUpdateIcon.showOrHideIcon();
253 
254             toolWindow.showHidePanels();
255             // focus last active panel only if it exists (do not create panel)
256             PluginToolWindow.focusPanelIfExists(project, projectConfigurationBean.getActiveToolWindowTab());
257             toolWindow.startTabChangeListener();
258 
259             IdeaHelper.getAppComponent().rescheduleStatusCheckers(false);
260             if (!pluginConfiguration.getProductServers(ServerType.JIRA_SERVER).transientGetServers().isEmpty()) {
261                 long uuid = projectConfigurationBean.getJiraConfiguration().getSelectedServerId();
262                 for (Server server : pluginConfiguration.getProductServers(ServerType.JIRA_SERVER).transientGetServers()) {
263                     if (server.getUid() == uuid) {
264                         jiraToolWindowPanel.selectServer(server);
265                     }
266                 }
267             }
268 
269             created = true;
270         }
271     }
272 
273     public Content createBambooContent() {
274         PeerFactory peerFactory = PeerFactory.getInstance();
275 
276         Content content = peerFactory.getContentFactory().createContent(
277                 bambooToolWindowPanel,
278                 PluginToolWindow.ToolWindowPanels.BAMBOO.toString(),
279                 false);
280 
281         content.setIcon(IconLoader.getIcon("/icons/tab_bamboo.png"));
282         content.putUserData(com.intellij.openapi.wm.ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
283 
284         return content;
285     }
286 
287 	public Content createCrucibleBottomContent() {
288 		   PeerFactory peerFactory = PeerFactory.getInstance();
289 
290 		   Content content = peerFactory.getContentFactory().createContent(
291 				   crucibleBottomToolWindowPanel, PluginToolWindow.ToolWindowPanels.CRUCIBLE_BOTTOM.toString(), false);
292 		   content.setIcon(IconLoader.getIcon("/icons/tab_crucible.png"));
293 		   content.putUserData(com.intellij.openapi.wm.ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
294 
295 		   return content;
296 	   }
297 
298 	public Content createCrucibleContent() {
299         PeerFactory peerFactory = PeerFactory.getInstance();
300 
301         Content content = peerFactory.getContentFactory().createContent(
302                 crucibleToolWindowPanel, PluginToolWindow.ToolWindowPanels.CRUCIBLE.toString(), false);
303         content.setIcon(IconLoader.getIcon("/icons/tab_crucible.png"));
304         content.putUserData(com.intellij.openapi.wm.ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
305 
306         return content;
307     }
308 
309 
310     public Content createJiraContent() {
311         PeerFactory peerFactory = PeerFactory.getInstance();
312 
313         Content content = peerFactory.getContentFactory().createContent(
314                 jiraToolWindowPanel, PluginToolWindow.ToolWindowPanels.JIRA.toString(), false);
315         content.setIcon(IconLoader.getIcon("/icons/tab_jira.png"));
316         content.putUserData(com.intellij.openapi.wm.ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
317 
318         return content;
319     }
320 
321     public void disposePlugin() {
322         if (created) {
323             // remove icon from status bar
324             statusBarBambooIcon.hideIcon();
325             statusBarBambooIcon = null;
326             statusBarCrucibleIcon.hideIcon();
327             statusBarCrucibleIcon = null;
328             statusPluginUpdateIcon.hideIcon();
329             statusPluginUpdateIcon = null;
330 
331             // unregister listeners
332             //bambooStatusChecker.unregisterListener(iconBambooStatusListener);
333             //bambooStatusChecker.unregisterListener(toolWindowBambooListener);
334             bambooStatusChecker.unregisterListener(tooltipBambooStatusListener);
335             crucibleStatusChecker.unregisterListener(crucibleToolWindowPanel);
336             crucibleStatusChecker.unregisterListener(crucibleNewReviewNotifier);
337 
338             // remove tool window
339             toolWindow.stopTabChangeListener();
340             toolWindowManager.unregisterToolWindow(PluginToolWindow.TOOL_WINDOW_NAME);
341 
342             created = false;
343         }
344     }
345 
346     public void projectOpened() {
347         // content moved to StartupManager to wait until
348     }
349 
350     public void projectClosed() {
351         System.out.println("Start: Project close");
352         disposePlugin();
353         System.out.println("End: Project close");
354     }
355 
356     public BambooStatusIcon getStatusBarBambooIcon() {
357         return statusBarBambooIcon;
358     }
359 
360     public CrucibleStatusIcon getStatusBarCrucibleIcon() {
361         return statusBarCrucibleIcon;
362     }
363 
364     public ProjectConfigurationBean getState() {
365         return projectConfigurationBean;
366     }
367 
368     public void loadState(ProjectConfigurationBean state) {
369         projectConfigurationBean.copyConfiguration(state);
370     }
371 
372     public ProjectConfigurationBean getProjectConfigurationBean() {
373         return projectConfigurationBean;
374     }
375 
376     public JIRAServer getCurrentJiraServer() {
377         return currentJiraServer;
378     }
379 
380     public void setCurrentJiraServer(JIRAServer currentJiraServer) {
381         this.currentJiraServer = currentJiraServer;
382     }
383 
384     public CrucibleStatusChecker getCrucibleStatusChecker() {
385         return crucibleStatusChecker;
386     }
387 
388 	public CrucibleBottomToolWindowPanel getCrucibleBottomToolWindowPanel() {
389 		return crucibleBottomToolWindowPanel;
390 	}
391 
392 	public CrucibleNewReviewNotifier getCrucibleNewReviewNotifier() {
393 		return crucibleNewReviewNotifier;
394 	}
395 	
396 	public BambooStatusChecker getBambooStatusChecker() {
397         return bambooStatusChecker;
398     }
399 
400     @Nullable
401     public Object getData(Collection<AbstractTreeNode> abstractTreeNodes, String s) {
402         return null;
403     }
404 
405     public List<ReviewItemVirtualFile> getReviewScopeFiles() {
406         return reviewScopeFiles;
407     }
408 
409     public void setReviewScopeFiles(List<ReviewItemVirtualFile> reviewScopeFiles) {
410         this.reviewScopeFiles = reviewScopeFiles;
411     }
412 
413     public String getReviewId() {
414         return reviewId;
415     }
416 
417     public void setReviewId(String reviewId) {
418         this.reviewId = reviewId;
419     }
420 }