IDEA-64302 maven: insert..dependency: better support for managed versions

This commit is contained in:
Sergey Evdokimov
2013-08-01 19:28:13 +04:00
parent 08b98ed6d0
commit e72512df55
4 changed files with 123 additions and 31 deletions

View File

@@ -20,6 +20,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
@@ -27,9 +28,9 @@ import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.ui.actions.generate.GenerateDomElementAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.DependencyConflictId;
import org.jetbrains.idea.maven.dom.MavenDomBundle;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.model.MavenDomDependencies;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomDependencyManagement;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
@@ -37,6 +38,7 @@ import org.jetbrains.idea.maven.indices.MavenArtifactSearchDialog;
import org.jetbrains.idea.maven.model.MavenId;
import java.util.List;
import java.util.Map;
public class GenerateDependencyAction extends GenerateDomElementAction {
public GenerateDependencyAction() {
@@ -46,7 +48,9 @@ public class GenerateDependencyAction extends GenerateDomElementAction {
protected MavenDomDependency doGenerate(@NotNull final MavenDomProjectModel mavenModel, final Editor editor) {
Project project = mavenModel.getManager().getProject();
final List<MavenId> ids = MavenArtifactSearchDialog.searchForArtifact(project);
final Map<DependencyConflictId, MavenDomDependency> managedDependencies = GenerateManagedDependencyAction.collectManagingDependencies(mavenModel);
final List<MavenId> ids = MavenArtifactSearchDialog.searchForArtifact(project, managedDependencies.values());
if (ids.isEmpty()) return null;
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -55,19 +59,39 @@ public class GenerateDependencyAction extends GenerateDomElementAction {
return new WriteCommandAction<MavenDomDependency>(psiFile.getProject(), "Generate Dependency", psiFile) {
@Override
protected void run(Result<MavenDomDependency> result) throws Throwable {
MavenDomDependencies deps;
boolean isInsideManagedDependencies;
MavenDomDependencyManagement dependencyManagement = mavenModel.getDependencyManagement();
XmlElement managetDependencyXml = dependencyManagement.getXmlElement();
if (managetDependencyXml != null && managetDependencyXml.getTextRange().contains(editor.getCaretModel().getOffset())) {
deps = dependencyManagement.getDependencies();
XmlElement managedDependencyXml = dependencyManagement.getXmlElement();
if (managedDependencyXml != null && managedDependencyXml.getTextRange().contains(editor.getCaretModel().getOffset())) {
isInsideManagedDependencies = true;
}
else {
deps = mavenModel.getDependencies();
isInsideManagedDependencies = false;
}
for (MavenId each : ids) {
result.setResult(MavenDomUtil.createDomDependency(deps, editor, each));
MavenDomDependency res;
if (isInsideManagedDependencies) {
res = MavenDomUtil.createDomDependency(dependencyManagement.getDependencies(), editor, each);
}
else {
DependencyConflictId conflictId = new DependencyConflictId(each.getGroupId(), each.getArtifactId(), null, null);
MavenDomDependency managedDependenciesDom = managedDependencies.get(conflictId);
if (managedDependenciesDom != null
&& Comparing.equal(each.getVersion(), managedDependenciesDom.getVersion().getStringValue())) {
// Generate dependency without <version> tag
res = MavenDomUtil.createDomDependency(mavenModel.getDependencies(), editor);
res.getGroupId().setStringValue(conflictId.getGroupId());
res.getArtifactId().setStringValue(conflictId.getArtifactId());
}
else {
res = MavenDomUtil.createDomDependency(mavenModel.getDependencies(), editor, each);
}
}
result.setResult(res);
}
}
}.execute().getResultObject();

View File

@@ -15,6 +15,8 @@
*/
package org.jetbrains.idea.maven.dom.generate;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
@@ -32,7 +34,6 @@ import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -54,10 +55,14 @@ public class GenerateManagedDependencyAction extends GenerateDomElementAction {
@Override
protected MavenDomDependency doGenerate(@NotNull final MavenDomProjectModel mavenModel, final Editor editor) {
Collection<MavenDomDependency> managingDependencies = collectManagingDependencies(mavenModel);
Set<DependencyConflictId> existingDependencies = collectExistingDependencies(mavenModel);
Map<DependencyConflictId, MavenDomDependency> managingDependencies = collectManagingDependencies(mavenModel);
Map<DependencyConflictId, MavenDomDependency> unexistManagingDeps = Maps.filterKeys(managingDependencies,
Predicates.not(Predicates.in(existingDependencies)));
final List<MavenDomDependency> dependenciesToOverride =
GenerateDependencyUtil.chooseDependencies(managingDependencies, mavenModel.getManager().getProject());
GenerateDependencyUtil.chooseDependencies(unexistManagingDeps.values(), mavenModel.getManager().getProject());
if (!dependenciesToOverride.isEmpty()) {
return new WriteCommandAction<MavenDomDependency>(editor.getProject(), mavenModel.getXmlTag().getContainingFile()) {
@@ -88,10 +93,7 @@ public class GenerateManagedDependencyAction extends GenerateDomElementAction {
}
}
@NotNull
public static Collection<MavenDomDependency> collectManagingDependencies(@NotNull final MavenDomProjectModel model) {
final Map<DependencyConflictId, MavenDomDependency> dependencies = new HashMap<DependencyConflictId, MavenDomDependency>();
private static Set<DependencyConflictId> collectExistingDependencies(@NotNull final MavenDomProjectModel model) {
final Set<DependencyConflictId> existingDependencies = new HashSet<DependencyConflictId>();
for (MavenDomDependency dependency : model.getDependencies().getDependencies()) {
DependencyConflictId id = DependencyConflictId.create(dependency);
@@ -100,20 +102,26 @@ public class GenerateManagedDependencyAction extends GenerateDomElementAction {
}
}
return existingDependencies;
}
@NotNull
public static Map<DependencyConflictId, MavenDomDependency> collectManagingDependencies(@NotNull final MavenDomProjectModel model) {
final Map<DependencyConflictId, MavenDomDependency> dependencies = new HashMap<DependencyConflictId, MavenDomDependency>();
Processor<MavenDomDependency> collectProcessor = new Processor<MavenDomDependency>() {
public boolean process(MavenDomDependency dependency) {
if (!model.equals(dependency.getParentOfType(MavenDomProjectModel.class, true))) {
DependencyConflictId id = DependencyConflictId.create(dependency);
if (id != null && !existingDependencies.contains(id) && !dependencies.containsKey(id)) {
dependencies.put(id, dependency);
}
DependencyConflictId id = DependencyConflictId.create(dependency);
if (id != null && !dependencies.containsKey(id)) {
dependencies.put(id, dependency);
}
return false;
}
};
MavenDomProjectProcessorUtils.processDependenciesInDependencyManagement(model, collectProcessor, model.getManager().getProject());
return dependencies.values();
return dependencies;
}
}

View File

@@ -17,18 +17,20 @@ package org.jetbrains.idea.maven.indices;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.TabbedPaneWrapper;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.model.MavenId;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.Collections;
import java.util.*;
import java.util.List;
import java.util.Map;
public class MavenArtifactSearchDialog extends DialogWrapper {
private List<MavenId> myResult = Collections.emptyList();
@@ -37,6 +39,8 @@ public class MavenArtifactSearchDialog extends DialogWrapper {
private MavenArtifactSearchPanel myArtifactsPanel;
private MavenArtifactSearchPanel myClassesPanel;
private final Map<Pair<String, String>, String> myManagedDependenciesMap = new HashMap<Pair<String, String>, String>();
private final Map<MavenArtifactSearchPanel, Boolean> myOkButtonStates = new THashMap<MavenArtifactSearchPanel, Boolean>();
@NotNull
@@ -49,14 +53,30 @@ public class MavenArtifactSearchDialog extends DialogWrapper {
}
@NotNull
public static List<MavenId> searchForArtifact(Project project) {
public static List<MavenId> searchForArtifact(Project project, Collection<MavenDomDependency> managedDependencies) {
MavenArtifactSearchDialog d = new MavenArtifactSearchDialog(project, "", false);
d.setManagedDependencies(managedDependencies);
d.show();
if (!d.isOK()) return Collections.emptyList();
return d.getResult();
}
public void setManagedDependencies(Collection<MavenDomDependency> managedDependencies) {
myManagedDependenciesMap.clear();
for (MavenDomDependency dependency : managedDependencies) {
String groupId = dependency.getGroupId().getStringValue();
String artifactId = dependency.getArtifactId().getStringValue();
String version = dependency.getVersion().getStringValue();
if (StringUtil.isNotEmpty(groupId) && StringUtil.isNotEmpty(artifactId) && StringUtil.isNotEmpty(version)) {
myManagedDependenciesMap.put(Pair.create(groupId, artifactId), version);
}
}
}
private MavenArtifactSearchDialog(Project project, String initialText, boolean classMode) {
super(project, true);
@@ -84,8 +104,8 @@ public class MavenArtifactSearchDialog extends DialogWrapper {
}
};
myArtifactsPanel = new MavenArtifactSearchPanel(project, !classMode ? initialText : "", false, listener, this);
myClassesPanel = new MavenArtifactSearchPanel(project, classMode ? initialText : "", true, listener, this);
myArtifactsPanel = new MavenArtifactSearchPanel(project, !classMode ? initialText : "", false, listener, this, myManagedDependenciesMap);
myClassesPanel = new MavenArtifactSearchPanel(project, classMode ? initialText : "", true, listener, this, myManagedDependenciesMap);
myTabbedPane.addTab("Search for artifact", myArtifactsPanel);
myTabbedPane.addTab("Search for class", myClassesPanel);

View File

@@ -19,6 +19,8 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.*;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
@@ -41,7 +43,7 @@ import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.*;
import java.util.List;
public class MavenArtifactSearchPanel extends JPanel {
@@ -55,15 +57,18 @@ public class MavenArtifactSearchPanel extends JPanel {
private final Alarm myAlarm;
private final Map<Pair<String, String>, String> myManagedDependenciesMap;
public MavenArtifactSearchPanel(Project project,
String initialText,
boolean classMode,
Listener listener,
MavenArtifactSearchDialog dialog) {
MavenArtifactSearchDialog dialog, Map<Pair<String, String>, String> managedDependenciesMap) {
myProject = project;
myDialog = dialog;
myClassMode = classMode;
myListener = listener;
myManagedDependenciesMap = managedDependenciesMap;
initComponents(initialText);
myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, dialog.getDisposable());
@@ -183,9 +188,34 @@ public class MavenArtifactSearchPanel extends JPanel {
}, 500);
}
private void resortUsingDependencyVersionMap(List<MavenArtifactSearchResult> result) {
for (MavenArtifactSearchResult searchResult : result) {
if (searchResult.versions.isEmpty()) continue;
MavenArtifactInfo artifactInfo = searchResult.versions.get(0);
final String managedVersion = myManagedDependenciesMap.get(Pair.create(artifactInfo.getGroupId(), artifactInfo.getArtifactId()));
if (managedVersion != null) {
Collections.sort(searchResult.versions, new Comparator<MavenArtifactInfo>() {
@Override
public int compare(MavenArtifactInfo o1, MavenArtifactInfo o2) {
String v1 = o1.getVersion();
String v2 = o2.getVersion();
if (Comparing.equal(v1, v2)) return 0;
if (managedVersion.equals(v1)) return -1;
if (managedVersion.equals(v2)) return 1;
return 0;
}
});
}
}
}
private void doSearch(String searchText) {
MavenSearcher searcher = myClassMode ? new MavenClassSearcher() : new MavenArtifactSearcher();
List<MavenArtifactSearchResult> result = searcher.search(myProject, searchText, 200);
resortUsingDependencyVersionMap(result);
final TreeModel model = new MyTreeModel(result);
SwingUtilities.invokeLater(new Runnable() {
@@ -273,7 +303,7 @@ public class MavenArtifactSearchPanel extends JPanel {
}
}
private static class MyArtifactCellRenderer extends JPanel implements TreeCellRenderer {
private class MyArtifactCellRenderer extends JPanel implements TreeCellRenderer {
protected SimpleColoredComponent myLeftComponent = new SimpleColoredComponent();
protected SimpleColoredComponent myRightComponent = new SimpleColoredComponent();
@@ -350,7 +380,17 @@ public class MavenArtifactSearchPanel extends JPanel {
}
else if (value instanceof MavenArtifactInfo) {
MavenArtifactInfo info = (MavenArtifactInfo)value;
myLeftComponent.append(info.getVersion(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
String version = info.getVersion();
String managedVersion = myManagedDependenciesMap.get(Pair.create(info.getGroupId(), info.getArtifactId()));
if (managedVersion != null && managedVersion.equals(version)) {
myLeftComponent.append(version, SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
myLeftComponent.append(" (from <dependencyManagement>)", SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
else {
myLeftComponent.append(version, SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
return this;
@@ -373,7 +413,7 @@ public class MavenArtifactSearchPanel extends JPanel {
}
}
private static class MyClassCellRenderer extends MyArtifactCellRenderer {
private class MyClassCellRenderer extends MyArtifactCellRenderer {
private MyClassCellRenderer(Tree tree) {
super(tree);