| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.jetbrains.idea.maven.utils; |
| |
| import com.intellij.codeInsight.actions.ReformatCodeProcessor; |
| import com.intellij.codeInsight.lookup.LookupElement; |
| import com.intellij.codeInsight.lookup.LookupElementBuilder; |
| import com.intellij.codeInsight.template.TemplateManager; |
| import com.intellij.codeInsight.template.impl.TemplateImpl; |
| import com.intellij.execution.configurations.ParametersList; |
| import com.intellij.ide.fileTemplates.FileTemplate; |
| import com.intellij.ide.fileTemplates.FileTemplateManager; |
| import com.intellij.notification.Notification; |
| import com.intellij.notification.NotificationType; |
| import com.intellij.notification.Notifications; |
| import com.intellij.openapi.application.ApplicationManager; |
| import com.intellij.openapi.application.ModalityState; |
| import com.intellij.openapi.application.PathManager; |
| import com.intellij.openapi.application.impl.ApplicationInfoImpl; |
| import com.intellij.openapi.application.impl.LaterInvocator; |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.fileEditor.FileEditorManager; |
| import com.intellij.openapi.fileEditor.OpenFileDescriptor; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.openapi.progress.ProcessCanceledException; |
| import com.intellij.openapi.progress.ProgressIndicator; |
| import com.intellij.openapi.progress.ProgressManager; |
| import com.intellij.openapi.progress.Task; |
| import com.intellij.openapi.project.DumbService; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.projectRoots.Sdk; |
| import com.intellij.openapi.roots.ModuleRootManager; |
| import com.intellij.openapi.startup.StartupManager; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.Pair; |
| import com.intellij.openapi.util.SystemInfo; |
| import com.intellij.openapi.util.io.FileUtil; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.openapi.vfs.JarFileSystem; |
| import com.intellij.openapi.vfs.LocalFileSystem; |
| import com.intellij.openapi.vfs.VfsUtil; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.psi.PsiFile; |
| import com.intellij.psi.PsiManager; |
| import com.intellij.util.DisposeAwareRunnable; |
| import com.intellij.util.Function; |
| import com.intellij.util.SystemProperties; |
| import com.intellij.util.containers.ContainerUtil; |
| import gnu.trove.THashSet; |
| import icons.MavenIcons; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| import org.jetbrains.idea.maven.model.MavenConstants; |
| import org.jetbrains.idea.maven.model.MavenId; |
| import org.jetbrains.idea.maven.model.MavenPlugin; |
| import org.jetbrains.idea.maven.project.MavenProject; |
| import org.jetbrains.idea.maven.project.MavenProjectsManager; |
| import org.jetbrains.idea.maven.server.MavenServerManager; |
| import org.jetbrains.idea.maven.server.MavenServerUtil; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.net.URL; |
| import java.util.*; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.Future; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.regex.PatternSyntaxException; |
| import java.util.zip.CRC32; |
| |
| public class MavenUtil { |
| public static final String MAVEN_NOTIFICATION_GROUP = "Maven"; |
| public static final String SETTINGS_XML = "settings.xml"; |
| public static final String DOT_M2_DIR = ".m2"; |
| public static final String PROP_USER_HOME = "user.home"; |
| public static final String ENV_M2_HOME = "M2_HOME"; |
| public static final String M2_DIR = "m2"; |
| public static final String BIN_DIR = "bin"; |
| public static final String CONF_DIR = "conf"; |
| public static final String M2_CONF_FILE = "m2.conf"; |
| public static final String REPOSITORY_DIR = "repository"; |
| public static final String LIB_DIR = "lib"; |
| |
| @SuppressWarnings("unchecked") |
| private static final Pair<Pattern, String>[] SUPER_POM_PATHS = new Pair[]{ |
| Pair.create(Pattern.compile("maven-\\d+\\.\\d+\\.\\d+-uber\\.jar"), "org/apache/maven/project/" + MavenConstants.SUPER_POM_XML), |
| Pair.create(Pattern.compile("maven-model-builder-\\d+\\.\\d+\\.\\d+\\.jar"), "org/apache/maven/model/" + MavenConstants.SUPER_POM_XML) |
| }; |
| |
| private static volatile Map<String, String> ourPropertiesFromMvnOpts; |
| |
| public static Map<String, String> getPropertiesFromMavenOpts() { |
| Map<String, String> res = ourPropertiesFromMvnOpts; |
| if (res == null) { |
| String mavenOpts = System.getenv("MAVEN_OPTS"); |
| if (mavenOpts != null) { |
| ParametersList mavenOptsList = new ParametersList(); |
| mavenOptsList.addParametersString(mavenOpts); |
| res = mavenOptsList.getProperties(); |
| } |
| else { |
| res = Collections.emptyMap(); |
| } |
| |
| ourPropertiesFromMvnOpts = res; |
| } |
| |
| return res; |
| } |
| |
| |
| public static void invokeLater(Project p, Runnable r) { |
| invokeLater(p, ModalityState.defaultModalityState(), r); |
| } |
| |
| public static void invokeLater(final Project p, final ModalityState state, final Runnable r) { |
| if (isNoBackgroundMode()) { |
| r.run(); |
| } |
| else { |
| ApplicationManager.getApplication().invokeLater(DisposeAwareRunnable.create(r, p), state); |
| } |
| } |
| |
| public static void invokeAndWait(Project p, Runnable r) { |
| invokeAndWait(p, ModalityState.defaultModalityState(), r); |
| } |
| |
| public static void invokeAndWait(final Project p, final ModalityState state, final Runnable r) { |
| if (isNoBackgroundMode()) { |
| r.run(); |
| } |
| else { |
| if (ApplicationManager.getApplication().isDispatchThread()) { |
| r.run(); |
| } |
| else { |
| ApplicationManager.getApplication().invokeAndWait(DisposeAwareRunnable.create(r, p), state); |
| } |
| } |
| } |
| |
| public static void invokeAndWaitWriteAction(Project p, final Runnable r) { |
| invokeAndWait(p, new Runnable() { |
| public void run() { |
| ApplicationManager.getApplication().runWriteAction(r); |
| } |
| }); |
| } |
| |
| public static void runDumbAware(final Project project, final Runnable r) { |
| if (DumbService.isDumbAware(r)) { |
| r.run(); |
| } |
| else { |
| DumbService.getInstance(project).runWhenSmart(DisposeAwareRunnable.create(r, project)); |
| } |
| } |
| |
| public static void runWhenInitialized(final Project project, final Runnable r) { |
| if (project.isDisposed()) return; |
| |
| if (isNoBackgroundMode()) { |
| r.run(); |
| return; |
| } |
| |
| if (!project.isInitialized()) { |
| StartupManager.getInstance(project).registerPostStartupActivity(DisposeAwareRunnable.create(r, project)); |
| return; |
| } |
| |
| runDumbAware(project, r); |
| } |
| |
| public static boolean isNoBackgroundMode() { |
| return (ApplicationManager.getApplication().isUnitTestMode() |
| || ApplicationManager.getApplication().isHeadlessEnvironment()); |
| } |
| |
| public static boolean isInModalContext() { |
| if (isNoBackgroundMode()) return false; |
| return LaterInvocator.isInModalContext(); |
| } |
| |
| public static void showError(Project project, String title, Throwable e) { |
| MavenLog.LOG.warn(title, e); |
| Notifications.Bus.notify(new Notification(MAVEN_NOTIFICATION_GROUP, title, e.getMessage(), NotificationType.ERROR), project); |
| } |
| |
| public static File getPluginSystemDir(String folder) { |
| // PathManager.getSystemPath() may return relative path |
| return new File(PathManager.getSystemPath(), "Maven" + "/" + folder).getAbsoluteFile(); |
| } |
| |
| public static VirtualFile findProfilesXmlFile(VirtualFile pomFile) { |
| return pomFile.getParent().findChild(MavenConstants.PROFILES_XML); |
| } |
| |
| public static File getProfilesXmlIoFile(VirtualFile pomFile) { |
| return new File(pomFile.getParent().getPath(), MavenConstants.PROFILES_XML); |
| } |
| |
| public static <T, U> List<T> collectFirsts(List<Pair<T, U>> pairs) { |
| List<T> result = new ArrayList<T>(pairs.size()); |
| for (Pair<T, ?> each : pairs) { |
| result.add(each.first); |
| } |
| return result; |
| } |
| |
| public static <T, U> List<U> collectSeconds(List<Pair<T, U>> pairs) { |
| List<U> result = new ArrayList<U>(pairs.size()); |
| for (Pair<T, U> each : pairs) { |
| result.add(each.second); |
| } |
| return result; |
| } |
| |
| public static List<String> collectPaths(List<VirtualFile> files) { |
| return ContainerUtil.map(files, new Function<VirtualFile, String>() { |
| public String fun(VirtualFile file) { |
| return file.getPath(); |
| } |
| }); |
| } |
| |
| public static List<VirtualFile> collectFiles(Collection<MavenProject> projects) { |
| return ContainerUtil.map(projects, new Function<MavenProject, VirtualFile>() { |
| public VirtualFile fun(MavenProject project) { |
| return project.getFile(); |
| } |
| }); |
| } |
| |
| public static <T> boolean equalAsSets(final Collection<T> collection1, final Collection<T> collection2) { |
| return toSet(collection1).equals(toSet(collection2)); |
| } |
| |
| private static <T> Collection<T> toSet(final Collection<T> collection) { |
| return (collection instanceof Set ? collection : new THashSet<T>(collection)); |
| } |
| |
| public static <T, U> List<Pair<T, U>> mapToList(Map<T, U> map) { |
| return ContainerUtil.map2List(map.entrySet(), new Function<Map.Entry<T, U>, Pair<T, U>>() { |
| public Pair<T, U> fun(Map.Entry<T, U> tuEntry) { |
| return Pair.create(tuEntry.getKey(), tuEntry.getValue()); |
| } |
| }); |
| } |
| |
| public static String formatHtmlImage(URL url) { |
| return "<img src=\"" + url + "\"> "; |
| } |
| |
| public static void runOrApplyMavenProjectFileTemplate(Project project, |
| VirtualFile file, |
| @NotNull MavenId projectId, |
| boolean interactive) throws IOException { |
| runOrApplyMavenProjectFileTemplate(project, file, projectId, null, null, interactive); |
| } |
| |
| public static void runOrApplyMavenProjectFileTemplate(Project project, |
| VirtualFile file, |
| @NotNull MavenId projectId, |
| MavenId parentId, |
| VirtualFile parentFile, |
| boolean interactive) throws IOException { |
| Properties properties = new Properties(); |
| Properties conditions = new Properties(); |
| properties.setProperty("GROUP_ID", projectId.getGroupId()); |
| properties.setProperty("ARTIFACT_ID", projectId.getArtifactId()); |
| properties.setProperty("VERSION", projectId.getVersion()); |
| if (parentId != null) { |
| conditions.setProperty("HAS_PARENT", "true"); |
| properties.setProperty("PARENT_GROUP_ID", parentId.getGroupId()); |
| properties.setProperty("PARENT_ARTIFACT_ID", parentId.getArtifactId()); |
| properties.setProperty("PARENT_VERSION", parentId.getVersion()); |
| |
| if (parentFile != null) { |
| VirtualFile modulePath = file.getParent(); |
| VirtualFile parentModulePath = parentFile.getParent(); |
| |
| if (!Comparing.equal(modulePath.getParent(), parentModulePath)) { |
| String relativePath = VfsUtil.getPath(file, parentModulePath, '/'); |
| if (relativePath != null) { |
| if (relativePath.endsWith("/")) relativePath = relativePath.substring(0, relativePath.length() - 1); |
| |
| conditions.setProperty("HAS_RELATIVE_PATH", "true"); |
| properties.setProperty("PARENT_RELATIVE_PATH", relativePath); |
| } |
| } |
| } |
| } |
| runOrApplyFileTemplate(project, file, MavenFileTemplateGroupFactory.MAVEN_PROJECT_XML_TEMPLATE, properties, conditions, interactive); |
| } |
| |
| public static void runFileTemplate(Project project, |
| VirtualFile file, |
| String templateName) throws IOException { |
| runOrApplyFileTemplate(project, file, templateName, new Properties(), new Properties(), true); |
| } |
| |
| private static void runOrApplyFileTemplate(Project project, |
| VirtualFile file, |
| String templateName, |
| Properties properties, |
| Properties conditions, |
| boolean interactive) throws IOException { |
| FileTemplateManager manager = FileTemplateManager.getInstance(); |
| FileTemplate fileTemplate = manager.getJ2eeTemplate(templateName); |
| Properties allProperties = manager.getDefaultProperties(project); |
| if (!interactive) { |
| allProperties.putAll(properties); |
| } |
| allProperties.putAll(conditions); |
| String text = fileTemplate.getText(allProperties); |
| Pattern pattern = Pattern.compile("\\$\\{(.*)\\}"); |
| Matcher matcher = pattern.matcher(text); |
| StringBuffer builder = new StringBuffer(); |
| while (matcher.find()) { |
| matcher.appendReplacement(builder, "\\$" + matcher.group(1).toUpperCase() + "\\$"); |
| } |
| matcher.appendTail(builder); |
| text = builder.toString(); |
| |
| TemplateImpl template = (TemplateImpl)TemplateManager.getInstance(project).createTemplate("", "", text); |
| for (int i = 0; i < template.getSegmentsCount(); i++) { |
| if (i == template.getEndSegmentNumber()) continue; |
| String name = template.getSegmentName(i); |
| String value = "\"" + properties.getProperty(name, "") + "\""; |
| template.addVariable(name, value, value, true); |
| } |
| |
| if (interactive) { |
| OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file); |
| Editor editor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true); |
| editor.getDocument().setText(""); |
| TemplateManager.getInstance(project).startTemplate(editor, template); |
| } |
| else { |
| VfsUtil.saveText(file, template.getTemplateText()); |
| |
| PsiFile psiFile = PsiManager.getInstance(project).findFile(file); |
| if (psiFile != null) { |
| new ReformatCodeProcessor(project, psiFile, null, false).run(); |
| } |
| } |
| } |
| |
| public static <T extends Collection<Pattern>> T collectPattern(String text, T result) { |
| String antPattern = FileUtil.convertAntToRegexp(text.trim()); |
| try { |
| result.add(Pattern.compile(antPattern)); |
| } |
| catch (PatternSyntaxException ignore) { |
| } |
| return result; |
| } |
| |
| public static boolean isIncluded(String relativeName, List<Pattern> includes, List<Pattern> excludes) { |
| boolean result = false; |
| for (Pattern each : includes) { |
| if (each.matcher(relativeName).matches()) { |
| result = true; |
| break; |
| } |
| } |
| if (!result) return false; |
| for (Pattern each : excludes) { |
| if (each.matcher(relativeName).matches()) return false; |
| } |
| return true; |
| } |
| |
| public static void run(Project project, String title, final MavenTask task) throws MavenProcessCanceledException { |
| final Exception[] canceledEx = new Exception[1]; |
| final RuntimeException[] runtimeEx = new RuntimeException[1]; |
| final Error[] errorEx = new Error[1]; |
| |
| ProgressManager.getInstance().run(new Task.Modal(project, title, true) { |
| public void run(@NotNull ProgressIndicator i) { |
| try { |
| task.run(new MavenProgressIndicator(i)); |
| } |
| catch (MavenProcessCanceledException e) { |
| canceledEx[0] = e; |
| } |
| catch (ProcessCanceledException e) { |
| canceledEx[0] = e; |
| } |
| catch (RuntimeException e) { |
| runtimeEx[0] = e; |
| } |
| catch (Error e) { |
| errorEx[0] = e; |
| } |
| } |
| }); |
| if (canceledEx[0] instanceof MavenProcessCanceledException) throw (MavenProcessCanceledException)canceledEx[0]; |
| if (canceledEx[0] instanceof ProcessCanceledException) throw new MavenProcessCanceledException(); |
| |
| if (runtimeEx[0] != null) throw runtimeEx[0]; |
| if (errorEx[0] != null) throw errorEx[0]; |
| } |
| |
| public static MavenTaskHandler runInBackground(final Project project, |
| final String title, |
| final boolean cancellable, |
| final MavenTask task) { |
| final MavenProgressIndicator indicator = new MavenProgressIndicator(); |
| |
| Runnable runnable = new Runnable() { |
| public void run() { |
| if (project.isDisposed()) return; |
| |
| try { |
| task.run(indicator); |
| } |
| catch (MavenProcessCanceledException ignore) { |
| indicator.cancel(); |
| } |
| catch (ProcessCanceledException ignore) { |
| indicator.cancel(); |
| } |
| } |
| }; |
| |
| if (isNoBackgroundMode()) { |
| runnable.run(); |
| return new MavenTaskHandler() { |
| public void waitFor() { |
| } |
| }; |
| } |
| else { |
| final Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(runnable); |
| final MavenTaskHandler handler = new MavenTaskHandler() { |
| public void waitFor() { |
| try { |
| future.get(); |
| } |
| catch (InterruptedException e) { |
| MavenLog.LOG.error(e); |
| } |
| catch (ExecutionException e) { |
| MavenLog.LOG.error(e); |
| } |
| } |
| }; |
| invokeLater(project, new Runnable() { |
| public void run() { |
| if (future.isDone()) return; |
| new Task.Backgroundable(project, title, cancellable) { |
| public void run(@NotNull ProgressIndicator i) { |
| indicator.setIndicator(i); |
| handler.waitFor(); |
| } |
| }.queue(); |
| } |
| }); |
| return handler; |
| } |
| } |
| |
| @Nullable |
| public static File resolveMavenHomeDirectory(@Nullable String overrideMavenHome) { |
| if (!isEmptyOrSpaces(overrideMavenHome)) { |
| return new File(overrideMavenHome); |
| } |
| |
| String m2home = System.getenv(ENV_M2_HOME); |
| if (!isEmptyOrSpaces(m2home)) { |
| final File homeFromEnv = new File(m2home); |
| if (isValidMavenHome(homeFromEnv)) { |
| return homeFromEnv; |
| } |
| } |
| |
| String mavenHome = System.getenv("MAVEN_HOME"); |
| if (!isEmptyOrSpaces(mavenHome)) { |
| final File mavenHomeFile = new File(mavenHome); |
| if (isValidMavenHome(mavenHomeFile)) { |
| return mavenHomeFile; |
| } |
| } |
| |
| String userHome = SystemProperties.getUserHome(); |
| if (!isEmptyOrSpaces(userHome)) { |
| final File underUserHome = new File(userHome, M2_DIR); |
| if (isValidMavenHome(underUserHome)) { |
| return underUserHome; |
| } |
| } |
| |
| if (SystemInfo.isMac) { |
| File home = fromBrew(); |
| if (home != null) { |
| return home; |
| } |
| |
| if ((home = fromMacSystemJavaTools()) != null) { |
| return home; |
| } |
| } |
| else if (SystemInfo.isLinux) { |
| File home = new File("/usr/share/maven"); |
| if (isValidMavenHome(home)) { |
| return home; |
| } |
| |
| home = new File("/usr/share/maven2"); |
| if (isValidMavenHome(home)) { |
| return home; |
| } |
| } |
| |
| return null; |
| } |
| |
| @Nullable |
| private static File fromMacSystemJavaTools() { |
| final File symlinkDir = new File("/usr/share/maven"); |
| if (isValidMavenHome(symlinkDir)) { |
| return symlinkDir; |
| } |
| |
| // well, try to search |
| final File dir = new File("/usr/share/java"); |
| final String[] list = dir.list(); |
| if (list == null || list.length == 0) { |
| return null; |
| } |
| |
| String home = null; |
| final String prefix = "maven-"; |
| final int versionIndex = prefix.length(); |
| for (String path : list) { |
| if (path.startsWith(prefix) && |
| (home == null || StringUtil.compareVersionNumbers(path.substring(versionIndex), home.substring(versionIndex)) > 0)) { |
| home = path; |
| } |
| } |
| |
| if (home != null) { |
| File file = new File(dir, home); |
| if (isValidMavenHome(file)) { |
| return file; |
| } |
| } |
| |
| return null; |
| } |
| |
| @Nullable |
| private static File fromBrew() { |
| final File brewDir = new File("/usr/local/Cellar/maven"); |
| final String[] list = brewDir.list(); |
| if (list == null || list.length == 0) { |
| return null; |
| } |
| |
| if (list.length > 1) { |
| Arrays.sort(list, new Comparator<String>() { |
| @Override |
| public int compare(String o1, String o2) { |
| return StringUtil.compareVersionNumbers(o2, o1); |
| } |
| }); |
| } |
| |
| final File file = new File(brewDir, list[0] + "/libexec"); |
| return isValidMavenHome(file) ? file : null; |
| } |
| |
| public static boolean isEmptyOrSpaces(@Nullable String str) { |
| return str == null || str.length() == 0 || str.trim().length() == 0; |
| } |
| |
| public static boolean isValidMavenHome(File home) { |
| return getMavenConfFile(home).exists(); |
| } |
| |
| public static File getMavenConfFile(File mavenHome) { |
| return new File(new File(mavenHome, BIN_DIR), M2_CONF_FILE); |
| } |
| |
| @Nullable |
| public static String getMavenVersion(String mavenHome) { |
| String[] libs = new File(mavenHome, "lib").list(); |
| |
| if (libs != null) { |
| for (String lib : libs) { |
| if (lib.startsWith("maven-core-") && lib.endsWith(".jar")) { |
| return lib.substring("maven-core-".length(), lib.length() - ".jar".length()); |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public static boolean isMaven3(String mavenHome) { |
| String version = getMavenVersion(mavenHome); |
| return version != null && version.compareTo("3.0.0") >= 0; |
| } |
| |
| @Nullable |
| public static File resolveGlobalSettingsFile(@Nullable String overriddenMavenHome) { |
| File directory = resolveMavenHomeDirectory(overriddenMavenHome); |
| if (directory == null) return null; |
| |
| return new File(new File(directory, CONF_DIR), SETTINGS_XML); |
| } |
| |
| @NotNull |
| public static File resolveUserSettingsFile(@Nullable String overriddenUserSettingsFile) { |
| if (!isEmptyOrSpaces(overriddenUserSettingsFile)) return new File(overriddenUserSettingsFile); |
| return new File(resolveM2Dir(), SETTINGS_XML); |
| } |
| |
| @NotNull |
| public static File resolveM2Dir() { |
| return new File(SystemProperties.getUserHome(), DOT_M2_DIR); |
| } |
| |
| @NotNull |
| public static File resolveLocalRepository(@Nullable String overriddenLocalRepository, |
| @Nullable String overriddenMavenHome, |
| @Nullable String overriddenUserSettingsFile) { |
| File result = null; |
| if (!isEmptyOrSpaces(overriddenLocalRepository)) result = new File(overriddenLocalRepository); |
| if (result == null) { |
| result = doResolveLocalRepository(resolveUserSettingsFile(overriddenUserSettingsFile), |
| resolveGlobalSettingsFile(overriddenMavenHome)); |
| } |
| try { |
| return result.getCanonicalFile(); |
| } |
| catch (IOException e) { |
| return result; |
| } |
| } |
| |
| @NotNull |
| public static File doResolveLocalRepository(@Nullable File userSettingsFile, @Nullable File globalSettingsFile) { |
| if (userSettingsFile != null) { |
| final String fromUserSettings = getRepositoryFromSettings(userSettingsFile); |
| if (!StringUtil.isEmpty(fromUserSettings)) { |
| return new File(fromUserSettings); |
| } |
| } |
| |
| if (globalSettingsFile != null) { |
| final String fromGlobalSettings = getRepositoryFromSettings(globalSettingsFile); |
| if (!StringUtil.isEmpty(fromGlobalSettings)) { |
| return new File(fromGlobalSettings); |
| } |
| } |
| |
| return new File(resolveM2Dir(), REPOSITORY_DIR); |
| } |
| |
| @Nullable |
| public static String getRepositoryFromSettings(final File file) { |
| try { |
| byte[] bytes = FileUtil.loadFileBytes(file); |
| return expandProperties(MavenJDOMUtil.findChildValueByPath(MavenJDOMUtil.read(bytes, null), "localRepository", null)); |
| } |
| catch (IOException e) { |
| return null; |
| } |
| } |
| |
| public static String expandProperties(String text) { |
| if (StringUtil.isEmptyOrSpaces(text)) return text; |
| Properties props = MavenServerUtil.collectSystemProperties(); |
| for (Map.Entry<Object, Object> each : props.entrySet()) { |
| Object val = each.getValue(); |
| text = text.replace("${" + each.getKey() + "}", val instanceof CharSequence ? (CharSequence)val : val.toString()); |
| } |
| return text; |
| } |
| |
| @NotNull |
| public static VirtualFile resolveSuperPomFile(@Nullable File mavenHome) { |
| VirtualFile result = null; |
| if (mavenHome != null) { |
| result = doResolveSuperPomFile(new File(mavenHome, LIB_DIR)); |
| } |
| if (result == null) { |
| result = doResolveSuperPomFile(MavenServerManager.getMavenLibDirectory()); |
| assert result != null : "Super pom not found in: " + MavenServerManager.getMavenLibDirectory(); |
| } |
| return result; |
| } |
| |
| @Nullable |
| public static VirtualFile doResolveSuperPomFile(@NotNull File mavenHome) { |
| File[] files = mavenHome.listFiles(); |
| if (files == null) return null; |
| |
| for (File library : files) { |
| |
| for (Pair<Pattern, String> path : SUPER_POM_PATHS) { |
| if (path.first.matcher(library.getName()).matches()) { |
| VirtualFile libraryVirtualFile = LocalFileSystem.getInstance().findFileByIoFile(library); |
| if (libraryVirtualFile == null) continue; |
| |
| VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(libraryVirtualFile); |
| if (root == null) continue; |
| |
| VirtualFile pomFile = root.findFileByRelativePath(path.second); |
| if (pomFile != null) { |
| return pomFile; |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public static List<LookupElement> getPhaseVariants(MavenProjectsManager manager) { |
| Set<String> goals = new HashSet<String>(); |
| goals.addAll(MavenConstants.PHASES); |
| |
| for (MavenProject mavenProject : manager.getProjects()) { |
| for (MavenPlugin plugin : mavenProject.getPlugins()) { |
| MavenPluginInfo pluginInfo = MavenArtifactUtil.readPluginInfo(manager.getLocalRepository(), plugin.getMavenId()); |
| if (pluginInfo != null) { |
| for (MavenPluginInfo.Mojo mojo : pluginInfo.getMojos()) { |
| goals.add(mojo.getDisplayName()); |
| } |
| } |
| } |
| } |
| |
| List<LookupElement> res = new ArrayList<LookupElement>(goals.size()); |
| for (String goal : goals) { |
| res.add(LookupElementBuilder.create(goal).withIcon(MavenIcons.Phase)); |
| } |
| |
| return res; |
| } |
| |
| public interface MavenTaskHandler { |
| void waitFor(); |
| } |
| |
| public static int crcWithoutSpaces(@NotNull InputStream in) throws IOException { |
| try { |
| final CRC32 crc = new CRC32(); |
| |
| SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); |
| |
| parser.parse(in, new DefaultHandler(){ |
| |
| boolean textContentOccur = false; |
| int spacesCrc; |
| |
| private void putString(@Nullable String string) { |
| if (string == null) return; |
| |
| for (int i = 0, end = string.length(); i < end; i++) { |
| crc.update(string.charAt(i)); |
| } |
| } |
| |
| @Override |
| public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { |
| textContentOccur = false; |
| |
| crc.update(1); |
| putString(qName); |
| |
| for (int i = 0; i < attributes.getLength(); i++) { |
| putString(attributes.getQName(i)); |
| putString(attributes.getValue(i)); |
| } |
| } |
| |
| @Override |
| public void endElement(String uri, String localName, String qName) throws SAXException { |
| textContentOccur = false; |
| |
| crc.update(2); |
| putString(qName); |
| } |
| |
| private void processTextOrSpaces(char[] ch, int start, int length) { |
| for (int i = start, end = start + length; i < end; i++) { |
| char a = ch[i]; |
| |
| if (Character.isWhitespace(a)) { |
| if (textContentOccur) { |
| spacesCrc = spacesCrc * 31 + a; |
| } |
| } |
| else { |
| if (textContentOccur && spacesCrc != 0) { |
| crc.update(spacesCrc); |
| crc.update(spacesCrc >> 8); |
| } |
| |
| crc.update(a); |
| |
| textContentOccur = true; |
| spacesCrc = 0; |
| } |
| } |
| } |
| |
| @Override |
| public void characters(char[] ch, int start, int length) throws SAXException { |
| processTextOrSpaces(ch, start, length); |
| } |
| |
| @Override |
| public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { |
| processTextOrSpaces(ch, start, length); |
| } |
| |
| @Override |
| public void processingInstruction(String target, String data) throws SAXException { |
| putString(target); |
| putString(data); |
| } |
| |
| @Override |
| public void skippedEntity(String name) throws SAXException { |
| putString(name); |
| } |
| |
| @Override |
| public void error(SAXParseException e) throws SAXException { |
| crc.update(100); |
| } |
| }); |
| |
| return (int)crc.getValue(); |
| } |
| catch (ParserConfigurationException e) { |
| throw new RuntimeException(e); |
| } |
| catch (SAXException e) { |
| return -1; |
| } |
| } |
| |
| public static int crcWithoutSpaces(@NotNull VirtualFile xmlFile) throws IOException { |
| InputStream inputStream = xmlFile.getInputStream(); |
| try { |
| return crcWithoutSpaces(inputStream); |
| } |
| finally { |
| inputStream.close(); |
| } |
| } |
| |
| public static String getSdkPath(@Nullable Sdk sdk) { |
| if (sdk == null) return null; |
| |
| VirtualFile homeDirectory = sdk.getHomeDirectory(); |
| if (homeDirectory == null) return null; |
| |
| if (!"jre".equals(homeDirectory.getName())) { |
| VirtualFile jreDir = homeDirectory.findChild("jre"); |
| if (jreDir != null) { |
| homeDirectory = jreDir; |
| } |
| } |
| |
| return homeDirectory.getPath(); |
| } |
| |
| @Nullable |
| public static String getModuleJreHome(@NotNull MavenProjectsManager mavenProjectsManager, @NotNull MavenProject mavenProject) { |
| return getSdkPath(getModuleJdk(mavenProjectsManager, mavenProject)); |
| } |
| |
| @Nullable |
| public static String getModuleJavaVersion(@NotNull MavenProjectsManager mavenProjectsManager, @NotNull MavenProject mavenProject) { |
| Sdk sdk = getModuleJdk(mavenProjectsManager, mavenProject); |
| if (sdk == null) return null; |
| |
| return sdk.getVersionString(); |
| } |
| |
| @Nullable |
| public static Sdk getModuleJdk(@NotNull MavenProjectsManager mavenProjectsManager, @NotNull MavenProject mavenProject) { |
| Module module = mavenProjectsManager.findModule(mavenProject); |
| if (module == null) return null; |
| |
| return ModuleRootManager.getInstance(module).getSdk(); |
| } |
| |
| @NotNull |
| public static <K, V extends Map> V getOrCreate(Map map, K key) { |
| Map res = (Map)map.get(key); |
| if (res == null) { |
| res = new HashMap(); |
| map.put(key, res); |
| } |
| |
| return (V)res; |
| } |
| |
| public static String getArtifactName(String packaging, Module module, boolean exploded) { |
| return module.getName() + ":" + packaging + (exploded ? " exploded" : ""); |
| } |
| |
| public static String getEjbClientArtifactName(Module module) { |
| return module.getName() + ":ejb-client"; |
| } |
| |
| public static String getIdeaVersionToPassToMavenProcess() { |
| return ApplicationInfoImpl.getShadowInstance().getMajorVersion() + "." + ApplicationInfoImpl.getShadowInstance().getMinorVersion(); |
| } |
| } |