diff options
author | Tor Norbye <tnorbye@google.com> | 2013-06-20 15:12:35 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-06-20 15:12:35 -0700 |
commit | 0e154c74931b6ff5ad6e0ec512b32e30df3cb068 (patch) | |
tree | f11327e8a38cd36b012c743a78e3dbf856b857f0 /plugins/maven | |
parent | 9a718963c1d41c5bcd3a1bdd5e518d497964ccdf (diff) | |
download | idea-0e154c74931b6ff5ad6e0ec512b32e30df3cb068.tar.gz |
Snapshot 4a019151cb9b5542ea5ba9ed2f07b29cee0951f0 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I2fd287fc46a5378a4c437af4c884c3a3be94c330
Diffstat (limited to 'plugins/maven')
23 files changed, 733 insertions, 400 deletions
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/DependencyId.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/DependencyId.java new file mode 100644 index 000000000000..f71270cd542b --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/DependencyId.java @@ -0,0 +1,63 @@ +package org.jetbrains.idea.maven.dom; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.dom.model.MavenDomDependency; + +/** +* @author Sergey Evdokimov +*/ +public class DependencyId { + private final String groupId; + private final String artifactId; + private final String type; + private final String classifier; + + public DependencyId(@NotNull String groupId, @NotNull String artifactId, @Nullable String type, @Nullable String classifier) { + this.groupId = groupId; + this.artifactId = artifactId; + this.type = StringUtil.isEmpty(type) ? "jar" : type; + this.classifier = classifier; + } + + @Nullable + public static DependencyId create(@NotNull MavenDomDependency dep) { + String groupId = dep.getGroupId().getStringValue(); + if (StringUtil.isEmpty(groupId)) return null; + + String artifactId = dep.getArtifactId().getStringValue(); + if (StringUtil.isEmpty(artifactId)) return null; + + //noinspection ConstantConditions + return new DependencyId(groupId, artifactId, dep.getType().getStringValue(), dep.getClassifier().getStringValue()); + } + + public boolean isValid() { + return StringUtil.isNotEmpty(groupId) && StringUtil.isNotEmpty(artifactId); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DependencyId)) return false; + + DependencyId id = (DependencyId)o; + + if (artifactId != null ? !artifactId.equals(id.artifactId) : id.artifactId != null) return false; + if (classifier != null ? !classifier.equals(id.classifier) : id.classifier != null) return false; + if (groupId != null ? !groupId.equals(id.groupId) : id.groupId != null) return false; + if (!type.equals(id.type)) return false; + + return true; + } + + @Override + public int hashCode() { + int result = groupId != null ? groupId.hashCode() : 0; + result = 31 * result + (artifactId != null ? artifactId.hashCode() : 0); + result = 31 * result + type.hashCode(); + result = 31 * result + (classifier != null ? classifier.hashCode() : 0); + return result; + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java index 246897a2cb53..fdb295875cc6 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java @@ -164,10 +164,9 @@ public class MavenDomProjectProcessorUtils { public static Set<MavenDomDependency> searchDependencyUsages(@NotNull final MavenDomDependency dependency) { final MavenDomProjectModel model = dependency.getParentOfType(MavenDomProjectModel.class, false); if (model != null) { - final String artifactId = dependency.getArtifactId().getStringValue(); - final String groupId = dependency.getGroupId().getStringValue(); - if (artifactId != null && groupId != null) { - return searchDependencyUsages(model, groupId, artifactId, Collections.singleton(dependency)); + DependencyId dependencyId = DependencyId.create(dependency); + if (dependencyId != null) { + return searchDependencyUsages(model, dependencyId, Collections.singleton(dependency)); } } return Collections.emptySet(); @@ -175,19 +174,8 @@ public class MavenDomProjectProcessorUtils { @NotNull public static Set<MavenDomDependency> searchDependencyUsages(@NotNull final MavenDomProjectModel model, - @NotNull final String groupId, - @NotNull final String artifactId) { - return searchDependencyUsages(model, groupId, artifactId, Collections.<MavenDomDependency>emptySet()); - } - - @NotNull - public static Set<MavenDomDependency> searchDependencyUsages(@NotNull final MavenDomProjectModel model, - @Nullable final String groupId, - @Nullable final String artifactId, + @NotNull final DependencyId dependencyId, @NotNull final Set<MavenDomDependency> excludes) { - - if (groupId == null || artifactId == null) return Collections.emptySet(); - Project project = model.getManager().getProject(); final Set<MavenDomDependency> usages = new HashSet<MavenDomDependency>(); Processor<MavenDomProjectModel> collectProcessor = new Processor<MavenDomProjectModel>() { @@ -195,8 +183,8 @@ public class MavenDomProjectProcessorUtils { if (!model.equals(mavenDomProjectModel)) { for (MavenDomDependency domDependency : mavenDomProjectModel.getDependencies().getDependencies()) { if (excludes.contains(domDependency)) continue; - if (artifactId.equals(domDependency.getArtifactId().getStringValue()) && - groupId.equals(domDependency.getGroupId().getStringValue())) { + + if (dependencyId.equals(DependencyId.create(domDependency))) { usages.add(domDependency); } } @@ -305,9 +293,8 @@ public class MavenDomProjectProcessorUtils { @Nullable public static MavenDomDependency searchManagingDependency(@NotNull final MavenDomDependency dependency, @NotNull final Project project) { - final String artifactId = dependency.getArtifactId().getStringValue(); - final String groupId = dependency.getGroupId().getStringValue(); - if (artifactId == null || groupId == null) return null; + final DependencyId depId = DependencyId.create(dependency); + if (depId == null) return null; final MavenDomProjectModel model = dependency.getParentOfType(MavenDomProjectModel.class, false); if (model == null) return null; @@ -316,8 +303,7 @@ public class MavenDomProjectProcessorUtils { @Override protected MavenDomDependency find(MavenDomDependencies mavenDomDependencies) { for (MavenDomDependency domDependency : mavenDomDependencies.getDependencies()) { - if (artifactId.equals(domDependency.getArtifactId().getStringValue()) && - groupId.equals(domDependency.getGroupId().getStringValue())) { + if (depId.equals(DependencyId.create(domDependency))) { return domDependency; } @@ -331,8 +317,7 @@ public class MavenDomProjectProcessorUtils { MavenDomProjectModel dependModel = MavenDomUtil.getMavenDomModel((PsiFile)resolve, MavenDomProjectModel.class); if (dependModel != null) { for (MavenDomDependency dep : dependModel.getDependencyManagement().getDependencies().getDependencies()) { - if (artifactId.equals(dep.getArtifactId().getStringValue()) && - groupId.equals(dep.getGroupId().getStringValue())) { + if (depId.equals(DependencyId.create(dep))) { return domDependency; } } @@ -592,6 +577,4 @@ public class MavenDomProjectProcessorUtils { return myResult; } } - - } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencyTypeConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencyTypeConverter.java index 932a9a7ad6bb..b4cb4a603368 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencyTypeConverter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencyTypeConverter.java @@ -17,10 +17,14 @@ package org.jetbrains.idea.maven.dom.converters; import com.intellij.util.xml.ConvertContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.model.MavenConstants; import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.idea.maven.project.MavenProjectsManager; import org.jetbrains.idea.maven.project.SupportedRequestType; import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Set; public class MavenDependencyTypeConverter extends MavenProjectConstantListConverter { public MavenDependencyTypeConverter() { @@ -29,6 +33,14 @@ public class MavenDependencyTypeConverter extends MavenProjectConstantListConver @Override protected Collection<String> getValues(@NotNull ConvertContext context, @NotNull MavenProject project) { - return project.getSupportedDependencyTypes(SupportedRequestType.FOR_COMPLETION); + Set<String> res = new LinkedHashSet<String>(); + + res.addAll(MavenProjectsManager.getInstance(context.getProject()).getImportingSettings().getDependencyTypesAsSet()); + + res.add(MavenConstants.TYPE_POM); + + res.addAll(project.getDependencyTypesFromImporters(SupportedRequestType.FOR_COMPLETION)); + + return res; } }
\ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java index dcfa5c2a8b34..bfdc3bde40f3 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/extract/ExtractManagedDependenciesAction.java @@ -34,6 +34,7 @@ import com.intellij.util.containers.hash.HashSet; import com.intellij.util.xml.DomUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.dom.DependencyId; import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; import org.jetbrains.idea.maven.dom.MavenDomUtil; import org.jetbrains.idea.maven.dom.model.MavenDomDependency; @@ -83,14 +84,14 @@ public class ExtractManagedDependenciesAction extends BaseRefactoringAction { MavenDomDependency.class); if (dependency == null || isManagedDependency(dependency)) return null; - Set<MavenDomProjectModel> parents = getParentProjects(file.getProject(), file); + Set<MavenDomProjectModel> parents = getParentProjects(file); if (parents.isEmpty()) return null; return Pair.create(dependency, parents); } @NotNull - private static Set<MavenDomProjectModel> getParentProjects(@NotNull Project project, @NotNull PsiFile file) { + private static Set<MavenDomProjectModel> getParentProjects(@NotNull PsiFile file) { final MavenDomProjectModel model = MavenDomUtil.getMavenDomModel(file, MavenDomProjectModel.class); if (model == null) return Collections.emptySet(); @@ -134,13 +135,11 @@ public class ExtractManagedDependenciesAction extends BaseRefactoringAction { if (typeValue != null) { addedDependency.getType().setStringValue(typeValue); - dependency.getType().undefine(); } String classifier = dependency.getClassifier().getStringValue(); if (classifier != null) { addedDependency.getClassifier().setStringValue(classifier); - dependency.getClassifier().undefine(); } String systemPath = dependency.getSystemPath().getStringValue(); @@ -219,10 +218,10 @@ public class ExtractManagedDependenciesAction extends BaseRefactoringAction { return new Function<MavenDomProjectModel, Set<MavenDomDependency>>() { public Set<MavenDomDependency> fun(MavenDomProjectModel model) { - String groupId = dependency.getGroupId().getStringValue(); - String artifactId = dependency.getArtifactId().getStringValue(); + DependencyId dependencyId = DependencyId.create(dependency); + if (dependencyId == null) return Collections.emptySet(); - return MavenDomProjectProcessorUtils.searchDependencyUsages(model, groupId, artifactId, Collections.singleton(dependency)); + return MavenDomProjectProcessorUtils.searchDependencyUsages(model, dependencyId, Collections.singleton(dependency)); } }; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenEditGoalDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenEditGoalDialog.java index 5bb135cdf7a3..635e1daa3368 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenEditGoalDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenEditGoalDialog.java @@ -19,10 +19,7 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileTypes.PlainTextFileType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.ComboBox; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.FixedSizeButton; -import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.ui.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.EditorComboBoxEditor; import com.intellij.ui.EditorComboBoxRenderer; @@ -117,6 +114,16 @@ public class MavenEditGoalDialog extends DialogWrapper { }); } + @Nullable + @Override + protected ValidationInfo doValidate() { + if (workDirectoryField.getText().trim().isEmpty()) { + return new ValidationInfo("Working directory is empty", workDirectoryField); + } + + return null; + } + @NotNull public String getGoals() { if (goalsComboBox != null) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExecuteGoalDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExecuteGoalDialog.java index dc238ba664d0..997101b45b0d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExecuteGoalDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenExecuteGoalDialog.java @@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.event.ActionEvent; import java.util.Collection; /** @@ -37,14 +36,8 @@ public class MavenExecuteGoalDialog extends MavenEditGoalDialog { @NotNull @Override protected Action getOKAction() { - return new DialogWrapperAction("&Execute") { - { - putValue(DEFAULT_ACTION, Boolean.TRUE); - } - @Override - protected void doAction(ActionEvent e) { - doOKAction(); - } - }; + Action action = super.getOKAction(); + action.putValue(Action.NAME, "&Execute"); + return action; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java index 1140cbc9ea83..90f67438db2f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java @@ -15,6 +15,8 @@ */ package org.jetbrains.idea.maven.importing; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.roots.*; @@ -25,6 +27,7 @@ import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; +import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -146,8 +149,26 @@ public class MavenModuleImporter { } private void configDependencies() { + THashSet<String> dependencyTypesFromSettings = new THashSet<String>(); + + AccessToken accessToken = ReadAction.start(); + try { + if (myModule.getProject().isDisposed()) return; + + dependencyTypesFromSettings.addAll(MavenProjectsManager.getInstance(myModule.getProject()).getImportingSettings().getDependencyTypesAsSet()); + } + finally { + accessToken.finish(); + } + + for (MavenArtifact artifact : myMavenProject.getDependencies()) { - if (!myMavenProject.isSupportedDependency(artifact, SupportedRequestType.FOR_IMPORT)) continue; + String dependencyType = artifact.getType(); + + if (!dependencyTypesFromSettings.contains(dependencyType) + && !myMavenProject.getDependencyTypesFromImporters(SupportedRequestType.FOR_IMPORT).contains(dependencyType)) { + continue; + } DependencyScope scope = selectScope(artifact.getScope()); @@ -155,7 +176,7 @@ public class MavenModuleImporter { if (depProject != null && !myMavenTree.isIgnored(depProject)) { if (depProject == myMavenProject) continue; - boolean isTestJar = MavenConstants.TYPE_TEST_JAR.equals(artifact.getType()) || "tests".equals(artifact.getClassifier()); + boolean isTestJar = MavenConstants.TYPE_TEST_JAR.equals(dependencyType) || "tests".equals(artifact.getClassifier()); myRootModelAdapter.addModuleDependency(myMavenProjectToModuleName.get(depProject), scope, isTestJar); Element buildHelperCfg = depProject.getPluginGoalConfiguration("org.codehaus.mojo", "build-helper-maven-plugin", "attach-artifact"); @@ -171,7 +192,7 @@ public class MavenModuleImporter { artifact.getArtifactId(), artifact.getVersion(), artifact.getBaseVersion(), - artifact.getType(), + dependencyType, artifact.getClassifier(), artifact.getScope(), artifact.isOptional(), diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java index a21d56081311..751e9a3432ae 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenRootModelAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -163,7 +163,7 @@ public class MavenRootModelAdapter { } public static boolean isEqualOrAncestor(String ancestor, String child) { - return ancestor.equals(child) || StringUtil.startsWithConcatenationOf(child, ancestor, "/"); + return ancestor.equals(child) || StringUtil.startsWithConcatenation(child, ancestor, "/"); } private boolean exists(String path) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java index 01186a5a1d5a..55dd3e31fdec 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java @@ -16,8 +16,13 @@ package org.jetbrains.idea.maven.navigator.actions; import com.intellij.execution.configurations.ParametersList; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -25,8 +30,10 @@ import org.jetbrains.idea.maven.execution.*; import org.jetbrains.idea.maven.project.MavenGeneralSettings; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; +import org.jetbrains.idea.maven.utils.MavenSettings; import org.jetbrains.idea.maven.utils.MavenUtil; +import javax.swing.event.HyperlinkEvent; import java.io.File; import java.util.Arrays; import java.util.LinkedHashMap; @@ -37,8 +44,8 @@ import java.util.List; */ public class MavenExecuteGoalAction extends DumbAwareAction { @Override - public void actionPerformed(AnActionEvent e) { - Project project = e.getRequiredData(PlatformDataKeys.PROJECT); + public void actionPerformed(final AnActionEvent e) { + final Project project = e.getRequiredData(PlatformDataKeys.PROJECT); ExecuteMavenGoalHistoryService historyService = ExecuteMavenGoalHistoryService.getInstance(project); @@ -77,8 +84,21 @@ public class MavenExecuteGoalAction extends DumbAwareAction { File mavenHome = MavenUtil.resolveMavenHomeDirectory(projectsManager.getGeneralSettings().getMavenHome()); if (mavenHome == null) { - // todo handle - throw new RuntimeException(); + Notification notification = new Notification(MavenUtil.MAVEN_NOTIFICATION_GROUP, + "Failed to execute goal", + RunnerBundle.message("external.maven.home.no.default.with.fix"), NotificationType.ERROR, + new NotificationListener() { + @Override + public void hyperlinkUpdate(@NotNull Notification notification, + @NotNull HyperlinkEvent event) { + if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + ShowSettingsUtil.getInstance().showSettingsDialog(project, MavenSettings.DISPLAY_NAME); + } + } + }); + + Notifications.Bus.notify(notification, project); + return; } MavenRunnerParameters parameters = new MavenRunnerParameters(true, workDirectory, Arrays.asList(ParametersList.parse(goals)), null); @@ -99,17 +119,4 @@ public class MavenExecuteGoalAction extends DumbAwareAction { return rootProjects.get(0).getDirectory(); } - - @Override - public void update(AnActionEvent e) { - Project project = e.getData(PlatformDataKeys.PROJECT); - - boolean hasMaven = false; - - if (project != null) { - hasMaven = MavenProjectsManager.getInstance(project).hasProjects(); - } - - e.getPresentation().setVisible(hasMaven); - } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java index c0bdf9b167a4..092af62a019c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenArtifactDownloader.java @@ -15,11 +15,15 @@ */ package org.jetbrains.idea.maven.project; +import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.LocalFileSystem; import gnu.trove.THashMap; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.importing.MavenExtraArtifactType; import org.jetbrains.idea.maven.model.*; @@ -38,33 +42,38 @@ public class MavenArtifactDownloader { new ThreadPoolExecutor(5, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() { AtomicInteger num = new AtomicInteger(); + @NotNull @Override - public Thread newThread(Runnable r) { + public Thread newThread(@NotNull Runnable r) { return new Thread(r, "Maven Artifact Downloader " + num.getAndIncrement()); } }); + private final Project myProject; private final MavenProjectsTree myProjectsTree; private final Collection<MavenProject> myMavenProjects; private final Collection<MavenArtifact> myArtifacts; private final MavenProgressIndicator myProgress; private final MavenEmbedderWrapper myEmbedder; - public static DownloadResult download(MavenProjectsTree projectsTree, + public static DownloadResult download(@NotNull Project project, + MavenProjectsTree projectsTree, Collection<MavenProject> mavenProjects, @Nullable Collection<MavenArtifact> artifacts, boolean downloadSources, boolean downloadDocs, MavenEmbedderWrapper embedder, MavenProgressIndicator p) throws MavenProcessCanceledException { - return new MavenArtifactDownloader(projectsTree, mavenProjects, artifacts, embedder, p).download(downloadSources, downloadDocs); + return new MavenArtifactDownloader(project, projectsTree, mavenProjects, artifacts, embedder, p).download(downloadSources, downloadDocs); } - private MavenArtifactDownloader(MavenProjectsTree projectsTree, + private MavenArtifactDownloader(@NotNull Project project, + MavenProjectsTree projectsTree, Collection<MavenProject> mavenProjects, Collection<MavenArtifact> artifacts, MavenEmbedderWrapper embedder, MavenProgressIndicator p) { + myProject = project; myProjectsTree = projectsTree; myMavenProjects = mavenProjects; myArtifacts = artifacts == null ? null : new THashSet<MavenArtifact>(artifacts); @@ -104,6 +113,18 @@ public class MavenArtifactDownloader { private Map<MavenId, DownloadData> collectArtifactsToDownload(List<MavenExtraArtifactType> types) { Map<MavenId, DownloadData> result = new THashMap<MavenId, DownloadData>(); + THashSet<String> dependencyTypesFromSettings = new THashSet<String>(); + + AccessToken accessToken = ReadAction.start(); + try { + if (myProject.isDisposed()) return result; + + dependencyTypesFromSettings.addAll(MavenProjectsManager.getInstance(myProject).getImportingSettings().getDependencyTypesAsSet()); + } + finally { + accessToken.finish(); + } + for (MavenProject eachProject : myMavenProjects) { List<MavenRemoteRepository> repositories = eachProject.getRemoteRepositories(); @@ -112,7 +133,13 @@ public class MavenArtifactDownloader { if (MavenConstants.SCOPE_SYSTEM.equalsIgnoreCase(eachDependency.getScope())) continue; if (myProjectsTree.findProject(eachDependency.getMavenId()) != null) continue; - if (!eachProject.isSupportedDependency(eachDependency, SupportedRequestType.FOR_IMPORT)) continue; + + String dependencyType = eachDependency.getType(); + + if (!dependencyTypesFromSettings.contains(dependencyType) + && !eachProject.getDependencyTypesFromImporters(SupportedRequestType.FOR_IMPORT).contains(dependencyType)) { + continue; + } MavenId id = eachDependency.getMavenId(); DownloadData data = result.get(id); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettings.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettings.java index 12f7adeba2ba..9da6703d3f34 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettings.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettings.java @@ -19,7 +19,10 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Property; import org.jetbrains.annotations.NotNull; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; public class MavenImportingSettings implements Cloneable { private static final String PROCESS_RESOURCES_PHASE = "process-resources"; @@ -50,6 +53,9 @@ public class MavenImportingSettings implements Cloneable { private GeneratedSourcesFolder generatedSourcesFolder = GeneratedSourcesFolder.AUTODETECT; + private String dependencyTypes = "jar, test-jar, maven-plugin, ejb, ejb-client, jboss-har, jboss-sar, war, ear, bundle"; + private Set<String> myDependencyTypesAsSet; + private List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); public enum GeneratedSourcesFolder { @@ -91,6 +97,30 @@ public class MavenImportingSettings implements Cloneable { fireAutoImportChanged(); } + @NotNull + public String getDependencyTypes() { + return dependencyTypes; + } + + public void setDependencyTypes(@NotNull String dependencyTypes) { + this.dependencyTypes = dependencyTypes; + myDependencyTypesAsSet = null; + } + + @NotNull + public Set<String> getDependencyTypesAsSet() { + if (myDependencyTypesAsSet == null) { + Set<String> res = new LinkedHashSet<String>(); + + for (StringTokenizer st = new StringTokenizer(dependencyTypes, " \n\r\t,;"); st.hasMoreTokens(); ) { + res.add(st.nextToken()); + } + + myDependencyTypesAsSet = res; + } + return myDependencyTypesAsSet; + } + public boolean isCreateModuleGroups() { return createModuleGroups; } @@ -179,6 +209,7 @@ public class MavenImportingSettings implements Cloneable { if (createModuleGroups != that.createModuleGroups) return false; if (createModulesForAggregators != that.createModulesForAggregators) return false; if (importAutomatically != that.importAutomatically) return false; + if (!dependencyTypes.equals(that.dependencyTypes)) return false; if (downloadDocsAutomatically != that.downloadDocsAutomatically) return false; if (downloadSourcesAutomatically != that.downloadSourcesAutomatically) return false; if (lookForNested != that.lookForNested) return false; @@ -220,6 +251,7 @@ public class MavenImportingSettings implements Cloneable { result = 31 * result + (updateFoldersOnImportPhase != null ? updateFoldersOnImportPhase.hashCode() : 0); result = 31 * result + dedicatedModuleDir.hashCode(); result = 31 * result + generatedSourcesFolder.hashCode(); + result = 31 * result + dependencyTypes.hashCode(); return result; } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form index 48408f7a7cec..124bdea09db6 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.form @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.idea.maven.project.MavenImportingSettingsForm"> - <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="17" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="19" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="536" height="565"/> + <xy x="20" y="20" width="769" height="577"/> </constraints> <properties/> <border type="none"/> <children> <component id="b48ca" class="javax.swing.JCheckBox" binding="myCreateModulesForAggregators"> <constraints> - <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Create $FULLNAME$ &modules for aggregator projects (with 'pom' packaging)"/> @@ -18,7 +18,7 @@ </component> <component id="2b9b5" class="javax.swing.JCheckBox" binding="myCreateGroupsCheckBox" default-binding="true"> <constraints> - <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="6" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Create module &groups for multi-module Maven projects"/> @@ -26,7 +26,7 @@ </component> <component id="d7aa1" class="javax.swing.JCheckBox" binding="mySearchRecursivelyCheckBox"> <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="&Search for projects recursively"/> @@ -34,7 +34,7 @@ </component> <component id="1b499" class="javax.swing.JCheckBox" binding="myUseMavenOutputCheckBox"> <constraints> - <grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="9" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Use Maven &output directories"/> @@ -43,7 +43,7 @@ </component> <component id="22b1c" class="com.intellij.ui.components.JBLabel"> <constraints> - <grid row="13" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="3" use-parent-layout="false"/> + <grid row="13" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="3" use-parent-layout="false"/> </constraints> <properties> <componentStyle value="SMALL"/> @@ -53,7 +53,7 @@ </component> <component id="323ff" class="javax.swing.JCheckBox" binding="myImportAutomaticallyBox"> <constraints> - <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Import Maven projects &automatically"/> @@ -63,7 +63,7 @@ <grid id="49dc8" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="10" left="0" bottom="0" right="0"/> <constraints> - <grid row="14" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="14" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties> <focusable value="true"/> @@ -103,7 +103,7 @@ </grid> <component id="6d280" class="javax.swing.JCheckBox" binding="myKeepSourceFoldersCheckBox"> <constraints> - <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="7" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Keep source and test &folders on reimport"/> @@ -112,7 +112,7 @@ <grid id="d7645" binding="myAdditionalSettingsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="15" left="0" bottom="0" right="0"/> <constraints> - <grid row="15" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/> + <grid row="17" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> @@ -120,13 +120,13 @@ </grid> <hspacer id="d45a7"> <constraints> - <grid row="14" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> + <grid row="14" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> </constraints> </hspacer> <grid id="eca06" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> @@ -157,7 +157,7 @@ <grid id="7fb78" binding="mySeparateModulesDirPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="10" right="0"/> <constraints> - <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> @@ -180,13 +180,13 @@ </grid> <vspacer id="5d738"> <constraints> - <grid row="16" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + <grid row="18" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> </constraints> </vspacer> <grid id="34bc4" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="12" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="12" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> @@ -215,14 +215,14 @@ </grid> <vspacer id="aa40b"> <constraints> - <grid row="11" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"> + <grid row="11" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"> <preferred-size width="-1" height="10"/> </grid> </constraints> </vspacer> <vspacer id="6351f"> <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"> + <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"> <preferred-size width="-1" height="10"/> </grid> </constraints> @@ -230,7 +230,7 @@ <grid id="f9c12" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <grid row="10" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + <grid row="10" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> </constraints> <properties/> <border type="none"/> @@ -258,13 +258,45 @@ </grid> <component id="af108" class="javax.swing.JCheckBox" binding="myExcludeTargetFolderCheckBox"> <constraints> - <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="8" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Exclude build directory (%PROJECT_ROOT%/target)"/> <toolTipText value="If you select this options folder /target will be excluded from project during reimport. Compiler output (/target/classes and /target/test-classes) will be excluded anyway"/> </properties> </component> + <component id="2e377" class="javax.swing.JLabel"> + <constraints> + <grid row="15" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <labelFor value="83bca"/> + <text value="Dependency types:"/> + <toolTipText value="Comma separated list of dependency types those must be added as external libraries on import"/> + </properties> + </component> + <component id="83bca" class="javax.swing.JTextField" binding="myDependencyTypes"> + <constraints> + <grid row="15" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="60" height="-1"/> + </grid> + </constraints> + <properties> + <columns value="0"/> + <toolTipText value="Comma separated list of dependency types those must be added as external libraries on import"/> + </properties> + </component> + <component id="d634c" class="com.intellij.ui.components.JBLabel"> + <constraints> + <grid row="16" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <componentStyle value="SMALL"/> + <fontColor value="BRIGHTER"/> + <labelFor value="83bca"/> + <text value="Comma separated list of dependency types those must be added as external libraries on import"/> + </properties> + </component> </children> </grid> <buttonGroups> diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java index da4dc0a5d642..ea7e0f76f241 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenImportingSettingsForm.java @@ -15,15 +15,15 @@ */ package org.jetbrains.idea.maven.project; -import com.intellij.openapi.updateSettings.impl.LabelTextReplacingUtil; -import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.updateSettings.impl.LabelTextReplacingUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.projectImport.ProjectFormatPanel; import com.intellij.ui.EnumComboBoxModel; +import com.intellij.ui.ListCellRendererWrapper; import javax.swing.*; import java.awt.event.ActionEvent; @@ -53,6 +53,7 @@ public class MavenImportingSettingsForm { private JPanel mySeparateModulesDirPanel; private JComboBox myGeneratedSourcesComboBox; private JCheckBox myExcludeTargetFolderCheckBox; + private JTextField myDependencyTypes; public MavenImportingSettingsForm(boolean isImportStep, boolean isCreatingNewProject) { mySearchRecursivelyCheckBox.setVisible(isImportStep); @@ -123,6 +124,8 @@ public class MavenImportingSettingsForm { data.setDownloadSourcesAutomatically(myDownloadSourcesCheckBox.isSelected()); data.setDownloadDocsAutomatically(myDownloadDocsCheckBox.isSelected()); + + data.setDependencyTypes(myDependencyTypes.getText()); } public void setData(MavenImportingSettings data) { @@ -145,6 +148,8 @@ public class MavenImportingSettingsForm { myDownloadSourcesCheckBox.setSelected(data.isDownloadSourcesAutomatically()); myDownloadDocsCheckBox.setSelected(data.isDownloadDocsAutomatically()); + myDependencyTypes.setText(data.getDependencyTypes()); + updateControls(); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java index 8561b2b076bf..cfc525f80bf7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProject.java @@ -789,10 +789,6 @@ public class MavenProject { return myState.myDependencyTree; } - public boolean isSupportedDependency(@NotNull MavenArtifact artifact, @NotNull SupportedRequestType type) { - return getSupportedDependencyTypes(type).contains(artifact.getType()); - } - @NotNull public Set<String> getSupportedPackagings() { Set<String> result = ContainerUtil.newHashSet(MavenConstants.TYPE_POM, @@ -804,20 +800,14 @@ public class MavenProject { return result; } - @NotNull - public Set<String> getSupportedDependencyTypes(@NotNull SupportedRequestType type) { - Set<String> result = ContainerUtil.newTroveSet(MavenConstants.TYPE_JAR, - MavenConstants.TYPE_TEST_JAR, - "maven-plugin", - "ejb", "ejb-client", "jboss-har", "jboss-sar", "war", "ear", "bundle"); - if (type == SupportedRequestType.FOR_COMPLETION) { - result.add(MavenConstants.TYPE_POM); - } + public Set<String> getDependencyTypesFromImporters(@NotNull SupportedRequestType type) { + THashSet<String> res = new THashSet<String>(); for (MavenImporter each : getSuitableImporters()) { - each.getSupportedDependencyTypes(result, type); + each.getSupportedDependencyTypes(res, type); } - return result; + + return res; } @NotNull diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index 0d5cf0f21688..00342683d535 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -16,7 +16,6 @@ package org.jetbrains.idea.maven.project; import com.intellij.compiler.CompilerWorkspaceConfiguration; -import com.intellij.compiler.server.BuildManager; import com.intellij.ide.startup.StartupManagerEx; import com.intellij.openapi.application.AccessToken; import com.intellij.openapi.application.ApplicationManager; @@ -30,7 +29,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; @@ -41,15 +39,11 @@ import com.intellij.util.EventDispatcher; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.Update; -import com.intellij.util.xmlb.XmlSerializer; import gnu.trove.THashMap; import gnu.trove.THashSet; -import org.jdom.Document; -import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.idea.maven.dom.references.MavenFilteredPropertyPsiReferenceProvider; import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider; import org.jetbrains.idea.maven.importing.MavenFoldersImporter; import org.jetbrains.idea.maven.importing.MavenModifiableModelsProvider; @@ -57,12 +51,9 @@ import org.jetbrains.idea.maven.importing.MavenProjectImporter; import org.jetbrains.idea.maven.model.*; import org.jetbrains.idea.maven.server.NativeMavenProjectHolder; import org.jetbrains.idea.maven.utils.*; -import org.jetbrains.jps.maven.model.impl.MavenIdBean; -import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration; -import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration; -import org.jetbrains.jps.maven.model.impl.ResourceRootConfiguration; -import java.io.*; +import java.io.File; +import java.io.IOException; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -177,7 +168,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent try { if (!CompilerWorkspaceConfiguration.getInstance(myProject).useOutOfProcessBuild()) return true; - generateBuildConfiguration(context.isRebuild()); + new MavenResourceCompilerConfigurationGenerator(myProject, myProjectsTree).generateBuildConfiguration(context.isRebuild()); } finally { token.finish(); @@ -1041,160 +1032,6 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent return projectImporter.getCreatedModules(); } - public void generateBuildConfiguration(boolean force) { - if (!isMavenizedProject()) { - return; - } - final BuildManager buildManager = BuildManager.getInstance(); - final File projectSystemDir = buildManager.getProjectSystemDirectory(myProject); - if (projectSystemDir == null) { - return; - } - - final File mavenConfigFile = new File(projectSystemDir, MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH); - - ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); - - final int crc = myProjectsTree.getFilterConfigCrc(fileIndex); - - final File crcFile = new File(mavenConfigFile.getParent(), "configuration.crc"); - - if (!force) { - try { - DataInputStream crcInput = new DataInputStream(new FileInputStream(crcFile)); - try { - if (crcInput.readInt() == crc) return; // Project had not change since last config generation. - } - finally { - crcInput.close(); - } - } - catch (IOException ignored) { - // // Config file is not generated. - } - } - - MavenProjectConfiguration projectConfig = new MavenProjectConfiguration(); - - for (MavenProject mavenProject : getProjects()) { - VirtualFile pomXml = mavenProject.getFile(); - - Module module = fileIndex.getModuleForFile(pomXml); - if (module == null) continue; - - if (mavenProject.getDirectoryFile() != fileIndex.getContentRootForFile(pomXml)) continue; - - MavenModuleResourceConfiguration resourceConfig = new MavenModuleResourceConfiguration(); - - MavenId projectId = mavenProject.getMavenId(); - resourceConfig.id = new MavenIdBean(projectId.getGroupId(), projectId.getArtifactId(), projectId.getVersion()); - - MavenId parentId = mavenProject.getParentId(); - if (parentId != null) { - resourceConfig.parentId = new MavenIdBean(parentId.getGroupId(), parentId.getArtifactId(), parentId.getVersion()); - } - resourceConfig.directory = FileUtil.toSystemIndependentName(mavenProject.getDirectory()); - resourceConfig.delimitersPattern = MavenFilteredPropertyPsiReferenceProvider.getDelimitersPattern(mavenProject).pattern(); - for (Map.Entry<String, String> entry : mavenProject.getModelMap().entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - if (value != null) { - resourceConfig.modelMap.put(key, value); - } - } - addResources(resourceConfig.resources, mavenProject.getResources()); - addResources(resourceConfig.testResources, mavenProject.getTestResources()); - resourceConfig.filteringExclusions.addAll(MavenProjectsTree.getFilterExclusions(mavenProject)); - final Properties properties = getFilteringProperties(mavenProject); - for (Map.Entry<Object, Object> propEntry : properties.entrySet()) { - resourceConfig.properties.put((String)propEntry.getKey(), (String)propEntry.getValue()); - } - - Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"); - resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", "\\"); - String escapeWindowsPaths = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths"); - if (escapeWindowsPaths != null) { - resourceConfig.escapeWindowsPaths = Boolean.parseBoolean(escapeWindowsPaths); - } - - projectConfig.moduleConfigurations.put(module.getName(), resourceConfig); - } - - final Document document = new Document(new Element("maven-project-configuration")); - XmlSerializer.serializeInto(projectConfig, document.getRootElement()); - buildManager.runCommand(new Runnable() { - @Override - public void run() { - buildManager.clearState(myProject); - FileUtil.createIfDoesntExist(mavenConfigFile); - try { - JDOMUtil.writeDocument(document, mavenConfigFile, "\n"); - - DataOutputStream crcOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(crcFile))); - try { - crcOutput.writeInt(crc); - } - finally { - crcOutput.close(); - } - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - }); - } - - private static void addResources(final List<ResourceRootConfiguration> container, Collection<MavenResource> resources) { - for (MavenResource resource : resources) { - final String dir = resource.getDirectory(); - if (dir == null) { - continue; - } - - final ResourceRootConfiguration props = new ResourceRootConfiguration(); - props.directory = FileUtil.toSystemIndependentName(dir); - - final String target = resource.getTargetPath(); - props.targetPath = target != null ? FileUtil.toSystemIndependentName(target) : null; - - props.isFiltered = resource.isFiltered(); - props.includes.clear(); - for (String include : resource.getIncludes()) { - props.includes.add(include.trim()); - } - props.excludes.clear(); - for (String exclude : resource.getExcludes()) { - props.excludes.add(exclude.trim()); - } - container.add(props); - } - } - - private static Properties getFilteringProperties(MavenProject mavenProject) { - final Properties properties = new Properties(); - - for (String each : mavenProject.getFilters()) { - try { - FileInputStream in = new FileInputStream(each); - try { - properties.load(in); - } - finally { - in.close(); - } - } - catch (IOException ignored) { - } - } - - properties.putAll(mavenProject.getProperties()); - - properties.put("settings.localRepository", mavenProject.getLocalRepository().getAbsolutePath()); - - return properties; - } - private Map<VirtualFile, Module> getFileToModuleMapping(MavenModelsProvider modelsProvider) { Map<VirtualFile, Module> result = new THashMap<VirtualFile, Module>(); for (Module each : modelsProvider.getModules()) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java index 465a72c9ac20..50589c20a815 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java @@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.util.PathUtil; +import com.intellij.util.containers.ConcurrentWeakHashMap; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.update.Update; import gnu.trove.THashSet; @@ -53,9 +54,13 @@ import org.jetbrains.idea.maven.utils.MavenMergingUpdateQueue; import org.jetbrains.idea.maven.utils.MavenUtil; import java.io.File; +import java.io.IOException; import java.util.*; public class MavenProjectsManagerWatcher { + + private static final Key<ConcurrentWeakHashMap<Project, Integer>> CRC_WITHOUT_SPACES = Key.create("MavenProjectsManagerWatcher.CRC_WITHOUT_SPACES"); + public static final Key<Boolean> FORCE_IMPORT_AND_RESOLVE_ON_REFRESH = Key.create(MavenProjectsManagerWatcher.class + "FORCE_IMPORT_AND_RESOLVE_ON_REFRESH"); @@ -325,10 +330,8 @@ public class MavenProjectsManagerWatcher { } private boolean isProfilesFile(String path) { - String suffix = "/" + MavenConstants.PROFILES_XML; - if (!path.endsWith(suffix)) return false; - int pos = path.lastIndexOf(suffix); - return myProjectsTree.isPotentialProject(path.substring(0, pos) + "/" + MavenConstants.POM_XML); + if (!path.endsWith("/" + MavenConstants.PROFILES_XML)) return false; + return myProjectsTree.isPotentialProject(path.substring(0, path.length() - MavenConstants.PROFILES_XML.length()) + MavenConstants.POM_XML); } private boolean isSettingsFile(String path) { @@ -358,16 +361,16 @@ public class MavenProjectsManagerWatcher { } @Override - protected void updateFile(VirtualFile file) { - doUpdateFile(file, false); + protected void updateFile(VirtualFile file, VFileEvent event) { + doUpdateFile(file, event, false); } @Override - protected void deleteFile(VirtualFile file) { - doUpdateFile(file, true); + protected void deleteFile(VirtualFile file, VFileEvent event) { + doUpdateFile(file, event, true); } - private void doUpdateFile(VirtualFile file, boolean remove) { + private void doUpdateFile(VirtualFile file, VFileEvent event, boolean remove) { initLists(); if (isSettingsFile(file)) { @@ -381,7 +384,9 @@ public class MavenProjectsManagerWatcher { VirtualFile pom = getPomFileProfilesFile(file); if (pom != null) { - filesToUpdate.add(pom); + if (remove || xmlFileWasChanged(pom, event)) { + filesToUpdate.add(pom); + } return; } @@ -389,7 +394,36 @@ public class MavenProjectsManagerWatcher { filesToRemove.add(file); } else { - filesToUpdate.add(file); + if (xmlFileWasChanged(file, event)) { + filesToUpdate.add(file); + } + } + } + + private boolean xmlFileWasChanged(VirtualFile xmlFile, VFileEvent event) { + if (!xmlFile.isValid() || !(event instanceof VFileContentChangeEvent)) return true; + + ConcurrentWeakHashMap<Project, Integer> map = xmlFile.getUserData(CRC_WITHOUT_SPACES); + if (map == null) { + map = xmlFile.putUserDataIfAbsent(CRC_WITHOUT_SPACES, new ConcurrentWeakHashMap<Project, Integer>()); + } + + Integer crc = map.get(myProject); + Integer newCrc; + + try { + newCrc = MavenUtil.crcWithoutSpaces(xmlFile); + } + catch (IOException ignored) { + return true; + } + + if (newCrc.equals(crc)) { + return false; + } + else { + map.put(myProject, newCrc); + return true; } } @@ -444,9 +478,9 @@ public class MavenProjectsManagerWatcher { private static abstract class MyFileChangeListenerBase implements BulkFileListener { protected abstract boolean isRelevant(String path); - protected abstract void updateFile(VirtualFile file); + protected abstract void updateFile(VirtualFile file, VFileEvent event); - protected abstract void deleteFile(VirtualFile file); + protected abstract void deleteFile(VirtualFile file, VFileEvent event); protected abstract void apply(); @@ -454,31 +488,31 @@ public class MavenProjectsManagerWatcher { public void before(@NotNull List<? extends VFileEvent> events) { for (VFileEvent each : events) { if (each instanceof VFileDeleteEvent) { - deleteRecursively(each.getFile()); + deleteRecursively(each.getFile(), each); } else { if (!isRelevant(each.getPath())) continue; if (each instanceof VFilePropertyChangeEvent) { if (isRenamed(each)) { - deleteRecursively(each.getFile()); + deleteRecursively(each.getFile(), each); } } else if (each instanceof VFileMoveEvent) { VFileMoveEvent moveEvent = (VFileMoveEvent)each; String newPath = moveEvent.getNewParent().getPath() + "/" + moveEvent.getFile().getName(); if (!isRelevant(newPath)) { - deleteRecursively(moveEvent.getFile()); + deleteRecursively(moveEvent.getFile(), each); } } } } } - private void deleteRecursively(VirtualFile f) { + private void deleteRecursively(VirtualFile f, final VFileEvent event) { VfsUtilCore.visitChildrenRecursively(f, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile f) { - if (isRelevant(f.getPath())) deleteFile(f); + if (isRelevant(f.getPath())) deleteFile(f, event); return true; } @@ -499,26 +533,26 @@ public class MavenProjectsManagerWatcher { VFileCreateEvent createEvent = (VFileCreateEvent)each; VirtualFile newChild = createEvent.getParent().findChild(createEvent.getChildName()); if (newChild != null) { - updateFile(newChild); + updateFile(newChild, each); } } else if (each instanceof VFileCopyEvent) { VFileCopyEvent copyEvent = (VFileCopyEvent)each; VirtualFile newChild = copyEvent.getNewParent().findChild(copyEvent.getNewChildName()); if (newChild != null) { - updateFile(newChild); + updateFile(newChild, each); } } else if (each instanceof VFileContentChangeEvent) { - updateFile(each.getFile()); + updateFile(each.getFile(), each); } else if (each instanceof VFilePropertyChangeEvent) { if (isRenamed(each)) { - updateFile(each.getFile()); + updateFile(each.getFile(), each); } } else if (each instanceof VFileMoveEvent) { - updateFile(each.getFile()); + updateFile(each.getFile(), each); } } apply(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessorArtifactsDownloadingTask.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessorArtifactsDownloadingTask.java index ddf7b4630d9f..0e3c07936f2d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessorArtifactsDownloadingTask.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsProcessorArtifactsDownloadingTask.java @@ -53,7 +53,7 @@ public class MavenProjectsProcessorArtifactsDownloadingTask implements MavenProj public void perform(final Project project, MavenEmbeddersManager embeddersManager, MavenConsole console, MavenProgressIndicator indicator) throws MavenProcessCanceledException { MavenArtifactDownloader.DownloadResult result = - myTree.downloadSourcesAndJavadocs(myProjects, myArtifacts, myDownloadSources, myDownloadDocs, embeddersManager, console, indicator); + myTree.downloadSourcesAndJavadocs(project, myProjects, myArtifacts, myDownloadSources, myDownloadDocs, embeddersManager, console, indicator); if (myCallbackResult != null) myCallbackResult.setDone(result); // todo: hack to update all file pointers. diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java index 8af95731bd9d..aaf26215eef9 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java @@ -1243,7 +1243,8 @@ public class MavenProjectsTree { }); } - public MavenArtifactDownloader.DownloadResult downloadSourcesAndJavadocs(@NotNull Collection<MavenProject> projects, + public MavenArtifactDownloader.DownloadResult downloadSourcesAndJavadocs(@NotNull Project project, + @NotNull Collection<MavenProject> projects, @Nullable Collection<MavenArtifact> artifacts, boolean downloadSources, boolean downloadDocs, @@ -1256,7 +1257,7 @@ public class MavenProjectsTree { try { MavenArtifactDownloader.DownloadResult result = - MavenArtifactDownloader.download(this, projects, artifacts, downloadSources, downloadDocs, embedder, process); + MavenArtifactDownloader.download(project, this, projects, artifacts, downloadSources, downloadDocs, embedder, process); for (MavenProject each : projects) { fireArtifactsDownloaded(each); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java new file mode 100644 index 000000000000..ff4aab87c5c2 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java @@ -0,0 +1,287 @@ +package org.jetbrains.idea.maven.project; + +import com.intellij.compiler.CompilerConfiguration; +import com.intellij.compiler.CompilerConfigurationImpl; +import com.intellij.compiler.server.BuildManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Document; +import org.jdom.Element; +import org.jetbrains.idea.maven.dom.references.MavenFilteredPropertyPsiReferenceProvider; +import org.jetbrains.idea.maven.model.MavenId; +import org.jetbrains.idea.maven.model.MavenResource; +import org.jetbrains.idea.maven.utils.MavenJDOMUtil; +import org.jetbrains.jps.maven.model.impl.MavenIdBean; +import org.jetbrains.jps.maven.model.impl.MavenModuleResourceConfiguration; +import org.jetbrains.jps.maven.model.impl.MavenProjectConfiguration; +import org.jetbrains.jps.maven.model.impl.ResourceRootConfiguration; + +import java.io.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Sergey Evdokimov + */ +public class MavenResourceCompilerConfigurationGenerator { + + private static final Pattern SIMPLE_NEGATIVE_PATTERN = Pattern.compile("!\\?(\\*\\.\\w+)"); + + private final Project myProject; + + private final MavenProjectsManager myMavenProjectsManager; + + private final MavenProjectsTree myProjectsTree; + + public MavenResourceCompilerConfigurationGenerator(Project project, MavenProjectsTree projectsTree) { + myProject = project; + myMavenProjectsManager = MavenProjectsManager.getInstance(project); + myProjectsTree = projectsTree; + } + + public void generateBuildConfiguration(boolean force) { + if (!myMavenProjectsManager.isMavenizedProject()) { + return; + } + + final BuildManager buildManager = BuildManager.getInstance(); + final File projectSystemDir = buildManager.getProjectSystemDirectory(myProject); + if (projectSystemDir == null) { + return; + } + + final File mavenConfigFile = new File(projectSystemDir, MavenProjectConfiguration.CONFIGURATION_FILE_RELATIVE_PATH); + + ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject); + + ProjectFileIndex fileIndex = projectRootManager.getFileIndex(); + + final int crc = myProjectsTree.getFilterConfigCrc(fileIndex) + (int)projectRootManager.getModificationCount(); + + final File crcFile = new File(mavenConfigFile.getParent(), "configuration.crc"); + + if (!force) { + try { + DataInputStream crcInput = new DataInputStream(new FileInputStream(crcFile)); + try { + if (crcInput.readInt() == crc) return; // Project had not change since last config generation. + } + finally { + crcInput.close(); + } + } + catch (IOException ignored) { + // // Config file is not generated. + } + } + + MavenProjectConfiguration projectConfig = new MavenProjectConfiguration(); + + for (MavenProject mavenProject : myMavenProjectsManager.getProjects()) { + VirtualFile pomXml = mavenProject.getFile(); + + Module module = fileIndex.getModuleForFile(pomXml); + if (module == null) continue; + + if (mavenProject.getDirectoryFile() != fileIndex.getContentRootForFile(pomXml)) continue; + + MavenModuleResourceConfiguration resourceConfig = new MavenModuleResourceConfiguration(); + + MavenId projectId = mavenProject.getMavenId(); + resourceConfig.id = new MavenIdBean(projectId.getGroupId(), projectId.getArtifactId(), projectId.getVersion()); + + MavenId parentId = mavenProject.getParentId(); + if (parentId != null) { + resourceConfig.parentId = new MavenIdBean(parentId.getGroupId(), parentId.getArtifactId(), parentId.getVersion()); + } + resourceConfig.directory = FileUtil.toSystemIndependentName(mavenProject.getDirectory()); + resourceConfig.delimitersPattern = MavenFilteredPropertyPsiReferenceProvider.getDelimitersPattern(mavenProject).pattern(); + for (Map.Entry<String, String> entry : mavenProject.getModelMap().entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + if (value != null) { + resourceConfig.modelMap.put(key, value); + } + } + addResources(resourceConfig.resources, mavenProject.getResources()); + addResources(resourceConfig.testResources, mavenProject.getTestResources()); + resourceConfig.filteringExclusions.addAll(MavenProjectsTree.getFilterExclusions(mavenProject)); + final Properties properties = getFilteringProperties(mavenProject); + for (Map.Entry<Object, Object> propEntry : properties.entrySet()) { + resourceConfig.properties.put((String)propEntry.getKey(), (String)propEntry.getValue()); + } + + Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin"); + resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", "\\"); + String escapeWindowsPaths = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths"); + if (escapeWindowsPaths != null) { + resourceConfig.escapeWindowsPaths = Boolean.parseBoolean(escapeWindowsPaths); + } + + projectConfig.moduleConfigurations.put(module.getName(), resourceConfig); + } + + addNonMavenResources(projectConfig); + + final Document document = new Document(new Element("maven-project-configuration")); + XmlSerializer.serializeInto(projectConfig, document.getRootElement()); + buildManager.runCommand(new Runnable() { + @Override + public void run() { + buildManager.clearState(myProject); + FileUtil.createIfDoesntExist(mavenConfigFile); + try { + JDOMUtil.writeDocument(document, mavenConfigFile, "\n"); + + DataOutputStream crcOutput = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(crcFile))); + try { + crcOutput.writeInt(crc); + } + finally { + crcOutput.close(); + } + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + }); + } + + private static Properties getFilteringProperties(MavenProject mavenProject) { + final Properties properties = new Properties(); + + for (String each : mavenProject.getFilters()) { + try { + FileInputStream in = new FileInputStream(each); + try { + properties.load(in); + } + finally { + in.close(); + } + } + catch (IOException ignored) { + } + } + + properties.putAll(mavenProject.getProperties()); + + properties.put("settings.localRepository", mavenProject.getLocalRepository().getAbsolutePath()); + + return properties; + } + + private static void addResources(final List<ResourceRootConfiguration> container, Collection<MavenResource> resources) { + for (MavenResource resource : resources) { + final String dir = resource.getDirectory(); + if (dir == null) { + continue; + } + + final ResourceRootConfiguration props = new ResourceRootConfiguration(); + props.directory = FileUtil.toSystemIndependentName(dir); + + final String target = resource.getTargetPath(); + props.targetPath = target != null ? FileUtil.toSystemIndependentName(target) : null; + + props.isFiltered = resource.isFiltered(); + props.includes.clear(); + for (String include : resource.getIncludes()) { + props.includes.add(include.trim()); + } + props.excludes.clear(); + for (String exclude : resource.getExcludes()) { + props.excludes.add(exclude.trim()); + } + container.add(props); + } + } + + private void addNonMavenResources(MavenProjectConfiguration projectCfg) { + Set<VirtualFile> processedRoots = new HashSet<VirtualFile>(); + + for (MavenProject project : myMavenProjectsManager.getProjects()) { + for (String dir : ContainerUtil.concat(project.getSources(), project.getTestSources())) { + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(dir); + if (file != null) { + processedRoots.add(file); + } + } + + for (MavenResource resource : ContainerUtil.concat(project.getResources(), project.getTestResources())) { + VirtualFile file = LocalFileSystem.getInstance().findFileByPath(resource.getDirectory()); + if (file != null) { + processedRoots.add(file); + } + } + } + + CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(myProject); + + for (Module module : ModuleManager.getInstance(myProject).getModules()) { + if (!myMavenProjectsManager.isMavenizedModule(module)) continue; + + for (ContentEntry contentEntry : ModuleRootManager.getInstance(module).getContentEntries()) { + for (SourceFolder folder : contentEntry.getSourceFolders()) { + VirtualFile file = folder.getFile(); + if (file == null) continue; + + if (!compilerConfiguration.isExcludedFromCompilation(file) && !isUnderRoots(processedRoots, file)) { + MavenModuleResourceConfiguration configuration = projectCfg.moduleConfigurations.get(module.getName()); + if (configuration == null) continue; + + List<ResourceRootConfiguration> resourcesList = folder.isTestSource() ? configuration.testResources : configuration.resources; + + final ResourceRootConfiguration cfg = new ResourceRootConfiguration(); + cfg.directory = FileUtil.toSystemIndependentName(FileUtil.toSystemIndependentName(file.getPath())); + + CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module); + if (compilerModuleExtension == null) continue; + + + String compilerOutputUrl = folder.isTestSource() + ? compilerModuleExtension.getCompilerOutputUrlForTests() + : compilerModuleExtension.getCompilerOutputUrl(); + + cfg.targetPath = VfsUtil.urlToPath(compilerOutputUrl); + + convertIdeaExcludesToMavenExcludes(cfg, (CompilerConfigurationImpl)compilerConfiguration); + + resourcesList.add(cfg); + } + } + } + } + } + + private static void convertIdeaExcludesToMavenExcludes(ResourceRootConfiguration cfg, CompilerConfigurationImpl compilerConfiguration) { + for (String pattern : compilerConfiguration.getResourceFilePatterns()) { + Matcher matcher = SIMPLE_NEGATIVE_PATTERN.matcher(pattern); + if (matcher.matches()) { + cfg.excludes.add("**/" + matcher.group(1)); + } + } + } + + private static boolean isUnderRoots(Set<VirtualFile> roots, VirtualFile file) { + for (VirtualFile f = file; f != null; f = f.getParent()) { + if (roots.contains(file)) { + return true; + } + } + + return false; + } + +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java index fd63fcfc816f..3f44d950ccbd 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.java @@ -22,6 +22,7 @@ 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.lexer.XmlLexer; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; @@ -48,6 +49,8 @@ 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.tree.IElementType; +import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.DisposeAwareRunnable; import com.intellij.util.Function; import com.intellij.util.SystemProperties; @@ -73,6 +76,7 @@ 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"; @@ -747,4 +751,40 @@ public class MavenUtil { public interface MavenTaskHandler { void waitFor(); } + + public static int crcWithoutSpaces(@NotNull VirtualFile xmlFile) throws IOException { + String text = VfsUtil.loadText(xmlFile); + + XmlLexer lexer = new XmlLexer(); + lexer.start(text); + + CRC32 crc = new CRC32(); + + boolean isCommentOrSpace = false; + + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) break; + + if (XmlTokenType.WHITESPACES.contains(tokenType) || XmlTokenType.COMMENTS.contains(tokenType) || tokenType == XmlTokenType.XML_REAL_WHITE_SPACE) { + if (!isCommentOrSpace) { + crc.update(1); + isCommentOrSpace = true; + } + } + else { + isCommentOrSpace = false; + + for (int start = lexer.getTokenStart(), end = lexer.getTokenEnd(); start < end; start++) { + char a = text.charAt(start); + crc.update(a); + crc.update(a >>> 8); + } + } + + lexer.advance(); + } + + return (int)crc.getValue(); + } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java index 8a4f802a7e88..c75a60418b6b 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenImportingTestCase.java @@ -50,10 +50,7 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.idea.maven.execution.*; import org.jetbrains.idea.maven.model.MavenArtifact; -import org.jetbrains.idea.maven.project.MavenArtifactDownloader; -import org.jetbrains.idea.maven.project.MavenProject; -import org.jetbrains.idea.maven.project.MavenProjectsManager; -import org.jetbrains.idea.maven.project.MavenProjectsTree; +import org.jetbrains.idea.maven.project.*; import javax.swing.*; import java.io.File; @@ -531,7 +528,8 @@ public abstract class MavenImportingTestCase extends MavenTestCase { modules.add(getModule(each)); } if (useJps()) { - MavenProjectsManager.getInstance(myProject).generateBuildConfiguration(false); + new MavenResourceCompilerConfigurationGenerator(myProject, MavenProjectsManager.getInstance(myProject).getProjectsTreeForTests()) + .generateBuildConfiguration(false); } } }); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java index bd3a718a7747..93cad4675fc4 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceCopyingTest.java @@ -17,13 +17,15 @@ package org.jetbrains.idea.maven.compiler; import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerConfigurationImpl; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.compiler.options.ExcludeEntryDescription; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.idea.maven.MavenImportingTestCase; -import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider; -import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; import java.io.File; @@ -426,38 +428,6 @@ public abstract class ResourceCopyingTest extends MavenImportingTestCase { assertCopied("target/classes/file.properties"); } - public void testWorkCorrectlyIfFoldersMarkedAsSource() throws Exception { - createProjectSubFile("src/main/resources/file.properties"); - createProjectSubFile("src/main/resources/file.txt"); - createProjectSubFile("src/main/resources/file.xxx"); - createProjectSubFile("src/main/ideaRes/file2.xxx"); - - importProject("<groupId>test</groupId>" + - "<artifactId>project</artifactId>" + - "<version>1</version>"); - - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom), - getModule("project"), - new MavenDefaultModifiableModelsProvider(myProject)); - adapter.addSourceFolder(myProjectRoot.findFileByRelativePath("src/main/resources").getPath(), false); - adapter.addSourceFolder(myProjectRoot.findFileByRelativePath("src/main/ideaRes").getPath(), false); - adapter.getRootModel().commit(); - } - }); - - - assertSources("project", "src/main/resources", "src/main/ideaRes"); - - compileModules("project"); - - assertCopied("target/classes/file.properties"); - assertCopied("target/classes/file.txt"); - assertCopied("target/classes/file.xxx"); - assertNotCopied("target/classes/file2.xxx"); - } - public void testDoNotDeleteFilesFromOtherModulesOutput() throws Exception { createProjectSubFile("m1/resources/file.xxx"); createProjectSubFile("m2/resources/file.yyy"); @@ -576,14 +546,16 @@ public abstract class ResourceCopyingTest extends MavenImportingTestCase { } private void setModulesOutput(final VirtualFile output, final String... moduleNames) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - for (String each : moduleNames) { - PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), false); - PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), true); - } + AccessToken accessToken = WriteAction.start(); + try { + for (String each : moduleNames) { + PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), false); + PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), true); } - }); + } + finally { + accessToken.finish(); + } } public void testWebResources() throws Exception { @@ -675,6 +647,47 @@ public abstract class ResourceCopyingTest extends MavenImportingTestCase { "</build>"); } + public void testCopingNonMavenResources() throws Exception { + if (ignore()) return; + + createProjectSubFile("src/resources/a.txt", "a"); + + VirtualFile configDir = createProjectSubDir("src/config"); + createProjectSubFile("src/config/b.txt", "b"); + createProjectSubFile("src/config/JavaClass.java", "class JavaClass {}"); + createProjectSubFile("src/config/xxx.xxx", "xxx"); // *.xxx is excluded from resource coping, see setUpInWriteAction() + + final VirtualFile excludedDir = createProjectSubDir("src/excluded"); + createProjectSubFile("src/excluded/c.txt", "c"); + + importProject("<groupId>test</groupId>" + + "<artifactId>project</artifactId>" + + "<version>1</version>"); + + Module module = ModuleManager.getInstance(myProject).findModuleByName("project"); + PsiTestUtil.addSourceRoot(module, configDir); + PsiTestUtil.addSourceRoot(module, excludedDir); + + new WriteCommandAction.Simple(myProject) { + @Override + protected void run() throws Throwable { + CompilerConfiguration.getInstance(myProject).getExcludedEntriesConfiguration() + .addExcludeEntryDescription(new ExcludeEntryDescription(excludedDir, true, false, getTestRootDisposable())); + + setModulesOutput(myProjectRoot.createChildDirectory(this, "output"), "project", "m1", "m2"); + } + }.execute().throwException(); + + compileModules("project"); + + assertCopied("output/a.txt"); + assertCopied("output/b.txt"); + + assertNotCopied("output/JavaClass.java"); + assertNotCopied("output/xxx.xxx"); + assertNotCopied("output/c.txt"); + } + private void assertCopied(String path) { if (useJps()) { assertTrue(new File(myProjectPom.getParent().getPath(), path).exists()); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java index a9f00d9ac5a5..4c2c7815e5ff 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java @@ -15,16 +15,12 @@ */ package org.jetbrains.idea.maven.compiler; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.idea.maven.MavenImportingTestCase; -import org.jetbrains.idea.maven.importing.MavenDefaultModifiableModelsProvider; -import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; import java.io.File; import java.io.IOException; @@ -306,50 +302,6 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase { assertResult("target/classes/file2.properties", "value=project"); } - public void testWorkCorrectlyIfFoldersMarkedAsSource() throws Exception { - createProjectSubFile("src/main/resources/file1.properties", "value=${project.artifactId}"); - createProjectSubFile("src/main/ideaRes/file2.properties", "value=${project.artifactId}"); - - importProject("<groupId>test</groupId>" + - "<artifactId>project</artifactId>" + - "<version>1</version>" + - - "<build>" + - " <resources>" + - " <resource>" + - " <directory>src/main/resources</directory>" + - " <filtering>true</filtering>" + - " </resource>" + - " </resources>" + - "</build>"); - - new WriteAction() { - protected void run(Result result) throws Throwable { - MavenRootModelAdapter adapter = new MavenRootModelAdapter(myProjectsTree.findProject(myProjectPom), - getModule("project"), - new MavenDefaultModifiableModelsProvider(myProject)); - adapter.addSourceFolder(myProjectRoot.findFileByRelativePath("src/main/resources").getPath(), false); - adapter.addSourceFolder(myProjectRoot.findFileByRelativePath("src/main/ideaRes").getPath(), false); - adapter.getRootModel().commit(); - } - }.execute(); - - assertSources("project", "src/main/resources", "src/main/ideaRes"); - - compileModules("project"); - - assertResult("target/classes/file1.properties", "value=project"); - if (useJps()) { - // in jps only maven resource builder works for mavenized modules, so the file should not be copied at all - File file = new File(myProjectPom.getParent().getPath(), "target/classes/file2.properties"); - assertFalse("The file should not be copied " + file.getPath(), file.exists()); - } - else { - assertResult("target/classes/file2.properties", "value=${project.artifactId}"); - } - } - - public void testEscapingWindowsChars() throws Exception { createProjectSubFile("resources/file.txt", "value=${foo}\n" + "value2=@foo@\n" + |