1 package com.atlassian.theplugin.idea.crucible;
2
3 import com.atlassian.theplugin.commons.crucible.api.model.ReviewItem;
4 import com.atlassian.theplugin.commons.crucible.api.model.VersionedComment;
5 import com.atlassian.theplugin.commons.crucible.CrucibleServerFacadeImpl;
6 import com.atlassian.theplugin.commons.remoteapi.RemoteApiException;
7 import com.atlassian.theplugin.commons.exception.ServerPasswordNotProvidedException;
8 import com.atlassian.theplugin.idea.IdeaHelper;
9 import com.atlassian.theplugin.idea.VcsIdeaHelper;
10 import com.atlassian.theplugin.util.PluginUtil;
11 import com.intellij.openapi.editor.Editor;
12 import com.intellij.openapi.editor.Document;
13 import com.intellij.openapi.editor.markup.TextAttributes;
14 import com.intellij.openapi.editor.markup.RangeHighlighter;
15 import com.intellij.openapi.editor.markup.HighlighterLayer;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.vfs.VirtualFile;
18 import com.intellij.openapi.vfs.VfsUtil;
19 import com.intellij.openapi.vfs.VirtualFileManager;
20 import com.intellij.openapi.fileEditor.FileEditorManager;
21 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
22 import com.intellij.openapi.fileEditor.FileEditor;
23 import com.intellij.openapi.vcs.history.VcsFileRevision;
24 import com.intellij.openapi.vcs.vfs.VcsVirtualFile;
25 import com.intellij.openapi.vcs.vfs.VcsFileSystem;
26
27 import java.util.Collection;
28 import java.util.ArrayList;
29 import java.util.Map;
30 import java.util.Set;
31 import java.awt.*;
32 import java.net.URL;
33 import java.net.MalformedURLException;
34
35
36
37
38
39
40
41
42 public final class CrucibleHelper {
43
44
45 private static final Color VERSIONED_COMMENT_BACKGROUND_COLOR = Color.LIGHT_GRAY;
46 private static final Color VERSIONED_COMMENT_STRIP_MARK_COLOR = Color.BLUE;
47
48 private CrucibleHelper(){};
49
50
51 public static void showVirtualFileWithComments(final Project project, final ReviewItem reviewItem, final Collection<VersionedComment> fileComments){
52
53 int line = 1;
54
55 if (!fileComments.isEmpty()){
56 line = fileComments.iterator().next().getFromStartLine();
57 }
58
59 Editor editor = showVirtualFileInEditor(project, getOpenFileDescriptor(project, reviewItem.getToPath(), reviewItem.getToRevision(), line, 1));
60 TextAttributes textAttributes = new TextAttributes();
61 textAttributes.setBackgroundColor(VERSIONED_COMMENT_BACKGROUND_COLOR);
62 highlightCommentsInEditor(project, editor, reviewItem,fileComments, textAttributes);
63 }
64
65
66
67
68
69
70
71 public static void showVirtualFileWithComments(Project project, final ReviewDataInfoAdapter reviewAdapter, final ReviewItem reviewItem){
72 Collection<VersionedComment> fileComments = null;
73 try {
74
75 fileComments = CrucibleServerFacadeImpl.getInstance().getVersionedComments(reviewAdapter.getServer(), reviewAdapter.getPermaId(), reviewItem.getPermId());
76 showVirtualFileWithComments(project, reviewItem, fileComments);
77 } catch (RemoteApiException e) {
78 PluginUtil.getLogger().error(e.getMessage());
79 } catch (ServerPasswordNotProvidedException e) {
80 PluginUtil.getLogger().error(e.getMessage());
81 }
82 }
83
84
85
86
87 public static Editor showVirtualFileInEditor(Project project, OpenFileDescriptor ofd){
88 Editor editor = null;
89
90 if (ofd != null) {
91 FileEditorManager fem = FileEditorManager.getInstance(project);
92 editor = fem.openTextEditor(ofd, true);
93 }
94
95 return editor;
96 }
97
98
99
100
101
102 public static void selectVersionedCommentLineInEditor(Project project, ReviewItem reviewItem, VersionedComment comment){
103 OpenFileDescriptor ofd = getOpenFileDescriptor(project, reviewItem.getToPath(), reviewItem.getToRevision(), comment.getFromStartLine(), 1);
104
105 if (ofd != null) {
106 FileEditorManager fem = FileEditorManager.getInstance(project);
107 fem.openTextEditor(ofd, true);
108 }
109
110 }
111
112 private static OpenFileDescriptor getOpenFileDescriptor(Project project, String filePath, String fileRevision, int line, int col){
113 VirtualFile baseDir = project.getBaseDir();
114 String baseUrl = VcsIdeaHelper.getRepositoryUrlForFile(baseDir);
115 OpenFileDescriptor ofd = null;
116 VcsVirtualFile vcvf = null;
117
118 if (baseUrl != null && filePath.startsWith(baseUrl)) {
119
120 String relUrl = filePath.substring(baseUrl.length());
121
122
123 VirtualFile vfl = null;
124
125
126
127
128
129
130 vfl = VfsUtil.findRelativeFile(relUrl, baseDir);
131
132 VirtualFile[] openFiles = FileEditorManager.getInstance(project).getOpenFiles();
133
134 for(VirtualFile file: openFiles) {
135 if (file.getPath().equals(filePath) && file instanceof VcsVirtualFile && ((VcsVirtualFile)file).getRevision().equals(fileRevision)) {
136 vcvf = (VcsVirtualFile)file;
137 }
138 }
139
140
141 if (vcvf == null) {
142 VcsFileRevision revision = VcsIdeaHelper.getFileRevision(vfl, fileRevision);
143 if (revision != null) {
144 vcvf = new VcsVirtualFile(filePath,revision, VcsFileSystem.getInstance());
145 }
146 }
147
148 ofd = new OpenFileDescriptor(project, vcvf, line, col);
149
150 }
151
152
153 return ofd;
154 }
155
156 private static void highlightCommentsInEditor(Project project, Editor editor, ReviewItem reviewItem, Collection<VersionedComment> fileVersionedComments, TextAttributes textAttribute){
157 Collection<RangeHighlighter> ranges = new ArrayList<RangeHighlighter>();
158
159
160 if (editor != null) {
161 for (VersionedComment comment: fileVersionedComments) {
162
163 RangeHighlighter rh = editor.getDocument().getMarkupModel(project).addLineHighlighter( comment.getFromStartLine(), HighlighterLayer.SELECTION, textAttribute);
164 rh.setErrorStripeTooltip(reviewItem.getPermId().getId() +":" + comment.getMessage());
165 rh.setErrorStripeMarkColor(VERSIONED_COMMENT_STRIP_MARK_COLOR);
166
167
168 }
169 }
170 }
171 }