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
.embedder
;
18 import com
.intellij
.openapi
.util
.io
.FileUtil
;
19 import com
.intellij
.openapi
.util
.text
.StringUtil
;
20 import com
.intellij
.openapi
.vfs
.JarFileSystem
;
21 import com
.intellij
.openapi
.vfs
.LocalFileSystem
;
22 import com
.intellij
.openapi
.vfs
.VfsUtil
;
23 import com
.intellij
.openapi
.vfs
.VirtualFile
;
24 import gnu
.trove
.THashSet
;
25 import org
.apache
.maven
.settings
.MavenSettingsBuilder
;
26 import org
.apache
.maven
.settings
.RuntimeInfo
;
27 import org
.apache
.maven
.settings
.Settings
;
28 import org
.codehaus
.classworlds
.ClassWorld
;
29 import org
.codehaus
.plexus
.DefaultPlexusContainer
;
30 import org
.codehaus
.plexus
.PlexusContainer
;
31 import org
.codehaus
.plexus
.PlexusContainerException
;
32 import org
.codehaus
.plexus
.component
.repository
.exception
.ComponentLookupException
;
33 import org
.codehaus
.plexus
.util
.xml
.pull
.XmlPullParserException
;
34 import org
.jetbrains
.annotations
.NotNull
;
35 import org
.jetbrains
.annotations
.Nullable
;
36 import org
.jetbrains
.idea
.maven
.project
.MavenGeneralSettings
;
37 import org
.jetbrains
.idea
.maven
.utils
.MavenConstants
;
38 import org
.jetbrains
.idea
.maven
.utils
.MavenJDOMUtil
;
39 import org
.jetbrains
.idea
.maven
.utils
.MavenLog
;
40 import org
.jetbrains
.idea
.maven
.utils
.MavenUtil
;
43 import java
.io
.IOException
;
46 import java
.util
.regex
.Pattern
;
48 public class MavenEmbedderFactory
{
49 private static final String PROP_MAVEN_HOME
= "maven.home";
50 private static final String PROP_USER_HOME
= "user.home";
51 private static final String ENV_M2_HOME
= "M2_HOME";
53 private static final String M2_DIR
= "m2";
54 private static final String BIN_DIR
= "bin";
55 private static final String DOT_M2_DIR
= ".m2";
56 private static final String CONF_DIR
= "conf";
57 private static final String LIB_DIR
= "lib";
58 private static final String M2_CONF_FILE
= "m2.conf";
60 private static final String REPOSITORY_DIR
= "repository";
62 private static final List
<String
> PHASES
=
63 Arrays
.asList("clean", "validate", "generate-sources", "process-sources", "generate-resources",
64 "process-resources", "compile", "process-classes", "generate-test-sources", "process-test-sources",
65 "generate-test-resources",
66 "process-test-resources", "test-compile", "test", "package", "pre-integration-test", "integration-test",
67 "post-integration-test",
68 "verify", "install", "site", "deploy");
69 private static final List
<String
> BASIC_PHASES
=
70 Arrays
.asList("clean", "validate", "compile", "test", "package", "install", "deploy", "site");
72 private static volatile Properties mySystemPropertiesCache
;
73 private static final String SUPER_POM_PATH
= "org/apache/maven/project/" + MavenConstants
.SUPER_POM_XML
;
76 public static File
resolveMavenHomeDirectory(@Nullable String overrideMavenHome
) {
77 if (!StringUtil
.isEmptyOrSpaces(overrideMavenHome
)) {
78 return new File(overrideMavenHome
);
81 final String m2home
= System
.getenv(ENV_M2_HOME
);
82 if (!StringUtil
.isEmptyOrSpaces(m2home
)) {
83 final File homeFromEnv
= new File(m2home
);
84 if (isValidMavenHome(homeFromEnv
)) {
89 String userHome
= System
.getProperty(PROP_USER_HOME
);
90 if (!StringUtil
.isEmptyOrSpaces(userHome
)) {
91 final File underUserHome
= new File(userHome
, M2_DIR
);
92 if (isValidMavenHome(underUserHome
)) {
100 public static boolean isValidMavenHome(File home
) {
101 return getMavenConfFile(home
).exists();
104 public static File
getMavenConfFile(File mavenHome
) {
105 return new File(new File(mavenHome
, BIN_DIR
), M2_CONF_FILE
);
109 public static File
resolveGlobalSettingsFile(@Nullable String overrideMavenHome
) {
110 File directory
= resolveMavenHomeDirectory(overrideMavenHome
);
111 if (directory
== null) return null;
113 return new File(new File(directory
, CONF_DIR
), MavenConstants
.SETTINGS_XML
);
117 public static VirtualFile
resolveSuperPomFile(@Nullable String overrideMavenHome
) {
118 VirtualFile result
= doResolveSuperPomFile(overrideMavenHome
);
119 if (result
== null) {
120 URL resource
= MavenEmbedderFactory
.class.getResource("/" + SUPER_POM_PATH
);
121 return VfsUtil
.findFileByURL(resource
);
127 private static VirtualFile
doResolveSuperPomFile(String overrideMavenHome
) {
128 File lib
= resolveMavenLib(overrideMavenHome
);
129 if (lib
== null) return null;
131 VirtualFile file
= LocalFileSystem
.getInstance().findFileByIoFile(lib
);
132 if (file
== null) return null;
134 VirtualFile root
= JarFileSystem
.getInstance().getJarRootForLocalFile(file
);
135 if (root
== null) return null;
137 return root
.findFileByRelativePath(SUPER_POM_PATH
);
140 private static File
resolveMavenLib(String overrideMavenHome
) {
141 File directory
= resolveMavenHomeDirectory(overrideMavenHome
);
142 if (directory
== null) return null;
143 File libs
= new File(directory
, LIB_DIR
);
144 File
[] files
= libs
.listFiles();
146 Pattern pattern
= Pattern
.compile("maven-\\d+\\.\\d+\\.\\d+-uber\\.jar");
147 for (File each
: files
) {
148 if (pattern
.matcher(each
.getName()).matches()) {
157 public static File
resolveUserSettingsFile(@Nullable String overrideSettingsFile
) {
158 if (!StringUtil
.isEmptyOrSpaces(overrideSettingsFile
)) return new File(overrideSettingsFile
);
160 String userHome
= System
.getProperty(PROP_USER_HOME
);
161 if (StringUtil
.isEmptyOrSpaces(userHome
)) return null;
163 return new File(new File(userHome
, DOT_M2_DIR
), MavenConstants
.SETTINGS_XML
);
167 public static File
resolveLocalRepository(@Nullable String mavenHome
, @Nullable String userSettings
, @Nullable String override
) {
168 File result
= doResolveLocalRepository(mavenHome
, userSettings
, override
);
170 return result
.getCanonicalFile();
172 catch (IOException e
) {
178 private static File
doResolveLocalRepository(String mavenHome
, String userSettings
, String override
) {
179 if (!StringUtil
.isEmpty(override
)) {
180 return new File(override
);
183 final File userSettingsFile
= resolveUserSettingsFile(userSettings
);
184 if (userSettingsFile
!= null) {
185 final String fromUserSettings
= getRepositoryFromSettings(userSettingsFile
);
186 if (!StringUtil
.isEmpty(fromUserSettings
)) {
187 return new File(fromUserSettings
);
191 final File globalSettingsFile
= resolveGlobalSettingsFile(mavenHome
);
192 if (globalSettingsFile
!= null) {
193 final String fromGlobalSettings
= getRepositoryFromSettings(globalSettingsFile
);
194 if (!StringUtil
.isEmpty(fromGlobalSettings
)) {
195 return new File(fromGlobalSettings
);
199 return new File(new File(System
.getProperty(PROP_USER_HOME
), DOT_M2_DIR
), REPOSITORY_DIR
);
203 private static String
getRepositoryFromSettings(final File file
) {
205 byte[] bytes
= FileUtil
.loadFileBytes(file
);
206 return expandProperties(MavenJDOMUtil
.findChildValueByPath(MavenJDOMUtil
.read(bytes
, null), "localRepository", null));
208 catch (IOException e
) {
213 private static String
expandProperties(String text
) {
214 if (StringUtil
.isEmptyOrSpaces(text
)) return text
;
215 Properties props
= collectSystemProperties();
216 for (Map
.Entry
<Object
, Object
> each
: props
.entrySet()) {
217 text
= text
.replace("${" + each
.getKey() + "}", (CharSequence
)each
.getValue());
222 public static List
<String
> getBasicPhasesList() {
226 public static List
<String
> getPhasesList() {
230 public static MavenEmbedderWrapper
createEmbedder(MavenGeneralSettings generalSettings
) {
231 DefaultPlexusContainer container
;
233 container
= new DefaultPlexusContainer();
235 catch (RuntimeException e
) {
236 String s
= "Cannot initialize Maven. Please make sure that your IDEA installation is correct and has no old libraries.";
237 throw new RuntimeException(s
, e
);
240 container
.setClassWorld(new ClassWorld("plexus.core", generalSettings
.getClass().getClassLoader()));
241 CustomLoggerManager loggerManager
= new CustomLoggerManager(generalSettings
.getLoggingLevel());
242 container
.setLoggerManager(loggerManager
);
245 container
.initialize();
248 catch (PlexusContainerException e
) {
249 MavenLog
.LOG
.error(e
);
250 throw new RuntimeException(e
);
253 File mavenHome
= generalSettings
.getEffectiveMavenHome();
254 if (mavenHome
!= null) {
255 System
.setProperty(PROP_MAVEN_HOME
, mavenHome
.getPath());
258 Settings settings
= buildSettings(container
, generalSettings
);
260 return new MavenEmbedderWrapper(container
, settings
, loggerManager
.getLogger(), generalSettings
);
263 private static Settings
buildSettings(PlexusContainer container
, MavenGeneralSettings generalSettings
) {
264 File file
= generalSettings
.getEffectiveGlobalSettingsIoFile();
266 System
.setProperty(MavenSettingsBuilder
.ALT_GLOBAL_SETTINGS_XML_LOCATION
, file
.getPath());
269 Settings settings
= null;
272 MavenSettingsBuilder builder
= (MavenSettingsBuilder
)container
.lookup(MavenSettingsBuilder
.ROLE
);
274 File userSettingsFile
= generalSettings
.getEffectiveUserSettingsIoFile();
275 if (userSettingsFile
!= null && userSettingsFile
.exists() && !userSettingsFile
.isDirectory()) {
276 settings
= builder
.buildSettings(userSettingsFile
, false);
279 if (settings
== null) {
280 settings
= builder
.buildSettings();
283 catch (ComponentLookupException e
) {
284 MavenLog
.LOG
.error(e
);
286 catch (IOException e
) {
287 MavenLog
.LOG
.warn(e
);
289 catch (XmlPullParserException e
) {
290 MavenLog
.LOG
.warn(e
);
293 if (settings
== null) {
294 settings
= new Settings();
297 File localRepository
= generalSettings
.getEffectiveLocalRepository();
298 if (localRepository
!= null) {
299 settings
.setLocalRepository(localRepository
.getPath());
302 settings
.setOffline(generalSettings
.isWorkOffline());
303 settings
.setInteractiveMode(false);
304 settings
.setUsePluginRegistry(generalSettings
.isUsePluginRegistry());
306 RuntimeInfo runtimeInfo
= new RuntimeInfo(settings
);
307 runtimeInfo
.setPluginUpdateOverride(generalSettings
.getPluginUpdatePolicy() == MavenExecutionOptions
.PluginUpdatePolicy
.UPDATE
);
308 settings
.setRuntimeInfo(runtimeInfo
);
313 public static Properties
collectSystemProperties() {
314 if (mySystemPropertiesCache
== null) {
315 Properties result
= new Properties();
316 result
.putAll(MavenUtil
.getSystemProperties());
318 Properties envVars
= MavenUtil
.getEnvProperties();
319 for (Map
.Entry
<Object
, Object
> each
: envVars
.entrySet()) {
320 result
.setProperty("env." + each
.getKey().toString(), each
.getValue().toString());
322 mySystemPropertiesCache
= result
;
325 return mySystemPropertiesCache
;
328 public static void resetSystemPropertiesCacheInTests() {
329 mySystemPropertiesCache
= null;