ComponentWithBrowseButton - optional remove listener on hide
[fedora-idea.git] / plugins / maven / src / main / java / org / jetbrains / idea / maven / utils / MavenUtil.java
blob48aa53d48e9445b0982c74f9a29775eb9658594a
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org.jetbrains.idea.maven.utils;
18 import com.intellij.codeInsight.template.TemplateManager;
19 import com.intellij.codeInsight.template.impl.TemplateImpl;
20 import com.intellij.ide.fileTemplates.FileTemplate;
21 import com.intellij.ide.fileTemplates.FileTemplateManager;
22 import com.intellij.notification.Notification;
23 import com.intellij.notification.NotificationType;
24 import com.intellij.notification.Notifications;
25 import com.intellij.openapi.application.ApplicationManager;
26 import com.intellij.openapi.application.ModalityState;
27 import com.intellij.openapi.application.PathManager;
28 import com.intellij.openapi.application.impl.LaterInvocator;
29 import com.intellij.openapi.editor.Editor;
30 import com.intellij.openapi.fileEditor.FileEditorManager;
31 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
32 import com.intellij.openapi.progress.ProcessCanceledException;
33 import com.intellij.openapi.progress.ProgressIndicator;
34 import com.intellij.openapi.progress.ProgressManager;
35 import com.intellij.openapi.progress.Task;
36 import com.intellij.openapi.project.DumbAware;
37 import com.intellij.openapi.project.DumbService;
38 import com.intellij.openapi.project.Project;
39 import com.intellij.openapi.startup.StartupManager;
40 import com.intellij.openapi.util.Pair;
41 import com.intellij.openapi.util.io.FileUtil;
42 import com.intellij.openapi.vfs.VfsUtil;
43 import com.intellij.openapi.vfs.VirtualFile;
44 import com.intellij.util.Function;
45 import com.intellij.util.ReflectionUtil;
46 import com.intellij.util.containers.ContainerUtil;
47 import gnu.trove.THashSet;
48 import org.apache.commons.beanutils.BeanUtils;
49 import org.apache.maven.model.Model;
50 import org.codehaus.plexus.util.xml.Xpp3Dom;
51 import org.jetbrains.annotations.NotNull;
52 import org.jetbrains.idea.maven.project.MavenId;
53 import org.jetbrains.idea.maven.project.MavenProject;
55 import java.io.File;
56 import java.io.IOException;
57 import java.io.Serializable;
58 import java.lang.reflect.Field;
59 import java.lang.reflect.InvocationTargetException;
60 import java.net.URL;
61 import java.util.*;
62 import java.util.concurrent.ExecutionException;
63 import java.util.concurrent.Future;
64 import java.util.regex.Matcher;
65 import java.util.regex.Pattern;
66 import java.util.regex.PatternSyntaxException;
68 public class MavenUtil {
69 public static void invokeLater(Project p, Runnable r) {
70 invokeLater(p, ModalityState.defaultModalityState(), r);
73 public static void invokeLater(final Project p, final ModalityState state, final Runnable r) {
74 if (isNoBackgroundMode()) {
75 r.run();
77 else {
78 ApplicationManager.getApplication().invokeLater(new Runnable() {
79 public void run() {
80 if (p.isDisposed()) return;
81 r.run();
83 }, state);
87 public static void invokeAndWait(Project p, Runnable r) {
88 invokeAndWait(p, ModalityState.defaultModalityState(), r);
91 public static void invokeAndWait(final Project p, final ModalityState state, final Runnable r) {
92 if (isNoBackgroundMode()) {
93 r.run();
95 else {
96 if (ApplicationManager.getApplication().isDispatchThread()) {
97 r.run();
99 else {
100 ApplicationManager.getApplication().invokeAndWait(new Runnable() {
101 public void run() {
102 if (p.isDisposed()) return;
103 r.run();
105 }, state);
110 public static void invokeAndWaitWriteAction(Project p, final Runnable r) {
111 invokeAndWait(p, new Runnable() {
112 public void run() {
113 ApplicationManager.getApplication().runWriteAction(r);
118 public static void runDumbAware(final Project project, final Runnable r) {
119 if (r instanceof DumbAware) {
120 r.run();
122 else {
123 DumbService.getInstance(project).runWhenSmart(new Runnable() {
124 public void run() {
125 if (project.isDisposed()) return;
126 r.run();
132 public static void runWhenInitialized(final Project project, final Runnable r) {
133 if (project.isDisposed()) return;
135 if (isNoBackgroundMode()) {
136 r.run();
137 return;
140 if (!project.isInitialized()) {
141 StartupManager.getInstance(project).registerPostStartupActivity(r);
142 return;
145 runDumbAware(project, r);
148 public static boolean isNoBackgroundMode() {
149 return ApplicationManager.getApplication().isUnitTestMode()
150 || ApplicationManager.getApplication().isHeadlessEnvironment();
153 public static boolean isInModalContext() {
154 if (isNoBackgroundMode()) return false;
155 return LaterInvocator.isInModalContext();
158 public static void showError(Project project, String title, Throwable e) {
159 MavenLog.LOG.warn(title, e);
160 Notifications.Bus.notify(new Notification("Maven", title, e.getMessage(), NotificationType.ERROR), project);
163 public static Properties getSystemProperties() {
164 Properties result = (Properties)System.getProperties().clone();
165 for (String each : new THashSet<String>((Set)result.keySet())) {
166 if (each.startsWith("idea.")) {
167 result.remove(each);
170 return result;
173 public static Properties getEnvProperties() {
174 Properties reuslt = new Properties();
175 for (Map.Entry<String, String> each : System.getenv().entrySet()) {
176 if (isMagicalProperty(each.getKey())) continue;
177 reuslt.put(each.getKey(), each.getValue());
179 return reuslt;
182 private static boolean isMagicalProperty(String key) {
183 return key.startsWith("=");
186 public static File getPluginSystemDir(String folder) {
187 // PathManager.getSystemPath() may return relative path
188 return new File(PathManager.getSystemPath(), "Maven" + "/" + folder).getAbsoluteFile();
191 public static VirtualFile findProfilesXmlFile(VirtualFile pomFile) {
192 return pomFile.getParent().findChild(MavenConstants.PROFILES_XML);
195 public static File getProfilesXmlIoFile(VirtualFile pomFile) {
196 return new File(pomFile.getParent().getPath(), MavenConstants.PROFILES_XML);
199 public static <T, U> List<T> collectFirsts(List<Pair<T, U>> pairs) {
200 List<T> result = new ArrayList<T>(pairs.size());
201 for (Pair<T, ?> each : pairs) {
202 result.add(each.first);
204 return result;
207 public static <T, U> List<U> collectSeconds(List<Pair<T, U>> pairs) {
208 List<U> result = new ArrayList<U>(pairs.size());
209 for (Pair<T, U> each : pairs) {
210 result.add(each.second);
212 return result;
215 public static List<String> collectPaths(List<VirtualFile> files) {
216 return ContainerUtil.map(files, new Function<VirtualFile, String>() {
217 public String fun(VirtualFile file) {
218 return file.getPath();
223 public static List<VirtualFile> collectFiles(Collection<MavenProject> projects) {
224 return ContainerUtil.map(projects, new Function<MavenProject, VirtualFile>() {
225 public VirtualFile fun(MavenProject project) {
226 return project.getFile();
231 public static <T> boolean equalAsSets(final Collection<T> collection1, final Collection<T> collection2) {
232 return toSet(collection1).equals(toSet(collection2));
235 private static <T> Collection<T> toSet(final Collection<T> collection) {
236 return (collection instanceof Set ? collection : new THashSet<T>(collection));
239 public static <T, U> List<Pair<T, U>> mapToList(Map<T, U> map) {
240 return ContainerUtil.map2List(map.entrySet(), new Function<Map.Entry<T, U>, Pair<T, U>>() {
241 public Pair<T, U> fun(Map.Entry<T, U> tuEntry) {
242 return Pair.create(tuEntry.getKey(), tuEntry.getValue());
247 public static String formatHtmlImage(URL url) {
248 return "<img src=\"" + url + "\"> ";
251 public static void runOrApplyMavenProjectFileTemplate(Project project,
252 VirtualFile file,
253 MavenId projectId,
254 MavenId parentId,
255 boolean interactive) throws IOException {
256 Properties properties = new Properties();
257 Properties conditions = new Properties();
258 properties.setProperty("GROUP_ID", projectId.getGroupId());
259 properties.setProperty("ARTIFACT_ID", projectId.getArtifactId());
260 properties.setProperty("VERSION", projectId.getVersion());
261 if (parentId != null) {
262 conditions.setProperty("HAS_PARENT", "true");
263 properties.setProperty("PARENT_GROUP_ID", parentId.getGroupId());
264 properties.setProperty("PARENT_ARTIFACT_ID", parentId.getArtifactId());
265 properties.setProperty("PARENT_VERSION", parentId.getVersion());
267 runOrApplyFileTemplate(project, file, MavenFileTemplateGroupFactory.MAVEN_PROJECT_XML_TEMPLATE, properties, conditions, interactive);
270 public static void runFileTemplate(Project project,
271 VirtualFile file,
272 String templateName) throws IOException {
273 runOrApplyFileTemplate(project, file, templateName, new Properties(), new Properties(), true);
276 private static void runOrApplyFileTemplate(Project project,
277 VirtualFile file,
278 String templateName,
279 Properties properties,
280 Properties conditions,
281 boolean interactive) throws IOException {
282 FileTemplateManager manager = FileTemplateManager.getInstance();
283 FileTemplate fileTemplate = manager.getJ2eeTemplate(templateName);
284 Properties allProperties = manager.getDefaultProperties();
285 if (!interactive) {
286 allProperties.putAll(properties);
288 allProperties.putAll(conditions);
289 String text = fileTemplate.getText(allProperties);
290 Pattern pattern = Pattern.compile("\\$\\{(.*)\\}");
291 Matcher matcher = pattern.matcher(text);
292 StringBuffer builder = new StringBuffer();
293 while (matcher.find()) {
294 matcher.appendReplacement(builder, "\\$" + matcher.group(1).toUpperCase() + "\\$");
296 matcher.appendTail(builder);
297 text = builder.toString();
299 TemplateImpl template = (TemplateImpl)TemplateManager.getInstance(project).createTemplate("", "", text);
300 for (int i = 0; i < template.getSegmentsCount(); i++) {
301 if (i == template.getEndSegmentNumber()) continue;
302 String name = template.getSegmentName(i);
303 String value = "\"" + properties.getProperty(name, "") + "\"";
304 template.addVariable(name, value, value, true);
307 if (interactive) {
308 OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
309 Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
310 editor.getDocument().setText("");
311 TemplateManager.getInstance(project).startTemplate(editor, template);
313 else {
314 VfsUtil.saveText(file, template.getTemplateText());
318 public static <T extends Collection<Pattern>> T collectPattern(String text, T result) {
319 String antPattern = FileUtil.convertAntToRegexp(text.trim());
320 try {
321 result.add(Pattern.compile(antPattern));
323 catch (PatternSyntaxException ignore) {
325 return result;
328 public static boolean isIncluded(String relativeName, List<Pattern> includes, List<Pattern> excludes) {
329 boolean result = false;
330 for (Pattern each : includes) {
331 if (each.matcher(relativeName).matches()) {
332 result = true;
333 break;
336 if (!result) return false;
337 for (Pattern each : excludes) {
338 if (each.matcher(relativeName).matches()) return false;
340 return true;
343 public static <T extends Serializable> T cloneObject(T object) {
344 try {
345 return (T)BeanUtils.cloneBean(object);
347 catch (IllegalAccessException e) {
348 throw new RuntimeException(e);
350 catch (InstantiationException e) {
351 throw new RuntimeException(e);
353 catch (InvocationTargetException e) {
354 throw new RuntimeException(e);
356 catch (NoSuchMethodException e) {
357 throw new RuntimeException(e);
361 public static void stripDown(Object object) {
362 try {
363 for (Field each : ReflectionUtil.collectFields(object.getClass())) {
364 Class<?> type = each.getType();
365 each.setAccessible(true);
366 Object value = each.get(object);
367 if (shouldStrip(value)) {
368 each.set(object, null);
370 else {
371 if (value != null) {
372 Package pack = type.getPackage();
373 if (pack != null && Model.class.getPackage().getName().equals(pack.getName())) {
374 stripDown(value);
380 catch (IllegalAccessException e) {
381 throw new RuntimeException(e);
385 public static boolean shouldStrip(Object value) {
386 if (value == null) return false;
387 return value.getClass().isArray()
388 || value instanceof Collection
389 || value instanceof Map
390 || value instanceof Xpp3Dom;
393 public static void run(Project project, String title, final MavenTask task) throws MavenProcessCanceledException {
394 final Exception[] canceledEx = new Exception[1];
396 ProgressManager.getInstance().run(new Task.Modal(project, title, true) {
397 public void run(@NotNull ProgressIndicator i) {
398 try {
399 task.run(new MavenProgressIndicator(i));
401 catch (MavenProcessCanceledException e) {
402 canceledEx[0] = e;
404 catch (ProcessCanceledException e) {
405 canceledEx[0] = e;
409 if (canceledEx[0] instanceof MavenProcessCanceledException) throw (MavenProcessCanceledException)canceledEx[0];
410 if (canceledEx[0] instanceof ProcessCanceledException) throw new MavenProcessCanceledException();
413 public static MavenTaskHandler runInBackground(final Project project,
414 final String title,
415 final boolean cancellable,
416 final MavenTask task) {
417 final MavenProgressIndicator indicator = new MavenProgressIndicator();
419 Runnable runnable = new Runnable() {
420 public void run() {
421 try {
422 task.run(indicator);
424 catch (MavenProcessCanceledException ignore) {
425 indicator.cancel();
427 catch (ProcessCanceledException ignore) {
428 indicator.cancel();
433 if (isNoBackgroundMode()) {
434 runnable.run();
435 return new MavenTaskHandler() {
436 public void waitFor() {
440 else {
441 final Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(runnable);
442 final MavenTaskHandler handler = new MavenTaskHandler() {
443 public void waitFor() {
444 try {
445 future.get();
447 catch (InterruptedException e) {
448 MavenLog.LOG.error(e);
450 catch (ExecutionException e) {
451 MavenLog.LOG.error(e);
455 invokeLater(project, new Runnable() {
456 public void run() {
457 if (future.isDone()) return;
458 new Task.Backgroundable(project, title, cancellable) {
459 public void run(@NotNull ProgressIndicator i) {
460 indicator.setIndicator(i);
461 handler.waitFor();
463 }.queue();
466 return handler;
470 public interface MavenTaskHandler {
471 void waitFor();