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
;
56 import java
.io
.IOException
;
57 import java
.io
.Serializable
;
58 import java
.lang
.reflect
.Field
;
59 import java
.lang
.reflect
.InvocationTargetException
;
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()) {
78 ApplicationManager
.getApplication().invokeLater(new Runnable() {
80 if (p
.isDisposed()) return;
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()) {
96 if (ApplicationManager
.getApplication().isDispatchThread()) {
100 ApplicationManager
.getApplication().invokeAndWait(new Runnable() {
102 if (p
.isDisposed()) return;
110 public static void invokeAndWaitWriteAction(Project p
, final Runnable r
) {
111 invokeAndWait(p
, new Runnable() {
113 ApplicationManager
.getApplication().runWriteAction(r
);
118 public static void runDumbAware(final Project project
, final Runnable r
) {
119 if (r
instanceof DumbAware
) {
123 DumbService
.getInstance(project
).runWhenSmart(new Runnable() {
125 if (project
.isDisposed()) return;
132 public static void runWhenInitialized(final Project project
, final Runnable r
) {
133 if (project
.isDisposed()) return;
135 if (isNoBackgroundMode()) {
140 if (!project
.isInitialized()) {
141 StartupManager
.getInstance(project
).registerPostStartupActivity(r
);
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.")) {
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());
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
);
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
);
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
,
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
,
272 String templateName
) throws IOException
{
273 runOrApplyFileTemplate(project
, file
, templateName
, new Properties(), new Properties(), true);
276 private static void runOrApplyFileTemplate(Project project
,
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();
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);
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
);
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());
321 result
.add(Pattern
.compile(antPattern
));
323 catch (PatternSyntaxException ignore
) {
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()) {
336 if (!result
) return false;
337 for (Pattern each
: excludes
) {
338 if (each
.matcher(relativeName
).matches()) return false;
343 public static <T
extends Serializable
> T
cloneObject(T object
) {
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
) {
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);
372 Package pack
= type
.getPackage();
373 if (pack
!= null && Model
.class.getPackage().getName().equals(pack
.getName())) {
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
) {
399 task
.run(new MavenProgressIndicator(i
));
401 catch (MavenProcessCanceledException e
) {
404 catch (ProcessCanceledException 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
,
415 final boolean cancellable
,
416 final MavenTask task
) {
417 final MavenProgressIndicator indicator
= new MavenProgressIndicator();
419 Runnable runnable
= new Runnable() {
424 catch (MavenProcessCanceledException ignore
) {
427 catch (ProcessCanceledException ignore
) {
433 if (isNoBackgroundMode()) {
435 return new MavenTaskHandler() {
436 public void waitFor() {
441 final Future
<?
> future
= ApplicationManager
.getApplication().executeOnPooledThread(runnable
);
442 final MavenTaskHandler handler
= new MavenTaskHandler() {
443 public void waitFor() {
447 catch (InterruptedException e
) {
448 MavenLog
.LOG
.error(e
);
450 catch (ExecutionException e
) {
451 MavenLog
.LOG
.error(e
);
455 invokeLater(project
, new Runnable() {
457 if (future
.isDone()) return;
458 new Task
.Backgroundable(project
, title
, cancellable
) {
459 public void run(@NotNull ProgressIndicator i
) {
460 indicator
.setIndicator(i
);
470 public interface MavenTaskHandler
{