View Javadoc

1   package com.atlassian.theplugin.idea;
2   
3   import com.intellij.execution.RunnerAndConfigurationSettings;
4   import com.intellij.execution.configurations.RunProfile;
5   import com.intellij.openapi.actionSystem.*;
6   import com.intellij.openapi.application.ApplicationInfo;
7   import com.intellij.openapi.diff.BinaryContent;
8   import com.intellij.openapi.editor.Editor;
9   import com.intellij.openapi.fileTypes.FileType;
10  import com.intellij.openapi.fileTypes.FileTypeManager;
11  import com.intellij.openapi.project.Project;
12  import com.intellij.openapi.vcs.changes.Change;
13  import com.intellij.openapi.vcs.changes.ChangeListManager;
14  import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser;
15  import com.intellij.openapi.vcs.changes.ui.MultipleChangeListBrowser;
16  import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
17  import com.intellij.openapi.vfs.VirtualFile;
18  import com.intellij.openapi.wm.StatusBar;
19  import com.intellij.openapi.wm.WindowManager;
20  import com.intellij.psi.PsiClass;
21  import com.intellij.psi.PsiFile;
22  import com.intellij.psi.search.GlobalSearchScope;
23  import com.intellij.ui.LightweightHint;
24  import org.jetbrains.annotations.NotNull;
25  
26  import javax.swing.*;
27  import java.awt.*;
28  import java.io.IOException;
29  import java.lang.reflect.Constructor;
30  import java.lang.reflect.Field;
31  import java.lang.reflect.InvocationTargetException;
32  import java.lang.reflect.Method;
33  import java.nio.charset.Charset;
34  import java.util.ArrayList;
35  import java.util.Collection;
36  
37  public final class IdeaVersionFacade {
38  
39  	private static final int IDEA_8_0 = 8000;
40  	private boolean isIdea8;
41  	private static final int IDEA_8_0_1 = 9164;
42  
43  	private IdeaVersionFacade() {
44  		String ver = ApplicationInfo.getInstance().getBuildNumber();
45  		int v = Integer.parseInt(ver);
46  		isIdea8 = v > IDEA_8_0;
47  	}
48  
49  	private static IdeaVersionFacade instance;
50  
51  	public static IdeaVersionFacade getInstance() {
52  		if (instance == null) {
53  			instance = new IdeaVersionFacade();
54  		}
55  		return instance;
56  	}
57  
58  	public PsiClass findClass(String name, Project project) {
59  		PsiClass cls = null;
60  		try {
61  			if (isIdea8) {
62  				Class javaPsiFacadeClass = Class.forName("com.intellij.psi.JavaPsiFacade");
63  				Method getInstance = javaPsiFacadeClass.getMethod("getInstance", Project.class);
64  				Object inst = getInstance.invoke(null, project);
65  				Method findClass = javaPsiFacadeClass.getMethod("findClass", String.class, GlobalSearchScope.class);
66  				cls = (PsiClass) findClass.invoke(inst, name, GlobalSearchScope.allScope(project));
67  			} else {
68  				Class psiManagerClass = Class.forName("com.intellij.psi.PsiManager");
69  				Method getInstance = psiManagerClass.getMethod("getInstance", Project.class);
70  				Object inst = getInstance.invoke(null, project);
71  				Method findClass = psiManagerClass.getMethod("findClass", String.class, GlobalSearchScope.class);
72  				cls = (PsiClass) findClass.invoke(inst, name, GlobalSearchScope.allScope(project));
73  			}
74  		} catch (ClassNotFoundException e) {
75  			e.printStackTrace();
76  		} catch (NoSuchMethodException e) {
77  			e.printStackTrace();
78  		} catch (IllegalAccessException e) {
79  			e.printStackTrace();
80  		} catch (InvocationTargetException e) {
81  			e.printStackTrace();
82  		}
83  		return cls;
84  	}
85  
86  	public PsiFile[] getFiles(String filePath, Project project) {
87  		PsiFile[] psiFiles = null;
88  		try {
89  			if (isIdea8) {
90  				Class filenameIndexClass = Class.forName("com.intellij.psi.search.FilenameIndex");
91  				Method getFilesByName = filenameIndexClass.getMethod("getFilesByName", Project.class,
92  						String.class, GlobalSearchScope.class);
93  				Class projectScopeClass = Class.forName("com.intellij.psi.search.ProjectScope");
94  				Method getProjectScope = projectScopeClass.getMethod("getProjectScope", Project.class);
95  				GlobalSearchScope scope = (GlobalSearchScope) getProjectScope.invoke(null, project);
96  				psiFiles = (PsiFile[]) getFilesByName.invoke(null, project, filePath, scope);
97  			} else {
98  				Class psiManagerClass = Class.forName("com.intellij.psi.PsiManager");
99  				Method getInstance = psiManagerClass.getMethod("getInstance", Project.class);
100 				Object inst = getInstance.invoke(null, project);
101 				Method getShortNamesCache = psiManagerClass.getMethod("getShortNamesCache");
102 				Class psiShortNamesCacheClass = Class.forName("com.intellij.psi.search.PsiShortNamesCache");
103 				Object cacheInstance = getShortNamesCache.invoke(inst);
104 				Method getFilesByName = psiShortNamesCacheClass.getMethod("getFilesByName", String.class);
105 				psiFiles = (PsiFile[]) getFilesByName.invoke(cacheInstance, filePath);
106 			}
107 		} catch (ClassNotFoundException e) {
108 			e.printStackTrace();
109 		} catch (NoSuchMethodException e) {
110 			e.printStackTrace();
111 		} catch (IllegalAccessException e) {
112 			e.printStackTrace();
113 		} catch (InvocationTargetException e) {
114 			e.printStackTrace();
115 		}
116 		return psiFiles;
117 	}
118 
119 	public MultipleChangeListBrowser getChangesListBrowser(Project project, ChangeListManager changeListManager,
120 			final Collection<Change> changes) {
121 		try {
122 
123 			final ArrayList<Change> changeList;
124 			if (changes == null) {
125 				changeList = new ArrayList<Change>(
126 						changeListManager.getDefaultChangeList().getChanges());
127 			} else {
128 				changeList = new ArrayList<Change>(changes);
129 			}
130 			String ver = ApplicationInfo.getInstance().getBuildNumber();
131 			int v = Integer.parseInt(ver);
132 			if (v > IDEA_8_0_1) {
133 				Class browserClass = Class.forName("com.intellij.openapi.vcs.changes.ui.MultipleChangeListBrowser");
134 				Constructor[] constructors = browserClass.getConstructors();
135 				return (MultipleChangeListBrowser) constructors[0].newInstance(project, changeListManager.getChangeLists(),
136 						changeList, null, true, true, null);
137 			} else {
138 				Class browserClass = Class.forName("com.intellij.openapi.vcs.changes.ui.MultipleChangeListBrowser");
139 				Constructor[] constructors = browserClass.getConstructors();
140 				return (MultipleChangeListBrowser) constructors[0].newInstance(project, changeListManager.getChangeLists(),
141 						changeList, null, true, true);
142 			}
143 		} catch (ClassNotFoundException e) {
144 			e.printStackTrace();
145 		} catch (IllegalAccessException e) {
146 			e.printStackTrace();
147 		} catch (InvocationTargetException e) {
148 			e.printStackTrace();
149 		} catch (InstantiationException e) {
150 			e.printStackTrace();
151 		}
152 		return null;
153 	}
154 
155     public void addActionToDiffGroup(@NotNull AnAction action) {
156         if (isIdea8) {
157             DefaultActionGroup diffToolbar =
158                     (DefaultActionGroup) ActionManager.getInstance().getAction("DiffPanel.Toolbar");
159             if (diffToolbar != null) {
160                 diffToolbar.add(action);
161             }
162         }
163     }
164 
165 	public void showEditorHints(LightweightHint lightweightHint, Editor anEditor, Point point) {
166 		try {
167 			Class hintManagerClass = Class.forName("com.intellij.codeInsight.hint.HintManager");
168 			Method getInstance = hintManagerClass.getMethod("getInstance");
169 			Object inst = getInstance.invoke(null);
170 			Class mgrClass;
171 			if (isIdea8) {
172 				Class hintManagerImplClass = Class.forName("com.intellij.codeInsight.hint.HintManagerImpl");
173 				mgrClass = hintManagerImplClass;
174 				inst = hintManagerImplClass.cast(inst);
175 			} else {
176 				mgrClass = hintManagerClass;
177 			}
178 
179 			Method showEditorHint = mgrClass.getMethod("showEditorHint",
180 					LightweightHint.class, Editor.class, Point.class, int.class, int.class, boolean.class);
181 			Field hideByAnyKey = mgrClass.getField("HIDE_BY_ANY_KEY");
182 			Field hideByTextChange = mgrClass.getField("HIDE_BY_TEXT_CHANGE");
183 			Field hideByOtherHint = mgrClass.getField("HIDE_BY_OTHER_HINT");
184 			Field hideByScrolling = mgrClass.getField("HIDE_BY_SCROLLING");
185 			int hbak = (Integer) hideByAnyKey.get(null);
186 			int hbtc = (Integer) hideByTextChange.get(null);
187 			int hboh = (Integer) hideByOtherHint.get(null);
188 			int hbs = (Integer) hideByScrolling.get(null);
189 
190 			showEditorHint.invoke(inst, lightweightHint, anEditor, point, hbak | hbtc | hboh | hbs, -1, false);
191 		} catch (ClassNotFoundException e) {
192 			e.printStackTrace();
193 		} catch (NoSuchMethodException e) {
194 			e.printStackTrace();
195 		} catch (IllegalAccessException e) {
196 			e.printStackTrace();
197 		} catch (InvocationTargetException e) {
198 			e.printStackTrace();
199 		} catch (NoSuchFieldException e) {
200 			e.printStackTrace();
201 		}
202 	}
203 
204 	public void runTests(RunnerAndConfigurationSettings settings, AnActionEvent ev, boolean debug) {
205 		try {
206 			if (isIdea8) {
207 				Class executorClass = Class.forName("com.intellij.execution.Executor");
208 				Class defaultDebugExecutorClass = Class.forName("com.intellij.execution.executors.DefaultDebugExecutor");
209 				Class defaultRunExecutorClass = Class.forName("com.intellij.execution.executors.DefaultRunExecutor");
210 				Class executorRegistryClass = Class.forName("com.intellij.execution.ExecutorRegistry");
211 				Method getInstance = executorRegistryClass.getMethod("getInstance");
212 				Object executorRegistryInstance = getInstance.invoke(null);
213 				Method getExecutorById = executorRegistryClass.getMethod("getExecutorById", String.class);
214 				Class selectedExecutorClass = debug ? defaultDebugExecutorClass : defaultRunExecutorClass;
215 				Field executorIdField = selectedExecutorClass.getField("EXECUTOR_ID");
216 				String executorId = (String) executorIdField.get(null);
217 				Object executor = getExecutorById.invoke(executorRegistryInstance, executorId);
218 
219 				Class runnerClass = Class.forName("com.intellij.execution.runners.ProgramRunner");
220 				Class runnerRegistryClass = Class.forName("com.intellij.execution.RunnerRegistry");
221 				getInstance = runnerRegistryClass.getMethod("getInstance");
222 				Object runnerRegistryInstance = getInstance.invoke(null);
223 				Method getId = executorClass.getMethod("getId");
224 				String id = (String) getId.invoke(executor);
225 				Method getRunner = runnerRegistryClass.getMethod("getRunner", String.class, RunProfile.class);
226 				Object runner = getRunner.invoke(runnerRegistryInstance, id, settings.getConfiguration());
227 				if (runner != null) {
228 					try {
229 						Class executionEnvironmentClass = Class.forName(
230 								"com.intellij.execution.runners.ExecutionEnvironment");
231 						Constructor c = executionEnvironmentClass.getConstructor(
232 								runnerClass, RunnerAndConfigurationSettings.class, DataContext.class);
233 						Object executionEnvironment = c.newInstance(runner, settings, ev.getDataContext());
234 						Method execute = runnerClass.getMethod("execute", executorClass, executionEnvironmentClass);
235 						execute.invoke(runner, executor, executionEnvironment);
236 					} catch (Exception e) {
237 						e.printStackTrace();
238 					}
239 				}
240 
241 			} else {
242 				Class javaProgramRunnerClass = Class.forName("com.intellij.execution.runners.JavaProgramRunner");
243 				Class executionRegistryClass = Class.forName("com.intellij.execution.ExecutionRegistry");
244 				Class runStrategyClass = Class.forName("com.intellij.execution.runners.RunStrategy");
245 
246 				Method getInstance = executionRegistryClass.getMethod("getInstance");
247 				Object registryInstance = getInstance.invoke(null);
248 
249 				getInstance = runStrategyClass.getMethod("getInstance");
250 				Object strategyInstance = getInstance.invoke(null);
251 
252 				Method getRunner = executionRegistryClass.getMethod(debug ? "getDebuggerRunner" : "getDefaultRunner");
253 
254 				Object runner = getRunner.invoke(registryInstance);
255 
256 				Method execute = runStrategyClass.getMethod("execute",
257 						RunnerAndConfigurationSettings.class, javaProgramRunnerClass, DataContext.class);
258 
259 				try {
260 					execute.invoke(strategyInstance, settings, runner, ev.getDataContext());
261 				} catch (Exception e) {
262 					e.printStackTrace();
263 				}
264 			}
265 		} catch (ClassNotFoundException e) {
266 			e.printStackTrace();
267 		} catch (NoSuchMethodException e) {
268 			e.printStackTrace();
269 		} catch (IllegalAccessException e) {
270 			e.printStackTrace();
271 		} catch (InvocationTargetException e) {
272 			e.printStackTrace();
273 		} catch (NoSuchFieldException e) {
274 			e.printStackTrace();
275 		}
276 	}
277 
278 	public BinaryContent createBinaryContent(@NotNull final VirtualFile virtualFile) {
279 		BinaryContent content = null;
280 		FileType fileType = FileTypeManager.getInstance().getFileTypeByFile(virtualFile);
281 		try {
282 			Class binaryContentClass = Class.forName("com.intellij.openapi.diff.BinaryContent");
283 			Constructor constructor = binaryContentClass
284 					.getConstructor(new Class[]{byte[].class, isIdea8 ? Charset.class : String.class, FileType.class});
285 			return (BinaryContent) constructor.newInstance(virtualFile.contentsToByteArray(), null, fileType);
286 		} catch (ClassNotFoundException e) {
287 			e.printStackTrace();
288 		} catch (NoSuchMethodException e) {
289 			e.printStackTrace();
290 		} catch (IllegalAccessException e) {
291 			e.printStackTrace();
292 		} catch (IOException e) {
293 			e.printStackTrace();
294 		} catch (InvocationTargetException e) {
295 			e.printStackTrace();
296 		} catch (InstantiationException e) {
297 			e.printStackTrace();
298 		}
299 		return content;
300 	}
301 
302 	public void setCommitedChangesList(@NotNull final CommittedChangesTreeBrowser browser,
303 			@NotNull final java.util.List<CommittedChangeList> list, final boolean flag) {
304 		try {
305 			Method setItems = null;
306 			for (Method method : browser.getClass().getMethods()) {
307 				if (method.getName().equals("setItems")) {
308 					setItems = method;
309 					break;
310 				}
311 			}
312 			if (setItems == null) {
313 				return;
314 			}
315 			if (isIdea8) {
316 				Class enumClass = Class.forName("com.intellij.openapi.vcs.changes.committed.CommittedChangesBrowserUseCase");
317 				Method valueOf = enumClass.getMethod("valueOf", String.class);
318 				setItems.invoke(browser, list, flag, valueOf.invoke(null, "COMMITTED"));
319 			} else {
320 				setItems.invoke(browser, list, flag);
321 			}
322 		} catch (ClassNotFoundException e) {
323 			e.printStackTrace();
324 		} catch (IllegalAccessException e) {
325 			e.printStackTrace();
326 		} catch (InvocationTargetException e) {
327 			e.printStackTrace();
328 		} catch (NoSuchMethodException e) {
329 			e.printStackTrace();
330 		}
331 	}
332 
333 	public enum OperationStatus {
334 		INFO, WARNING, ERROR
335 	}
336 
337 	public void fireNofification(Project project, JComponent content, String message, String iconName, OperationStatus status,
338 			Color color) {
339 /*
340 		if (isIdea8) {
341 			ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
342 			if (toolWindowManager != null) {
343 				try {
344 					Method notifyByBalloon = null;
345 					for (Method method : toolWindowManager.getClass().getMethods()) {
346 						if (method.getName().equals("notifyByBalloon")) {
347 							Class<?>[] params = method.getParameterTypes();
348 							if (params.length == 5) {
349 								notifyByBalloon = method;
350 								break;
351 							}
352 						}
353 					}
354 					if (notifyByBalloon == null) {
355 						return;
356 					}
357 					Class messageTypeClass = Class.forName("com.intellij.openapi.ui.MessageType");
358 					HyperlinkListener listener = new HyperlinkListener() {
359 						public void hyperlinkUpdate(final HyperlinkEvent e) {
360 							if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
361 								URL url = e.getURL();
362 								BrowserUtil.launchBrowser(url.toString());
363 							}
364 						}
365 					};
366 					System.out.println("message = " + message);
367 					notifyByBalloon.invoke(toolWindowManager,
368 							new Object[]{PluginToolWindow.TOOL_WINDOW_NAME,
369 									messageTypeClass.getField(status.toString()).get(null),
370 									message, IconLoader.getIcon(iconName), listener});
371 				} catch (IllegalAccessException e) {
372 					e.printStackTrace();
373 				} catch (InvocationTargetException e) {
374 					e.printStackTrace();
375 				} catch (NoSuchFieldException e) {
376 					e.printStackTrace();
377 				} catch (ClassNotFoundException e) {
378 					e.printStackTrace();
379 				}
380 			}
381 		} else {
382 */
383 		final WindowManager windowManager = WindowManager.getInstance();
384 		if (windowManager != null) {
385 			final StatusBar statusBar = windowManager.getStatusBar(project);
386 			if (statusBar != null) {
387 				statusBar.fireNotificationPopup(content, color);
388 			}
389 		}
390 //		}
391 	}
392 }