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   * Copyright (C) 2008 Atlassian
18   *
19   * Licensed under the Apache License, Version 2.0 (the "License");
20   * you may not use this file except in compliance with the License.
21   * You may obtain a copy of the License at
22   *
23   *    http://www.apache.org/licenses/LICENSE-2.0
24   *
25   * Unless required by applicable law or agreed to in writing, software
26   * distributed under the License is distributed on an "AS IS" BASIS,
27   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28   * See the License for the specific language governing permissions and
29   * limitations under the License.
30   */
31  
32  package com.atlassian.theplugin.idea.crucible;
33  
34  import com.atlassian.theplugin.commons.VirtualFileSystem;
35  import com.atlassian.theplugin.commons.cfg.CrucibleServerCfg;
36  import com.atlassian.theplugin.commons.crucible.CrucibleServerFacade;
37  import com.atlassian.theplugin.commons.crucible.ValueNotYetInitialized;
38  import com.atlassian.theplugin.commons.crucible.api.model.Action;
39  import com.atlassian.theplugin.commons.crucible.api.model.*;
40  import com.atlassian.theplugin.commons.exception.ServerPasswordNotProvidedException;
41  import com.atlassian.theplugin.commons.remoteapi.RemoteApiException;
42  import com.atlassian.theplugin.cfg.CfgUtil;
43  import com.atlassian.theplugin.idea.IdeaHelper;
44  import com.intellij.ide.BrowserUtil;
45  import com.intellij.openapi.ui.DialogWrapper;
46  import com.intellij.openapi.ui.Messages;
47  import static com.intellij.openapi.ui.Messages.showMessageDialog;
48  import com.intellij.openapi.vcs.FileStatus;
49  import com.intellij.openapi.vcs.changes.Change;
50  import com.intellij.openapi.vcs.changes.ChangeList;
51  import com.intellij.uiDesigner.core.GridConstraints;
52  import com.intellij.uiDesigner.core.GridLayoutManager;
53  import org.jetbrains.annotations.Nullable;
54  
55  import javax.swing.*;
56  import java.awt.*;
57  import java.awt.event.*;
58  import static java.lang.System.arraycopy;
59  import java.util.*;
60  import java.util.List;
61  
62  enum ReviewCreationMode {
63  	EMPTY,
64  	REVISION,
65  	PATCH
66  }
67  
68  public class CrucibleReviewCreateForm extends DialogWrapper {
69  	private ReviewCreationMode mode;
70  
71  	private JTextArea patchPreview;
72  	private JPanel rootComponent;
73  	private JTextField titleText;
74  	private JComboBox crucibleServersComboBox;
75  	private JTextArea statementArea;
76  	private JCheckBox openBrowserToCompleteCheckBox;
77  	private JComboBox repoComboBox;
78  	private JComboBox projectsComboBox;
79  	private JComboBox authorComboBox;
80  	private JComboBox moderatorComboBox;
81  	private JList reviewersList;
82  	private JCheckBox allowCheckBox;
83  	private JCheckBox leaveAsDraftCheckBox;
84  	private JScrollPane patchPanel;
85  	private JLabel patchLabel;
86  	private String patchText;
87  	private DefaultListModel model;
88  
89  	private com.intellij.openapi.project.Project project;
90  	private CrucibleServerFacade crucibleServerFacade;
91  	private ChangeList[] changes;
92  
93  	public CrucibleReviewCreateForm(com.intellij.openapi.project.Project project, CrucibleServerFacade crucibleServerFacade,
94  			ChangeList[] changes) {
95  		this(project, crucibleServerFacade, "");
96  		this.mode = ReviewCreationMode.REVISION;
97  		this.changes = changes;
98  		if (changes.length == 1) {
99  			titleText.setText(changes[0].getName());
100 		} else {
101 			titleText.setText("");
102 		}
103 		showPatchPanel(false);
104 		setTitle("Create Review");
105 	}
106 
107 	public CrucibleReviewCreateForm(com.intellij.openapi.project.Project project, CrucibleServerFacade crucibleServerFacade,
108 			String commitMessage,
109 			String patch) {
110 		this(project, crucibleServerFacade, commitMessage);
111 		this.mode = ReviewCreationMode.PATCH;
112 		setPatchPreview(patch);
113 		showPatchPanel(true);
114 		setTitle("Create Patch Review");
115 	}
116 
117 	private CrucibleReviewCreateForm(com.intellij.openapi.project.Project project, CrucibleServerFacade crucibleServerFacade,
118 			String commitMessage) {
119 		super(false);
120 		this.project = project;
121 		this.crucibleServerFacade = crucibleServerFacade;
122 		$$$setupUI$$$();
123 		init();
124 		titleText.setText(commitMessage);
125 		getOKAction().putValue(javax.swing.Action.NAME, "Create review...");
126 		crucibleServersComboBox.addActionListener(new ActionListener() {
127 			public void actionPerformed(ActionEvent e) {
128 				if (crucibleServersComboBox.getItemCount() > 0 && crucibleServersComboBox.getSelectedItem() != null &&
129 						crucibleServersComboBox.getSelectedItem() instanceof ServerComboBoxItem) {
130 					final ServerComboBoxItem boxItem = (ServerComboBoxItem) crucibleServersComboBox.getSelectedItem();
131 					fillServerRelatedCombos(boxItem.getServer());
132 				}
133 			}
134 		});
135 
136 		reviewersList.addMouseListener(new MouseAdapter() {
137 			@Override
138 			public void mousePressed(MouseEvent e) {
139 				int index = reviewersList.locationToIndex(e.getPoint());
140 				setCheckboxState(index);
141 			}
142 		});
143 
144 		reviewersList.addKeyListener(new KeyAdapter() {
145 			@Override
146 			public void keyPressed(KeyEvent e) {
147 				if (e.getKeyCode() == KeyEvent.VK_SPACE) {
148 					int index = reviewersList.getSelectedIndex();
149 					setCheckboxState(index);
150 				}
151 			}
152 		});
153 
154 
155 		fillInCrucibleServers();
156 	}
157 
158 	private void showPatchPanel(boolean visible) {
159 		this.patchPanel.setVisible(visible);
160 		this.patchLabel.setVisible(visible);
161 	}
162 
163 	private void setCheckboxState(int index) {
164 		if (index != -1) {
165 			UserListItem pi = (UserListItem) reviewersList.getModel().getElementAt(index);
166 			pi.setSelected(!pi.isSelected());
167 			setViewState(index, pi.isSelected());
168 			repaint();
169 		}
170 	}
171 
172 	private void setViewState(int index, boolean newState) {
173 		int[] oldIdx = reviewersList.getSelectedIndices();
174 		int[] newIdx;
175 		if (newState) {
176 			newIdx = new int[oldIdx.length + 1];
177 			arraycopy(newIdx, 0, oldIdx, 0, oldIdx.length);
178 			newIdx[newIdx.length - 1] = index;
179 		} else {
180 			newIdx = new int[Math.max(0, oldIdx.length - 1)];
181 			int i = 0;
182 			for (int id : oldIdx) {
183 				if (id == index) {
184 					continue;
185 				}
186 				newIdx[i++] = id;
187 			}
188 		}
189 		reviewersList.setSelectedIndices(newIdx);
190 	}
191 
192 	@Override
193 	public JComponent getPreferredFocusedComponent() {
194 		return titleText;
195 	}
196 
197 	/**
198 	 * Method generated by IntelliJ IDEA GUI Designer
199 	 * >>> IMPORTANT!! <<<
200 	 * DO NOT edit this method OR call it in your code!
201 	 *
202 	 * @noinspection ALL
203 	 */
204 	private void $$$setupUI$$$() {
205 		createUIComponents();
206 		rootComponent = new JPanel();
207 		rootComponent.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
208 		rootComponent.setMinimumSize(new Dimension(760, 505));
209 		final JPanel panel1 = new JPanel();
210 		panel1.setLayout(new GridLayoutManager(14, 6, new Insets(1, 1, 1, 1), -1, -1));
211 		rootComponent.add(panel1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
212 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
213 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
214 		crucibleServersComboBox = new JComboBox();
215 		panel1.add(crucibleServersComboBox, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST,
216 				GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
217 				null, null, 0, false));
218 		final JLabel label1 = new JLabel();
219 		label1.setText("Server:");
220 		panel1.add(label1, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
221 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
222 		final JLabel label2 = new JLabel();
223 		label2.setText("Statement of Objectives:");
224 		panel1.add(label2, new GridConstraints(8, 0, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
225 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
226 		patchPanel = new JScrollPane();
227 		panel1.add(patchPanel, new GridConstraints(11, 0, 1, 6, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
228 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW,
229 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
230 		patchPreview = new JTextArea();
231 		patchPreview.setEditable(false);
232 		patchPreview.setEnabled(true);
233 		patchPreview.setFont(new Font("Monospaced", patchPreview.getFont().getStyle(), patchPreview.getFont().getSize()));
234 		patchPreview.setLineWrap(true);
235 		patchPreview.setRows(5);
236 		patchPreview.setText("");
237 		patchPanel.setViewportView(patchPreview);
238 		final JScrollPane scrollPane1 = new JScrollPane();
239 		panel1.add(scrollPane1, new GridConstraints(9, 0, 1, 6, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
240 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
241 		statementArea = new JTextArea();
242 		statementArea.setLineWrap(true);
243 		statementArea.setRows(5);
244 		scrollPane1.setViewportView(statementArea);
245 		patchLabel = new JLabel();
246 		patchLabel.setText("Patch:");
247 		panel1.add(patchLabel, new GridConstraints(10, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
248 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
249 		openBrowserToCompleteCheckBox = new JCheckBox();
250 		openBrowserToCompleteCheckBox.setSelected(false);
251 		openBrowserToCompleteCheckBox.setText("Open browser to complete review creation");
252 		panel1.add(openBrowserToCompleteCheckBox, new GridConstraints(12, 0, 1, 4, GridConstraints.ANCHOR_WEST,
253 				GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
254 				GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
255 		final JLabel label3 = new JLabel();
256 		label3.setText("Title:");
257 		panel1.add(label3, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
258 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
259 		final JLabel label4 = new JLabel();
260 		label4.setText("Moderator:");
261 		panel1.add(label4, new GridConstraints(5, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
262 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
263 		moderatorComboBox = new JComboBox();
264 		panel1.add(moderatorComboBox, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_WEST,
265 				GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
266 				null, null, 0, false));
267 		final JLabel label5 = new JLabel();
268 		label5.setInheritsPopupMenu(false);
269 		label5.setText("Project Key:");
270 		panel1.add(label5, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
271 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
272 		projectsComboBox = new JComboBox();
273 		panel1.add(projectsComboBox, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST,
274 				GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null,
275 				null, null, 0, false));
276 		final JLabel label6 = new JLabel();
277 		label6.setText("Repository Name:");
278 		panel1.add(label6, new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
279 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
280 		repoComboBox = new JComboBox();
281 		panel1.add(repoComboBox, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
282 				GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
283 		final JLabel label7 = new JLabel();
284 		label7.setText("Author:");
285 		panel1.add(label7, new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
286 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
287 		authorComboBox = new JComboBox();
288 		panel1.add(authorComboBox, new GridConstraints(6, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
289 				GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
290 		titleText = new JTextField();
291 		panel1.add(titleText, new GridConstraints(1, 0, 1, 6, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
292 				GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0,
293 				false));
294 		final JScrollPane scrollPane2 = new JScrollPane();
295 		panel1.add(scrollPane2, new GridConstraints(2, 3, 5, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, 1, 1,
296 				null, null, null, 0, false));
297 		scrollPane2.setViewportView(reviewersList);
298 		final JLabel label8 = new JLabel();
299 		label8.setText("Reviewers");
300 		panel1.add(label8, new GridConstraints(2, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
301 				GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
302 		allowCheckBox = new JCheckBox();
303 		allowCheckBox.setEnabled(true);
304 		allowCheckBox.setText("Allow anyone to join");
305 		panel1.add(allowCheckBox, new GridConstraints(7, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE,
306 				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED,
307 				null, null, null, 0, false));
308 		leaveAsDraftCheckBox = new JCheckBox();
309 		leaveAsDraftCheckBox.setText("Save review as Draft");
310 		panel1.add(leaveAsDraftCheckBox, new GridConstraints(13, 0, 1, 3, GridConstraints.ANCHOR_WEST,
311 				GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
312 				GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
313 		label1.setLabelFor(crucibleServersComboBox);
314 		label2.setLabelFor(statementArea);
315 		patchLabel.setLabelFor(patchPreview);
316 		label3.setLabelFor(titleText);
317 		label7.setLabelFor(scrollPane2);
318 	}
319 
320 	/**
321 	 * @noinspection ALL
322 	 */
323 	public JComponent $$$getRootComponent$$$() {
324 		return rootComponent;
325 	}
326 
327 	private static final class ServerComboBoxItem {
328 		private final CrucibleServerCfg server;
329 
330 		private ServerComboBoxItem(CrucibleServerCfg server) {
331 			this.server = server;
332 		}
333 
334 		@Override
335 		public String toString() {
336 			return server.getName();
337 		}
338 
339 		public CrucibleServerCfg getServer() {
340 			return server;
341 		}
342 	}
343 
344 	private static final class ProjectComboBoxItem {
345 		private final Project project;
346 
347 		private ProjectComboBoxItem(Project project) {
348 			this.project = project;
349 		}
350 
351 		@Override
352 		public String toString() {
353 			return project.getKey();
354 		}
355 
356 		public Project getProject() {
357 			return project;
358 		}
359 	}
360 
361 	private static final class RepositoryComboBoxItem {
362 		private final Repository repo;
363 
364 		private RepositoryComboBoxItem(Repository repo) {
365 			this.repo = repo;
366 		}
367 
368 		@Override
369 		public String toString() {
370 			return repo.getName();
371 		}
372 
373 		public Repository getRepository() {
374 			return repo;
375 		}
376 	}
377 
378 	private static final class UserComboBoxItem {
379 		private final User user;
380 
381 		private UserComboBoxItem(User user) {
382 			this.user = user;
383 		}
384 
385 		@Override
386 		public String toString() {
387 			return user.getDisplayName();
388 		}
389 
390 		public User getUser() {
391 			return user;
392 		}
393 	}
394 
395 
396 	private void fillInCrucibleServers() {
397 		final Collection<CrucibleServerCfg> enabledServers = IdeaHelper.getCfgManager()
398 				.getAllEnabledCrucibleServers(CfgUtil.getProjectId(project));
399 
400 		if (enabledServers.isEmpty()) {
401 			crucibleServersComboBox.setEnabled(false);
402 			crucibleServersComboBox.addItem("Enable a Crucible server first!");
403 			getOKAction().setEnabled(false);
404 		} else {
405 			for (CrucibleServerCfg server : enabledServers) {
406 				crucibleServersComboBox.addItem(new ServerComboBoxItem(server));
407 			}
408 		}
409 	}
410 
411 	private void fillServerRelatedCombos(final CrucibleServerCfg server) {
412 		projectsComboBox.removeAllItems();
413 		repoComboBox.removeAllItems();
414 		authorComboBox.removeAllItems();
415 		moderatorComboBox.removeAllItems();
416 		model.removeAllElements();
417 		getOKAction().setEnabled(false);
418 
419 		new Thread(new Runnable() {
420 			public void run() {
421 				List<Project> projects = new ArrayList<Project>();
422 				List<Repository> repositories = new ArrayList<Repository>();
423 				List<User> users = new ArrayList<User>();
424 
425 				try {
426 					projects = crucibleServerFacade.getProjects(server);
427 					repositories = crucibleServerFacade.getRepositories(server);
428 					users = crucibleServerFacade.getUsers(server);
429 				} catch (RemoteApiException e) {
430 					// nothing can be done here
431 				} catch (ServerPasswordNotProvidedException e) {
432 					// nothing can be done here
433 				}
434 				final List<Project> finalProjects = projects;
435 				final List<Repository> finalRepositories = repositories;
436 				final List<User> finalUsers = users;
437 				EventQueue.invokeLater(new Runnable() {
438 					public void run() {
439 						updateServerRelatedCombos(server, finalProjects, finalRepositories, finalUsers);
440 					}
441 				});
442 			}
443 		}, "atlassian-idea-plugin crucible patch upload combos refresh").start();
444 	}
445 
446 	private void updateServerRelatedCombos(
447 			CrucibleServerCfg server,
448 			List<Project> projects,
449 			List<Repository> repositories,
450 			List<User> users) {
451 		if (projects.isEmpty()) {
452 			projectsComboBox.setEnabled(false);
453 			projectsComboBox.addItem("No projects");
454 			getOKAction().setEnabled(false);
455 		} else {
456 			for (Project project : projects) {
457 				projectsComboBox.addItem(new ProjectComboBoxItem(project));
458 			}
459 			getOKAction().setEnabled(true);
460 		}
461 		repoComboBox.addItem("");
462 		if (!repositories.isEmpty()) {
463 			for (Repository repo : repositories) {
464 				repoComboBox.addItem(new RepositoryComboBoxItem(repo));
465 			}
466 			getOKAction().setEnabled(true);
467 		}
468 		// if only one repository
469 		if (this.mode == ReviewCreationMode.REVISION
470 				&& repositories.size() == 1) {
471 			repoComboBox.setSelectedIndex(repoComboBox.getItemCount() - 1);
472 		}
473 		authorComboBox.addItem("");
474 		moderatorComboBox.addItem("");
475 		if (!users.isEmpty()) {
476 			int indexToSelect = -1;
477 			int index = 0;
478 			for (User user : users) {
479 				authorComboBox.addItem(new UserComboBoxItem(user));
480 				moderatorComboBox.addItem(new UserComboBoxItem(user));
481 				if (!user.getUserName().equals(server.getUsername())) {
482 					model.addElement(new UserListItem(user, false));
483 				} else {
484 					indexToSelect = index + 1;
485 				}
486 				index++;
487 			}
488 			if (indexToSelect != -1) {
489 				authorComboBox.setSelectedIndex(indexToSelect);
490 				moderatorComboBox.setSelectedIndex(indexToSelect);
491 			}
492 		}
493 	}
494 
495 	public JComponent getRootComponent() {
496 		return rootComponent;
497 	}
498 
499 	public void setPatchPreview(String preview) {
500 		this.patchText = preview;
501 		patchPreview.setText(preview);
502 	}
503 
504 	@Override
505 	@Nullable
506 	protected JComponent createCenterPanel() {
507 		return getRootComponent();
508 	}
509 
510 	private class ReviewProvider implements Review {
511 		private final CrucibleServerCfg server;
512 
513 		public ReviewProvider(CrucibleServerCfg server) {
514 			this.server = server;
515 		}
516 
517 		public User getAuthor() {
518 			if (authorComboBox.getSelectedItem() instanceof UserComboBoxItem) {
519 				return ((UserComboBoxItem) authorComboBox.getSelectedItem()).getUser();
520 			} else {
521 				return null;
522 			}
523 		}
524 
525 		public User getCreator() {
526 			UserBean user = new UserBean();
527 			user.setUserName(server.getUsername());
528 			return user;
529 		}
530 
531 		public String getDescription() {
532 			return statementArea.getText();
533 		}
534 
535 		public User getModerator() {
536 			if (moderatorComboBox.getSelectedItem() instanceof UserComboBoxItem) {
537 				return ((UserComboBoxItem) moderatorComboBox.getSelectedItem()).getUser();
538 			} else {
539 				return null;
540 			}
541 		}
542 
543 		public String getName() {
544 			return titleText.getText();
545 		}
546 
547 		public PermId getParentReview() {
548 			return null;
549 		}
550 
551 		public PermId getPermId() {
552 			return null;
553 		}
554 
555 		public String getProjectKey() {
556 			return ((ProjectComboBoxItem) projectsComboBox.getSelectedItem()).getProject().getKey();
557 		}
558 
559 		public String getRepoName() {
560 			if (repoComboBox.getSelectedItem() instanceof RepositoryComboBoxItem) {
561 				return ((RepositoryComboBoxItem) repoComboBox.getSelectedItem()).getRepository().getName();
562 			} else {
563 				return null;
564 			}
565 		}
566 
567 		public State getState() {
568 			return null;
569 		}
570 
571 		public boolean isAllowReviewerToJoin() {
572 			return allowCheckBox.isSelected();
573 		}
574 
575 		public int getMetricsVersion() {
576 			return 0;
577 		}
578 
579 		public Date getCreateDate() {
580 			return null;
581 		}
582 
583 		public Date getCloseDate() {
584 			return null;
585 		}
586 
587 		public String getSummary() {
588 			return null;
589 		}
590 
591 		public List<Reviewer> getReviewers() throws ValueNotYetInitialized {
592 			return null;
593 		}
594 
595 		public List<GeneralComment> getGeneralComments() throws ValueNotYetInitialized {
596 			return null;
597 		}
598 
599 		public List<VersionedComment> getVersionedComments() throws ValueNotYetInitialized {
600 			return null;
601 		}
602 
603 		public List<CrucibleFileInfo> getFiles() throws ValueNotYetInitialized {
604 			return null;
605 		}
606 
607 		public List<Action> getTransitions() throws ValueNotYetInitialized {
608 			return null;
609 		}
610 
611 		public List<Action> getActions() throws ValueNotYetInitialized {
612 			return null;
613 		}
614 
615 		public VirtualFileSystem getVirtualFileSystem() {
616 			return null;
617 		}
618 
619 	}
620 
621 	@Override
622 	protected void doOKAction() {
623 		final ServerComboBoxItem selectedItem = (ServerComboBoxItem) crucibleServersComboBox.getSelectedItem();
624 
625 		if (selectedItem != null) {
626 			final CrucibleServerCfg server = selectedItem.getServer();
627 			Review review = new ReviewProvider(server);
628 
629 			try {
630 				Review draftReview = null;
631 				switch (mode) {
632 					case PATCH:
633 						draftReview =
634 								crucibleServerFacade.createReviewFromPatch(
635 										server, review, patchText);
636 						break;
637 					case REVISION:
638 						if (mode == ReviewCreationMode.REVISION
639 								&& review.getRepoName() == null) {
640 							Messages.showErrorDialog(project,
641 									"Repository not selected. Unable to create review.\n"
642 									, "Repository required");
643 							return;
644 						}
645 						List<String> revisions = new ArrayList<String>();
646 						for (ChangeList change : changes) {
647 							for (Change change1 : change.getChanges()) {
648 								if (change1.getFileStatus().equals(FileStatus.DELETED)) {
649 									revisions.add(change1.getBeforeRevision().getRevisionNumber().asString());
650 								} else {
651 									revisions.add(change1.getAfterRevision().getRevisionNumber().asString());
652 								}
653 								break;
654 							}
655 						}
656 						draftReview =
657 								crucibleServerFacade.createReviewFromRevision(
658 										server, review, revisions);
659 						break;
660 					case EMPTY:
661 						break;
662 				}
663 
664 				Set<String> users = new HashSet<String>();
665 				for (int i = 0; i < model.getSize(); ++i) {
666 					UserListItem item = (UserListItem) model.get(i);
667 					if (item.isSelected()) {
668 						users.add(item.getUser().getUserName());
669 					}
670 				}
671 
672 				if (!users.isEmpty()) {
673 					crucibleServerFacade.addReviewers(server, draftReview.getPermId(), users);
674 				}
675 
676 				if (!leaveAsDraftCheckBox.isSelected()) {
677 					try {
678 						Review newReview = crucibleServerFacade.getReview(server, draftReview.getPermId());
679 						if (newReview.getModerator().getUserName().equals(server.getUsername())) {
680 							if (newReview.getActions().contains(Action.APPROVE)) {
681 								crucibleServerFacade.approveReview(server, draftReview.getPermId());
682 							} else {
683 								Messages.showErrorDialog(project,
684 										newReview.getAuthor().getDisplayName() + " is authorized to approve review.\n" +
685 												"Leaving review in draft state."
686 										, "Permission denied");
687 							}
688 						} else {
689 							if (newReview.getActions().contains(Action.SUBMIT)) {
690 								crucibleServerFacade.submitReview(server, draftReview.getPermId());
691 							} else {
692 								Messages.showErrorDialog(project,
693 										newReview.getAuthor().getDisplayName() + " is authorized submit review.\n" +
694 												"Leaving review in draft state."
695 										, "Permission denied");
696 							}
697 						}
698 					} catch (ValueNotYetInitialized valueNotYetInitialized) {
699 						Messages.showErrorDialog(project,
700 								"Unable to change review state. Leaving review in draft state."
701 								, "Permission denied");
702 					}
703 				}
704 				if (openBrowserToCompleteCheckBox.isSelected()) {
705 					BrowserUtil.launchBrowser(server.getUrl()
706 							+ "/cru/"
707 							+ draftReview.getPermId().getId());
708 				}
709 
710 				super.doOKAction();
711 			} catch (RemoteApiException e) {
712 				showMessageDialog(e.getMessage(),
713 						"Error creating review: " + server.getUrl(), Messages.getErrorIcon());
714 			} catch (ServerPasswordNotProvidedException e) {
715 				showMessageDialog(e.getMessage(), "Error creating review: " + server.getUrl(), Messages.getErrorIcon());
716 			}
717 		}
718 	}
719 
720 	private void createUIComponents() {
721 		model = new DefaultListModel();
722 		reviewersList = new JList(model);
723 		reviewersList.setCellRenderer(new UserListCellRenderer());
724 		reviewersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
725 	}
726 }
727