1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.theplugin.util;
18
19 import com.atlassian.theplugin.commons.crucible.api.model.CrucibleFileInfo;
20 import com.atlassian.theplugin.idea.IdeaVersionFacade;
21 import com.atlassian.theplugin.idea.VcsIdeaHelper;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.openapi.vfs.VirtualFile;
24 import com.intellij.psi.PsiFile;
25 import org.apache.commons.io.FilenameUtils;
26 import org.apache.commons.lang.StringUtils;
27 import org.jetbrains.annotations.Nullable;
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Set;
32
33 public final class CodeNavigationUtil {
34
35 private CodeNavigationUtil() {
36
37 }
38
39
40
41
42 @Nullable
43 public static PsiFile guessMatchingFile(String pathname, PsiFile[] psifiles, VirtualFile baseDir) {
44
45
46
47 pathname = pathname.replace('\\', '/');
48
49 PsiFile bestMatch = null;
50
51 int difference = 0;
52
53 for (PsiFile psiFile : psifiles) {
54
55 String absolutePath = psiFile.getVirtualFile().getUrl();
56 if (absolutePath == null) {
57 continue;
58 }
59
60 int diff = StringUtils.indexOfDifference(StringUtils.reverse(pathname)
61 , StringUtils.reverse(absolutePath));
62 if (diff >= FilenameUtils.getName(absolutePath).length()
63 && (diff > difference || absolutePath.equals(pathname))) {
64 difference = diff;
65 bestMatch = psiFile;
66 if (absolutePath.equals(pathname)) {
67 break;
68 }
69 }
70 }
71 return bestMatch;
72 }
73
74
75
76
77
78
79
80
81 static Collection<PsiFile> getMatchingFiles(String filePath, final PsiFile[] psiFiles) {
82 filePath = filePath.replace('\\', '/');
83
84 Collection<PsiFile> match = new ArrayList<PsiFile>();
85
86 for (PsiFile psiFile : psiFiles) {
87 String absolutePath = psiFile.getVirtualFile().getUrl();
88 absolutePath = absolutePath.replace('\\', '/');
89 if (absolutePath == null) {
90 continue;
91 }
92
93 if (absolutePath.endsWith(FilenameUtils.getName(filePath)) && absolutePath.contains(filePath)) {
94 match.add(psiFile);
95 }
96 }
97 return match;
98 }
99
100 public static CrucibleFileInfo getBestMatchingCrucibleFileInfo(String path, Set<CrucibleFileInfo> files) {
101 path = path.replace('\\', '/');
102
103 CrucibleFileInfo bestMatch = null;
104 int difference = 0;
105
106 for (CrucibleFileInfo file : files) {
107 String pathname = "";
108 switch (file.getCommitType()) {
109 case Added:
110 case Modified:
111 case Copied:
112 case Moved:
113 pathname = file.getFileDescriptor().getAbsoluteUrl();
114 break;
115 case Deleted:
116 pathname = file.getOldFileDescriptor().getAbsoluteUrl();
117 break;
118 default:
119 pathname = file.getOldFileDescriptor().getAbsoluteUrl();
120 break;
121
122 }
123 int diff = StringUtils.indexOfDifference(StringUtils.reverse(path)
124 , StringUtils.reverse(pathname));
125 if (diff == -1 || (diff >= FilenameUtils.getName(pathname).length()
126 && (diff > difference || pathname.equals(path)))) {
127 difference = diff;
128 bestMatch = file;
129 if (pathname.equals(path)) {
130 break;
131 }
132 }
133 }
134 if (difference < StringUtils.reverse(path).indexOf('/')) {
135 return null;
136 }
137 return bestMatch;
138 }
139
140
141
142
143 @Nullable
144 public static PsiFile guessCorrespondingPsiFile(final Project project, final String filepath) {
145 final PsiFile[] psifiles = IdeaVersionFacade.getInstance().getFiles(FilenameUtils.getName(filepath), project);
146 return CodeNavigationUtil.guessMatchingFile(filepath, psifiles, project.getBaseDir());
147 }
148
149
150
151
152
153
154
155
156 @Nullable
157 public static Collection<PsiFile> findPsiFiles(final Project project, final String filePath) {
158
159 final PsiFile[] psifiles = IdeaVersionFacade.getInstance().getFiles(FilenameUtils.getName(filePath), project);
160
161 return CodeNavigationUtil.getMatchingFiles(filePath, psifiles);
162 }
163
164
165
166
167
168
169
170
171
172 public static Collection<PsiFile> findPsiFilesWithVcsUrl(final Collection<PsiFile> psiFiles, final String vcsUrl,
173 final Project project) {
174 Collection<PsiFile> retFiles = new ArrayList<PsiFile>();
175 if (psiFiles != null && vcsUrl != null && project != null) {
176 for (PsiFile psiFile : psiFiles) {
177 String repositoryUrl = VcsIdeaHelper.getRepositoryRootUrlForFile(project, psiFile.getVirtualFile());
178 if (repositoryUrl.equals(vcsUrl)) {
179 retFiles.add(psiFile);
180 }
181 }
182 }
183
184 return retFiles;
185 }
186 }