1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.theplugin.idea.jira;
18
19 import com.atlassian.theplugin.cfg.CfgUtil;
20 import com.atlassian.theplugin.commons.cfg.CfgManager;
21 import com.atlassian.theplugin.commons.cfg.JiraServerCfg;
22 import com.atlassian.theplugin.commons.cfg.ServerCfg;
23 import com.atlassian.theplugin.commons.cfg.ServerId;
24 import com.atlassian.theplugin.commons.configuration.PluginConfigurationBean;
25 import com.atlassian.theplugin.commons.util.LoggerImpl;
26 import com.atlassian.theplugin.configuration.JiraFilterEntryBean;
27 import com.atlassian.theplugin.configuration.JiraFiltersBean;
28 import com.atlassian.theplugin.configuration.ProjectConfigurationBean;
29 import com.atlassian.theplugin.configuration.ProjectToolWindowTableConfiguration;
30 import com.atlassian.theplugin.idea.IdeaHelper;
31 import com.atlassian.theplugin.idea.action.jira.FilterTypeAction;
32 import com.atlassian.theplugin.idea.action.jira.JIRANextPageAction;
33 import com.atlassian.theplugin.idea.action.jira.JIRAPreviousPageAcion;
34 import com.atlassian.theplugin.idea.action.jira.JIRAShowIssuesFilterAction;
35 import com.atlassian.theplugin.idea.action.jira.RunJIRAActionAction;
36 import com.atlassian.theplugin.idea.action.jira.SavedFilterComboAction;
37 import com.atlassian.theplugin.idea.jira.table.JIRATableColumnProviderImpl;
38 import com.atlassian.theplugin.idea.jira.table.columns.IssueKeyColumn;
39 import com.atlassian.theplugin.idea.jira.table.columns.IssuePriorityColumn;
40 import com.atlassian.theplugin.idea.jira.table.columns.IssueStatusColumn;
41 import com.atlassian.theplugin.idea.jira.table.columns.IssueSummaryColumn;
42 import com.atlassian.theplugin.idea.jira.table.columns.IssueTypeColumn;
43 import com.atlassian.theplugin.idea.ui.AbstractTableToolWindowPanel;
44 import com.atlassian.theplugin.idea.ui.TableColumnProvider;
45 import com.atlassian.theplugin.jira.JIRAServer;
46 import com.atlassian.theplugin.jira.JIRAServerFacade;
47 import com.atlassian.theplugin.jira.JIRAServerFacadeImpl;
48 import com.atlassian.theplugin.jira.api.JIRAAction;
49 import com.atlassian.theplugin.jira.api.JIRAException;
50 import com.atlassian.theplugin.jira.api.JIRAIssue;
51 import com.atlassian.theplugin.jira.api.JIRAQueryFragment;
52 import com.atlassian.theplugin.jira.api.JIRASavedFilterBean;
53 import com.atlassian.theplugin.remoteapi.MissingPasswordHandlerJIRA;
54 import com.intellij.ide.BrowserUtil;
55 import com.intellij.ide.DataManager;
56 import com.intellij.openapi.actionSystem.ActionGroup;
57 import com.intellij.openapi.actionSystem.ActionManager;
58 import com.intellij.openapi.actionSystem.ActionPlaces;
59 import com.intellij.openapi.actionSystem.ActionPopupMenu;
60 import com.intellij.openapi.actionSystem.ActionToolbar;
61 import com.intellij.openapi.actionSystem.AnAction;
62 import com.intellij.openapi.actionSystem.AnActionEvent;
63 import com.intellij.openapi.actionSystem.DefaultActionGroup;
64 import com.intellij.openapi.project.Project;
65 import com.intellij.openapi.ui.popup.JBPopupFactory;
66 import com.intellij.openapi.ui.popup.PopupChooserBuilder;
67 import com.intellij.openapi.util.Key;
68 import com.intellij.openapi.vcs.changes.ChangeListManager;
69 import com.intellij.openapi.vcs.changes.LocalChangeList;
70 import com.intellij.util.ui.UIUtil;
71
72 import javax.swing.*;
73 import java.awt.*;
74 import java.util.ArrayList;
75 import java.util.Calendar;
76 import java.util.List;
77 import java.util.Map;
78
79 public class JIRAToolWindowPanel extends AbstractTableToolWindowPanel<JiraIssueAdapter> {
80 private static final int PAGE_SIZE = 50;
81 public static final String JIRA_ATLASSIAN_TOOLWINDOW_SERVER_TOOL_BAR = "atlassian.jira.toolwindow";
82 private static final Key<JIRAToolWindowPanel> WINDOW_PROJECT_KEY = Key.create(JIRAToolWindowPanel.class.getName());
83
84 private transient ActionToolbar filterToolbar;
85 private transient ActionToolbar filterEditToolbar;
86 private JIRAIssueFilterPanel jiraIssueFilterPanel;
87
88 private TableColumnProvider columnProvider;
89
90 private transient JiraFiltersBean filters;
91 private transient JIRAQueryFragment savedQuery;
92 private final List<JIRAQueryFragment> advancedQuery;
93
94 private final transient JIRAServerFacade jiraServerFacade;
95 private final transient PluginConfigurationBean pluginConfiguration;
96
97 private int maxIndex = PAGE_SIZE;
98 private int startIndex = 0;
99 private boolean nextPageAvailable = false;
100 private boolean prevPageAvailable = false;
101 private String sortColumn = "issuekey";
102 private String sortOrder = "ASC";
103
104
105
106 private transient JIRAIssue selectedIssue = null;
107 private CfgManager cfgManager;
108
109 @Override
110 protected void handlePopupClick(Object selectedObject) {
111 selectedIssue = ((JiraIssueAdapter) selectedObject).getIssue();
112 }
113
114 public static JIRAToolWindowPanel getInstance(Project project, ProjectConfigurationBean projectConfigurationBean,
115 final CfgManager cfgManager) {
116
117 JIRAToolWindowPanel window = project.getUserData(WINDOW_PROJECT_KEY);
118
119 if (window == null) {
120 window = new JIRAToolWindowPanel(project, IdeaHelper.getPluginConfiguration(),
121 projectConfigurationBean, cfgManager);
122 project.putUserData(WINDOW_PROJECT_KEY, window);
123 }
124 return window;
125 }
126
127 @Override
128 protected void handleDoubleClick(Object selectedObject) {
129 AnAction action = ActionManager.getInstance().getAction("ThePlugin.JIRA.OpenIssue");
130 action.actionPerformed(new AnActionEvent(null, DataManager.getInstance().getDataContext(this),
131 ActionPlaces.UNKNOWN, action.getTemplatePresentation(),
132 ActionManager.getInstance(), 0));
133 }
134
135 @Override
136 protected String getInitialMessage() {
137 return "Select a JIRA server to retrieve your issues.";
138 }
139
140 @Override
141 protected String getToolbarActionGroup() {
142 return "ThePlugin.JIRA.ServerToolBar";
143 }
144
145 @Override
146 protected String getPopupActionGroup() {
147 return "ThePlugin.JIRA.IssuePopupMenu";
148 }
149
150 @Override
151 protected TableColumnProvider getTableColumnProvider() {
152 if (columnProvider == null) {
153 columnProvider = new JIRATableColumnProviderImpl();
154 }
155 return columnProvider;
156 }
157
158 @Override
159 protected ProjectToolWindowTableConfiguration getTableConfiguration() {
160 return projectConfiguration.getJiraConfiguration().getTableConfiguration();
161 }
162
163 public JIRAToolWindowPanel(Project project, PluginConfigurationBean pluginConfiguration,
164 ProjectConfigurationBean projectConfigurationBean, final CfgManager cfgManager) {
165 super(project, projectConfigurationBean);
166 this.cfgManager = cfgManager;
167 this.project = project;
168 this.pluginConfiguration = pluginConfiguration;
169 this.jiraServerFacade = JIRAServerFacadeImpl.getInstance();
170 this.advancedQuery = new ArrayList<JIRAQueryFragment>();
171
172 createFilterToolBar();
173 createFilterEditToolBar();
174
175 jiraIssueFilterPanel = new JIRAIssueFilterPanel(progressAnimation);
176 }
177
178 public List<JiraFilterEntryBean> serializeQuery() {
179 List<JiraFilterEntryBean> query = new ArrayList<JiraFilterEntryBean>();
180 for (JIRAQueryFragment jiraQueryFragment : advancedQuery) {
181 query.add(new JiraFilterEntryBean(jiraQueryFragment.getMap()));
182 }
183 return query;
184 }
185
186 public void restoreQuery(List<JiraFilterEntryBean> query, JiraFilterEntryBean savedFilter) {
187 advancedQuery.clear();
188 for (JiraFilterEntryBean filterMapBean : query) {
189 Map<String, String> filter = filterMapBean.getFilterEntry();
190 String className = filter.get("filterTypeClass");
191 try {
192 Class<?> c = Class.forName(className);
193 advancedQuery.add((JIRAQueryFragment) c.getConstructor(Map.class).newInstance(filter));
194 } catch (Exception e) {
195 LoggerImpl.getInstance().error(e);
196 }
197 }
198 if (savedFilter != null) {
199 savedQuery = new JIRASavedFilterBean(savedFilter.getFilterEntry());
200 } else {
201 savedQuery = null;
202 }
203 }
204
205 @Override
206 public void applyAdvancedFilter() {
207 advancedQuery.clear();
208 advancedQuery.addAll(jiraIssueFilterPanel.getFilter());
209 startIndex = 0;
210 updateIssues(IdeaHelper.getCurrentJIRAServer(project));
211 filters.setManualFilter(serializeQuery());
212 filters.setSavedFilterUsed(false);
213 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
214
215 if (jiraServer != null) {
216 projectConfiguration.
217 getJiraConfiguration().setFiltersBean(
218 jiraServer.getServer().getServerId().toString(), filters);
219 }
220
221 hideJIRAIssuesFilter();
222 filterToolbarSetVisible(true);
223 }
224
225 @Override
226 public void cancelAdvancedFilter() {
227 filters.setManualFilter(serializeQuery());
228 filters.setSavedFilterUsed(false);
229 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
230
231 if (jiraServer != null) {
232 projectConfiguration.getJiraConfiguration()
233 .setFiltersBean(jiraServer.getServer().getServerId().toString(), filters);
234 }
235
236 hideJIRAIssuesFilter();
237 filterToolbarSetVisible(true);
238 }
239
240 @Override
241 public void clearAdvancedFilter() {
242 advancedQuery.clear();
243 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
244 if (jiraServer != null) {
245 jiraIssueFilterPanel.setJiraServer(jiraServer, advancedQuery);
246 }
247 filterToolbarSetVisible(false);
248 filterEditToolbarSetVisible(true);
249 setScrollPaneViewport(jiraIssueFilterPanel.$$$getRootComponent$$$());
250 }
251
252 public String getActionPlace() {
253 return JIRA_ATLASSIAN_TOOLWINDOW_SERVER_TOOL_BAR + project.getName();
254 }
255
256 public final void hideJIRAIssuesFilter() {
257 setScrollPaneViewport(table);
258 filterEditToolbarSetVisible(false);
259 }
260
261 public final void showJIRAIssueFilter() {
262 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
263 if (jiraServer != null) {
264 jiraIssueFilterPanel.setJiraServer(jiraServer, advancedQuery);
265 }
266 filterToolbarSetVisible(false);
267 filterEditToolbarSetVisible(true);
268 setScrollPaneViewport(jiraIssueFilterPanel.$$$getRootComponent$$$());
269 }
270
271
272 public void viewIssue() {
273 final JiraIssueAdapter issueAdapter = table.getSelectedObject();
274 if (issueAdapter == null) {
275 return;
276 }
277 JIRAIssue issue = issueAdapter.getIssue();
278 BrowserUtil.launchBrowser(issue.getIssueUrl());
279 }
280
281 public void editIssue() {
282 final JiraIssueAdapter issueAdapter = table.getSelectedObject();
283 if (issueAdapter == null) {
284 return;
285 }
286 JIRAIssue issue = issueAdapter.getIssue();
287 BrowserUtil.launchBrowser(issue.getServerUrl() + "/secure/EditIssue!default.jspa?key=" + issue.getKey());
288 }
289
290 public void showIssueActions() {
291 final JiraIssueAdapter adapter = table.getSelectedObject();
292 if (adapter == null) {
293 return;
294 }
295 final JIRAIssue issue = adapter.getIssue();
296 List<JIRAAction> actions = adapter.getCachedActions();
297 if (actions != null) {
298 showActionsPopup(adapter, actions);
299 } else {
300 Thread thread = new Thread("atlassian-idea-plugin show issue actions") {
301 @Override
302 public void run() {
303 setStatusMessage("Getting available issue actions for issue " + issue.getKey() + "...");
304 try {
305 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
306 if (jiraServer != null) {
307 List<JIRAAction> actions =
308 jiraServerFacade.getAvailableActions(jiraServer.getServer(), issue);
309 adapter.setCachedActions(actions);
310 setStatusMessage("Retrieved actions for issue " + issue.getKey());
311 showActionsPopup(adapter, actions);
312 }
313 } catch (JIRAException e) {
314 setStatusMessage("Unable to retrieve available issue actions: " + e.getMessage(), true);
315 }
316 }
317
318 };
319 thread.start();
320 }
321 }
322
323 public void selectLastActiveServer() {
324
325 String uuidString = projectConfiguration.getJiraConfiguration().getSelectedServerId();
326
327 if (uuidString != null) {
328 final ServerId serverId = new ServerId(uuidString);
329 ServerCfg serverCfg = cfgManager.getServer(CfgUtil.getProjectId(project), serverId);
330 if (serverCfg != null && serverCfg instanceof JiraServerCfg && serverCfg.isEnabled()) {
331 selectServer((JiraServerCfg) serverCfg);
332 }
333 }
334 }
335
336 final class ActionsPopupListener implements Runnable {
337 private JiraIssueAdapter adapter;
338 private JList list;
339
340 public ActionsPopupListener(JiraIssueAdapter adapter, JList list) {
341 this.adapter = adapter;
342 this.list = list;
343 }
344
345 public void run() {
346 JIRAAction action = (JIRAAction) list.getSelectedValue();
347 RunJIRAActionAction ja = new RunJIRAActionAction(JIRAToolWindowPanel.this, jiraServerFacade, adapter, action);
348 ja.runIssueActionOrLaunchBrowser(project);
349 }
350 }
351
352 private void showActionsPopup(JiraIssueAdapter adapter, List<JIRAAction> actions) {
353 JList list = new JList();
354 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
355 DefaultListModel lm = new DefaultListModel();
356 for (JIRAAction a : actions) {
357 lm.addElement(a);
358 }
359 list.setModel(lm);
360 PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(list);
361 builder.setTitle("Actions available for " + adapter.getKey())
362 .setRequestFocus(true)
363 .setResizable(false)
364 .setMovable(true)
365 .setItemChoosenCallback(new ActionsPopupListener(adapter, list))
366 .createPopup()
367 .showInCenterOf(this);
368 }
369
370 @Override
371 protected void addCustomSubmenus(DefaultActionGroup actionGroup, final ActionPopupMenu popup) {
372 final DefaultActionGroup submenu = new DefaultActionGroup("Querying For Actions... ", true) {
373 @Override
374 public void update(AnActionEvent event) {
375 super.update(event);
376
377 if (getChildrenCount() > 0) {
378 event.getPresentation().setText("Issue Actions");
379 }
380 }
381 };
382 actionGroup.add(submenu);
383
384 final JiraIssueAdapter adapter = table.getSelectedObject();
385 if (adapter == null) {
386 return;
387 }
388 final JIRAIssue issue = adapter.getIssue();
389 List<JIRAAction> actions = adapter.getCachedActions();
390 if (actions != null) {
391 for (JIRAAction a : actions) {
392 submenu.add(new RunJIRAActionAction(this, jiraServerFacade, adapter, a));
393 }
394 } else {
395 new Thread() {
396 @Override
397 public void run() {
398 try {
399 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
400
401 if (jiraServer != null) {
402 final List<JIRAAction> actions =
403 jiraServerFacade.getAvailableActions(jiraServer.getServer(), issue);
404 adapter.setCachedActions(actions);
405 SwingUtilities.invokeLater(new Runnable() {
406 public void run() {
407 JPopupMenu pMenu = popup.getComponent();
408 if (pMenu.isVisible()) {
409 for (JIRAAction a : actions) {
410 submenu.add(new RunJIRAActionAction(JIRAToolWindowPanel.this,
411 jiraServerFacade, adapter, a));
412 }
413
414 pMenu.setVisible(false);
415 pMenu.setVisible(true);
416 }
417 }
418 });
419 }
420 } catch (JIRAException e) {
421 setStatusMessage("Query for issue actions failed: " + e.getMessage(), true);
422 } catch (NullPointerException e) {
423
424 }
425 }
426 }
427 .start();
428 }
429 }
430
431
432 public void refreshIssuesPage() {
433 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
434 if (jiraServer != null) {
435 updateIssues(jiraServer);
436 serializeQuery();
437 }
438 }
439
440 public void refreshIssues() {
441 startIndex = 0;
442 refreshIssuesPage();
443 }
444
445 public void clearIssues() {
446 listTableModel.setItems(new ArrayList<JiraIssueAdapter>());
447 listTableModel.fireTableDataChanged();
448 table.setEnabled(false);
449 editorPane.setText(wrapBody("No issues for selected criteria."));
450 }
451
452 public void setIssues(List<JIRAIssue> issues) {
453 List<JiraIssueAdapter> adapters = new ArrayList<JiraIssueAdapter>();
454 for (JIRAIssue issue : issues) {
455 adapters.add(new JiraIssueAdapter(
456 issue,
457 pluginConfiguration.getJIRAConfigurationData().isDisplayIconDescription()));
458 }
459 listTableModel.setItems(adapters);
460 listTableModel.fireTableDataChanged();
461 table.setEnabled(true);
462 table.setForeground(UIUtil.getActiveTextColor());
463
464 checkPrevPageAvaialble();
465 checkNextPageAvailable(issues);
466
467 editorPane.setText(wrapBody("Loaded <b>" + issues.size() + "</b> issues starting at <b>" + (startIndex + 1) + "</b>."));
468 }
469
470
471 public void selectServer(JiraServerCfg server) {
472 if (server != null) {
473 projectConfiguration.getJiraConfiguration().setSelectedServerId(server.getServerId().toString());
474 hideJIRAIssuesFilter();
475 final JIRAServer jiraServer = new JIRAServer(server, jiraServerFacade);
476 IdeaHelper.setCurrentJIRAServer(jiraServer);
477 new Thread(new SelectServerTask(jiraServer, this), "atlassian-idea-plugin jira tab select server").start();
478 }
479 }
480
481 private final class SelectServerTask implements Runnable {
482 private JIRAServer jiraServer;
483 private JIRAToolWindowPanel jiraPanel;
484
485 public SelectServerTask(JIRAServer jiraServer, JIRAToolWindowPanel jiraToolWindowPanel) {
486 this.jiraServer = jiraServer;
487 this.jiraPanel = jiraToolWindowPanel;
488 }
489
490 public void run() {
491 progressAnimation.startProgressAnimation();
492 filterToolbarSetVisible(false);
493 startIndex = 0;
494 clearIssues();
495
496 if (jiraServer.checkServer() == false) {
497 setStatusMessage("Unable to connect to server. " + jiraServer.getErrorMessage(), true);
498 progressAnimation.stopProgressAnimation();
499 EventQueue.invokeLater(new MissingPasswordHandlerJIRA(jiraServerFacade, jiraServer.getServer(), jiraPanel));
500 return;
501 }
502 setStatusMessage("Retrieving saved filters...");
503 jiraServer.getSavedFilters();
504
505 setStatusMessage("Retrieving projects...");
506 jiraServer.getProjects();
507
508 setStatusMessage("Retrieving issue types...");
509 jiraServer.getIssueTypes();
510
511 setStatusMessage("Retrieving statuses...");
512 jiraServer.getStatuses();
513
514 setStatusMessage("Retrieving resolutions...");
515 jiraServer.getResolutions();
516
517 setStatusMessage("Retrieving priorities...");
518 jiraServer.getPriorieties();
519
520 if (jiraServer.equals(IdeaHelper.getCurrentJIRAServer(project))) {
521 filters = projectConfiguration.getJiraConfiguration()
522 .getJiraFilters(IdeaHelper.getCurrentJIRAServer(project).getServer().getServerId().toString());
523 if (filters == null) {
524 filters = new JiraFiltersBean();
525 }
526 restoreQuery(filters.getManualFilter(), filters.getSavedFilter());
527 EventQueue.invokeLater(new Runnable() {
528 public void run() {
529 updateIssues(jiraServer);
530 }
531 });
532 filterToolbarSetVisible(true);
533 }
534
535 progressAnimation.stopProgressAnimation();
536 }
537 }
538
539 private void createFilterToolBar() {
540 ActionManager actionManager = ActionManager.getInstance();
541 DefaultActionGroup filterToolBar = new DefaultActionGroup("ThePlugin.JIRA.FilterToolBar" + project.getName(), false);
542
543 filterToolBar.add(new FilterTypeAction());
544 filterToolBar.add(new SavedFilterComboAction(project));
545 filterToolBar.add(new JIRAShowIssuesFilterAction());
546 filterToolBar.addSeparator();
547 filterToolBar.add(new JIRAPreviousPageAcion());
548 filterToolBar.add(new JIRANextPageAction());
549
550 filterToolbar = actionManager.createActionToolbar("atlassian.toolwindow.filterToolBar" + project.getName(),
551 filterToolBar, true);
552
553 toolBarPanel.add(filterToolbar.getComponent(), BorderLayout.CENTER);
554 filterToolbarSetVisible(false);
555 }
556
557 private void createFilterEditToolBar() {
558 ActionManager actionManager = ActionManager.getInstance();
559 ActionGroup filterEditToolBar = (ActionGroup) actionManager.getAction("ThePlugin.JIRA.FilterEditToolBar");
560 filterEditToolbar = actionManager.createActionToolbar("atlassian.toolwindow.filterEditToolBar",
561 filterEditToolBar, true);
562 toolBarPanel.add(filterEditToolbar.getComponent(), BorderLayout.SOUTH);
563 filterEditToolbarSetVisible(false);
564 }
565
566 private void filterToolbarSetVisible(boolean visible) {
567 filterToolbar.getComponent().setVisible(visible);
568 }
569
570 @Override
571 protected void filterEditToolbarSetVisible(boolean visible) {
572 filterEditToolbar.getComponent().setVisible(visible);
573 }
574
575 public void prevPage() {
576 startIndex -= PAGE_SIZE;
577 checkPrevPageAvaialble();
578 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
579 if (jiraServer != null) {
580 updateIssues(jiraServer);
581 }
582 }
583
584 public void nextPage() {
585 startIndex += PAGE_SIZE;
586 checkPrevPageAvaialble();
587 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
588 if (jiraServer != null) {
589 updateIssues(jiraServer);
590 }
591 }
592
593 private void checkPrevPageAvaialble() {
594 if (startIndex < 0) {
595 startIndex = 0;
596 }
597 if (startIndex == 0) {
598 prevPageAvailable = false;
599 } else {
600 prevPageAvailable = true;
601 }
602 }
603
604 private void checkNextPageAvailable(List<?> result) {
605 if (result.size() < PAGE_SIZE) {
606 nextPageAvailable = false;
607 } else {
608 nextPageAvailable = true;
609 }
610 }
611
612 private void disablePagesButton() {
613 prevPageAvailable = false;
614 nextPageAvailable = false;
615 }
616
617 private void updateIssues(final JIRAServer jiraServer) {
618 table.setEnabled(false);
619 table.setForeground(UIUtil.getInactiveTextColor());
620 clearIssues();
621 disablePagesButton();
622 new Thread(new IssueRefreshTask(jiraServer), "atlassian-idea-plugin jira tab update issues").start();
623 }
624
625 private final class IssueRefreshTask implements Runnable {
626 private JIRAServer jiraServer;
627
628 private IssueRefreshTask(JIRAServer jiraServer) {
629 this.jiraServer = jiraServer;
630 }
631
632 public void run() {
633 progressAnimation.startProgressAnimation();
634 JIRAServerFacade serverFacade = jiraServerFacade;
635 try {
636 List<JIRAQueryFragment> query = new ArrayList<JIRAQueryFragment>();
637 final List<JIRAIssue> result;
638 checkTableSort();
639 if (filters.getSavedFilterUsed()) {
640 if (savedQuery != null) {
641 query.add(savedQuery);
642 setStatusMessage("Retrieving issues from <b>" + jiraServer.getServer().getName() + "</b>...");
643 editorPane.setCaretPosition(0);
644 result = serverFacade.getSavedFilterIssues(jiraServer.getServer(),
645 query, sortColumn, sortOrder, startIndex, maxIndex);
646 EventQueue.invokeLater(new Runnable() {
647 public void run() {
648 setIssues(result);
649 }
650 });
651 }
652 } else {
653 for (JIRAQueryFragment jiraQueryFragment : advancedQuery) {
654 if (jiraQueryFragment.getId() != JIRAServer.ANY_ID) {
655 query.add(jiraQueryFragment);
656 }
657 }
658 setStatusMessage("Retrieving issues from <b>" + jiraServer.getServer().getName() + "</b>...");
659 editorPane.setCaretPosition(0);
660 result = serverFacade.getIssues(jiraServer.getServer(),
661 query, sortColumn, sortOrder, startIndex, maxIndex);
662 EventQueue.invokeLater(new Runnable() {
663 public void run() {
664 setIssues(result);
665 }
666 });
667 }
668 } catch (JIRAException e) {
669 setStatusMessage("Error contacting server <b>" + jiraServer.getServer().getName() + "</b>", true);
670 } finally {
671 progressAnimation.stopProgressAnimation();
672 }
673 }
674 }
675
676 private void checkTableSort() {
677 final int sortedColumnIndex = table.getTableViewModel().getSortedColumnIndex();
678
679 if (sortedColumnIndex < 0) {
680 return;
681 }
682
683
684 String columnName = table.getTableViewModel().getColumnName(sortedColumnIndex);
685
686 if (IssueTypeColumn.COLUMN_NAME.equals(columnName)) {
687 sortColumn = "issuetype";
688 } else {
689 if (IssueStatusColumn.COLUMN_NAME.equals(columnName)) {
690 sortColumn = "status";
691 } else {
692 if (IssuePriorityColumn.COLUMN_NAME.equals(columnName)) {
693 sortColumn = "priority";
694 } else {
695 if (IssueKeyColumn.COLUMN_NAME.equals(columnName)) {
696 sortColumn = "issuekey";
697 } else {
698 if (IssueSummaryColumn.COLUMN_NAME.equals(columnName)) {
699 sortColumn = "description";
700 }
701 }
702 }
703 }
704 }
705 if (table.getTableViewModel().getSortingType() == 1) {
706 if (IssuePriorityColumn.COLUMN_NAME.equals(columnName)) {
707 sortOrder = "DESC";
708 } else {
709 sortOrder = "ASC";
710 }
711 } else {
712 if (IssuePriorityColumn.COLUMN_NAME.equals(columnName)) {
713 sortOrder = "ASC";
714 } else {
715 sortOrder = "DESC";
716 }
717 }
718 }
719
720 public void addQueryFragment(JIRAQueryFragment fragment) {
721 savedQuery = fragment;
722 if (fragment != null) {
723 filters.setSavedFilter(new JiraFilterEntryBean(fragment.getMap()));
724 filters.setSavedFilterUsed(true);
725 } else {
726 filters.setSavedFilterUsed(false);
727 }
728 startIndex = 0;
729 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
730 if (jiraServer != null) {
731 projectConfiguration.getJiraConfiguration().
732 setFiltersBean(jiraServer.getServer().getServerId().toString(), filters);
733 }
734 }
735
736 @SuppressWarnings("unchecked")
737 public List<JiraIssueAdapter> getIssues() {
738 return listTableModel.getItems();
739 }
740
741 public JIRAIssue getCurrentIssue() {
742 Object selectedObject = table.getSelectedObject();
743 if (selectedObject != null) {
744 return ((JiraIssueAdapter) selectedObject).getIssue();
745 }
746 return null;
747 }
748
749 public void assignIssueToMyself() {
750 JiraIssueAdapter adapter = table.getSelectedObject();
751 if (adapter == null) {
752 return;
753 }
754 final JIRAIssue issue = adapter.getIssue();
755 try {
756 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
757 if (jiraServer != null) {
758 assignIssue(issue, jiraServer.getServer().getUsername());
759 }
760 } catch (NullPointerException ex) {
761
762 }
763 }
764
765 public void assignIssueToSomebody() {
766 final JIRAIssue issue = table.getSelectedObject().getIssue();
767
768 final GetUserNameDialog getUserNameDialog = new GetUserNameDialog(issue.getKey());
769 getUserNameDialog.show();
770 if (getUserNameDialog.isOK()) {
771 try {
772 assignIssue(issue, getUserNameDialog.getName());
773 } catch (NullPointerException ex) {
774
775 }
776 }
777 }
778
779 public void createChangeListAction(Project projectArg) {
780 JiraIssueAdapter adapter = table.getSelectedObject();
781 if (adapter == null) {
782 return;
783 }
784 final JIRAIssue issue = adapter.getIssue();
785 String changeListName = issue.getKey() + " - " + issue.getSummary();
786 final ChangeListManager changeListManager = ChangeListManager.getInstance(projectArg);
787
788 LocalChangeList changeList = changeListManager.findChangeList(changeListName);
789 if (changeList == null) {
790 ChangesetCreate c = new ChangesetCreate(issue.getKey());
791 c.setChangesetName(changeListName);
792 c.setChangestComment(changeListName + "\n");
793 c.setActive(true);
794 c.show();
795 if (c.isOK()) {
796 changeListName = c.getChangesetName();
797 changeList = changeListManager.addChangeList(changeListName, c.getChangesetComment());
798 if (c.isActive()) {
799 changeListManager.setDefaultChangeList(changeList);
800 }
801 }
802 } else {
803 changeListManager.setDefaultChangeList(changeList);
804 }
805 }
806
807 public void addCommentToIssue() {
808 JiraIssueAdapter adapter = table.getSelectedObject();
809 if (adapter == null) {
810 return;
811 }
812 final JIRAIssue issue = adapter.getIssue();
813 final IssueComment issueComment = new IssueComment(issue.getKey());
814 issueComment.show();
815 if (issueComment.isOK()) {
816 Thread thread = new Thread("atlassian-idea-plugin comment issue") {
817 @Override
818 public void run() {
819 setStatusMessage("Commenting issue " + issue.getKey() + "...");
820 try {
821 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
822 if (jiraServer != null) {
823 jiraServerFacade.addComment(jiraServer.getServer(),
824 issue, issueComment.getComment());
825 setStatusMessage("Commented issue " + issue.getKey());
826 }
827 } catch (JIRAException e) {
828 setStatusMessage("Issue not commented: " + e.getMessage(), true);
829 }
830 }
831
832 };
833 thread.start();
834 }
835 }
836
837 public void logWorkForIssue() {
838 JiraIssueAdapter adapter = table.getSelectedObject();
839 if (adapter == null) {
840 return;
841 }
842 final JIRAIssue issue = adapter.getIssue();
843 final WorkLogCreate workLogCreate = new WorkLogCreate(jiraServerFacade, adapter, project);
844 workLogCreate.show();
845 if (workLogCreate.isOK()) {
846 Thread thread = new Thread("atlassian-idea-plugin work log") {
847 @Override
848 public void run() {
849 setStatusMessage("Logging work for issue " + issue.getKey() + "...");
850 try {
851 Calendar cal = Calendar.getInstance();
852 cal.setTime(workLogCreate.getStartDate());
853 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
854
855 if (jiraServer != null) {
856 JiraServerCfg server = jiraServer.getServer();
857 String newRemainingEstimate = workLogCreate.getUpdateRemainingManually()
858 ? workLogCreate.getRemainingEstimateString() : null;
859 jiraServerFacade.logWork(server, issue, workLogCreate.getTimeSpentString(),
860 cal, workLogCreate.getComment(),
861 !workLogCreate.getLeaveRemainingUnchanged(), newRemainingEstimate);
862 if (workLogCreate.isStopProgressSelected()) {
863 setStatusMessage("Stopping work for issue " + issue.getKey() + "...");
864 jiraServerFacade.progressWorkflowAction(server, issue, workLogCreate.getInProgressAction());
865 setStatusMessage("Work logged and progress stopped for issue " + issue.getKey());
866 refreshIssuesPage();
867 } else {
868 setStatusMessage("Logged work for issue " + issue.getKey());
869 }
870 }
871 } catch (JIRAException e) {
872 setStatusMessage("Work not logged: " + e.getMessage(), true);
873 }
874 }
875
876 };
877 thread.start();
878 }
879 }
880
881 private void assignIssue(final JIRAIssue issue, final String assignee) {
882 Thread thread = new Thread("atlassian-idea-plugin assign issue issue") {
883 @Override
884 public void run() {
885 setStatusMessage("Assigning issue " + issue.getKey() + " to " + assignee + "...");
886 try {
887
888 JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
889 if (jiraServer != null) {
890 jiraServerFacade.setAssignee(jiraServer.getServer(), issue, assignee);
891 setStatusMessage("Assigned issue " + issue.getKey() + " to " + assignee);
892 }
893 } catch (JIRAException e) {
894 setStatusMessage("Failed to assign issue: " + e.getMessage(), true);
895 }
896 }
897
898 };
899 thread.start();
900 }
901
902 public void createIssue() {
903 final JIRAServer jiraServer = IdeaHelper.getCurrentJIRAServer(project);
904
905 if (jiraServer != null) {
906 final IssueCreate issueCreate = new IssueCreate(jiraServer);
907 issueCreate.initData();
908 issueCreate.show();
909 if (issueCreate.isOK()) {
910 Thread thread = new Thread("atlassian-idea-plugin create issue") {
911
912 @Override
913 public void run() {
914 setStatusMessage("Creating new issue...");
915 JIRAIssue newIssue;
916 String message;
917 boolean isError = false;
918 try {
919 newIssue = jiraServerFacade.createIssue(jiraServer.getServer(), issueCreate.getJIRAIssue());
920 message =
921 "New issue created: <a href="
922 + newIssue.getIssueUrl()
923 + ">"
924 + newIssue.getKey()
925 + "</a>";
926 } catch (JIRAException e) {
927 message = "Failed to create new issue: " + e.getMessage();
928 isError = true;
929 }
930
931 setStatusMessage(message, isError);
932 }
933 };
934 thread.start();
935 }
936 }
937 }
938
939 public JiraFiltersBean getFilters() {
940 return filters;
941 }
942
943 public boolean isNextPageAvailable() {
944 return nextPageAvailable;
945 }
946
947 public boolean isPrevPageAvailable() {
948 return prevPageAvailable;
949 }
950
951 public JIRAIssue getSelectedIssue() {
952 return selectedIssue;
953 }
954 }