From ce3f80c7310dca02afa706264af7b0f9ba03553d Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Fri, 12 Feb 2010 15:21:36 +0300 Subject: [PATCH] maven dependency management gutter support (override icons) --- plugins/maven/maven.iml | 1 + .../maven/dom/MavenDomProjectProcessorUtils.java | 322 +++++++++++++++++++++ .../dom/annotator/MavenDomGutterAnnotator.java | 156 ++++++++++ .../generate/MavenCodeInsightGenerateAction.java | 2 +- .../dom/references/MavenPropertyPsiReference.java | 122 +------- .../idea/maven/project/MavenProjectsManager.java | 7 + .../idea/maven/project/MavenProjectsTree.java | 2 +- .../org/jetbrains/idea/maven/utils/MavenIcons.java | 3 + .../maven/src/main/resources/DomBundle.properties | 3 + .../maven/src/main/resources/META-INF/plugin.xml | 1 + .../main/resources/images/overridenDependency.png | Bin 0 -> 544 bytes .../main/resources/images/overridingDependency.png | Bin 0 -> 504 bytes 12 files changed, 507 insertions(+), 112 deletions(-) create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java create mode 100644 plugins/maven/src/main/resources/images/overridenDependency.png create mode 100644 plugins/maven/src/main/resources/images/overridingDependency.png diff --git a/plugins/maven/maven.iml b/plugins/maven/maven.iml index 8889960a8f..c23db08986 100644 --- a/plugins/maven/maven.iml +++ b/plugins/maven/maven.iml @@ -108,6 +108,7 @@ + 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 new file mode 100644 index 0000000000..1330d20832 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java @@ -0,0 +1,322 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.maven.dom; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.Function; +import com.intellij.util.Processor; +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.MavenDomUtil; +import org.jetbrains.idea.maven.dom.model.*; +import org.jetbrains.idea.maven.project.*; +import org.jetbrains.idea.maven.utils.MavenUtil; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Set; + +public class MavenDomProjectProcessorUtils { + private MavenDomProjectProcessorUtils() { + } + + @Nullable + public static XmlTag searchProperty(@NotNull final String propertyName, + @NotNull MavenDomProjectModel projectDom, + @NotNull final Project project) { + final XmlTag[] property = new XmlTag[]{null}; + + Processor searchProcessor = new Processor() { + public boolean process(MavenDomProperties mavenDomProperties) { + XmlTag propertiesTag = mavenDomProperties.getXmlTag(); + if (propertiesTag != null) { + for (XmlTag each : propertiesTag.getSubTags()) { + if (each.getName().equals(propertyName)) { + property[0] = each; + return true; + } + } + } + return false; + } + }; + + processProperties(projectDom, searchProcessor, project); + + return property[0]; + } + + @Nullable + public static Set collectProperties(@NotNull MavenDomProjectModel projectDom, @NotNull final Project project) { + final Set properties = new HashSet(); + + Processor collectProcessor = new Processor() { + public boolean process(MavenDomProperties mavenDomProperties) { + XmlTag propertiesTag = mavenDomProperties.getXmlTag(); + if (propertiesTag != null) { + properties.addAll(Arrays.asList(propertiesTag.getSubTags())); + } + return false; + } + }; + + processProperties(projectDom, collectProcessor, project); + + return properties; + } + + @NotNull + public static Set searchDependencyUsages(@NotNull final MavenDomDependency dependency, + @NotNull final Project project) { + final Set usages = new HashSet(); + + 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) { + Processor collectProcessor = new Processor() { + public boolean process(MavenDomProjectModel mavenDomProjectModel) { + for (MavenDomDependency domDependency : mavenDomProjectModel.getDependencies().getDependencies()) { + if (domDependency.equals(dependency)) continue; + if (artifactId.equals(domDependency.getArtifactId().getStringValue()) && + groupId.equals(domDependency.getGroupId().getStringValue())) { + usages.add(domDependency); + } + } + return false; + } + }; + + processProjectDependenciesRecursively(model, collectProcessor, project); + } + } + + return usages; + } + + private static void processProjectDependenciesRecursively(@Nullable MavenDomProjectModel model, + @NotNull Processor processor, + @NotNull Project project) { + if (model != null) { + if (processor.process(model)) return; + + MavenProject mavenProject = MavenDomUtil.findProject(model); + if (mavenProject != null) { + for (MavenProject childProject : MavenProjectsManager.getInstance(project).findInheritors(mavenProject)) { + MavenDomProjectModel childProjectModel = MavenDomUtil.getMavenDomProjectModel(project, childProject.getFile()); + + processProjectDependenciesRecursively(childProjectModel, processor, project); + } + } + } + } + + @Nullable + public static MavenDomDependency searchManagingDependency(@NotNull final MavenDomDependency dependency, @NotNull final Project project) { + final MavenDomDependency[] parent = new MavenDomDependency[]{null}; + + final String artifactId = dependency.getArtifactId().getStringValue(); + final String groupId = dependency.getGroupId().getStringValue(); + if (artifactId != null && groupId != null) { + MavenDomProjectModel model = dependency.getParentOfType(MavenDomProjectModel.class, false); + if (model != null) { + Processor processor = new Processor() { + public boolean process(MavenDomDependencies mavenDomDependencies) { + for (MavenDomDependency domDependency : mavenDomDependencies.getDependencies()) { + if (domDependency.equals(dependency)) continue; + if (artifactId.equals(domDependency.getArtifactId().getStringValue()) && + groupId.equals(domDependency.getGroupId().getStringValue())) { + parent[0] = domDependency; + return true; + } + } + return false; + } + }; + processDependenciesInDependencyManagement(model, processor, project); + } + } + + return parent[0]; + } + + + public static boolean processDependenciesInDependencyManagement(@NotNull MavenDomProjectModel projectDom, + @NotNull final Processor processor, + @NotNull final Project project) { + + Function domProfileFunction = new Function() { + public MavenDomDependencies fun(MavenDomProfile mavenDomProfile) { + return mavenDomProfile.getDependencyManagement().getDependencies(); + } + }; + Function projectDomFunction = new Function() { + public MavenDomDependencies fun(MavenDomProjectModel mavenDomProjectModel) { + return mavenDomProjectModel.getDependencyManagement().getDependencies(); + } + }; + + return process(projectDom, processor, project, domProfileFunction, projectDomFunction); + } + + public static boolean processProperties(@NotNull MavenDomProjectModel projectDom, + @NotNull final Processor processor, + @NotNull final Project project) { + + Function domProfileFunction = new Function() { + public MavenDomProperties fun(MavenDomProfile mavenDomProfile) { + return mavenDomProfile.getProperties(); + } + }; + Function projectDomFunction = new Function() { + public MavenDomProperties fun(MavenDomProjectModel mavenDomProjectModel) { + return mavenDomProjectModel.getProperties(); + } + }; + + return process(projectDom, processor, project, domProfileFunction, projectDomFunction); + } + + public static boolean process(@NotNull MavenDomProjectModel projectDom, + @NotNull final Processor processor, + @NotNull final Project project, + @NotNull final Function domProfileFunction, + @NotNull final Function projectDomFunction) { + + MavenProject mavenProjectOrNull = MavenDomUtil.findProject(projectDom); + + if (processSettingsXml(mavenProjectOrNull, processor, project, domProfileFunction)) return true; + if (processProject(projectDom, mavenProjectOrNull, processor, project, domProfileFunction, projectDomFunction)) return true; + + return processParentProjectFile(projectDom, processor, project, domProfileFunction, projectDomFunction); + } + + private static boolean processParentProjectFile(MavenDomProjectModel projectDom, + final Processor processor, + final Project project, + final Function domProfileFunction, + final Function projectDomFunction) { + Boolean aBoolean = new MyMavenParentProjectFileProcessor(project) { + protected Boolean doProcessParent(VirtualFile parentFile) { + MavenDomProjectModel parentProjectDom = MavenDomUtil.getMavenDomProjectModel(project, parentFile); + if (parentProjectDom == null) return false; + MavenProject parentMavenProject = MavenDomUtil.findProject(parentProjectDom); + + return processProject(parentProjectDom, parentMavenProject, processor, project, domProfileFunction, projectDomFunction); + } + }.process(projectDom); + + return aBoolean == null ? false : aBoolean.booleanValue(); + } + + private static boolean processSettingsXml(@Nullable MavenProject mavenProject, + @NotNull Processor processor, + @NotNull Project project, + Function domProfileFunction) { + MavenGeneralSettings settings = MavenProjectsManager.getInstance(project).getGeneralSettings(); + + for (VirtualFile each : settings.getEffectiveSettingsFiles()) { + MavenDomSettingsModel settingsDom = MavenDomUtil.getMavenDomModel(project, each, MavenDomSettingsModel.class); + if (settingsDom == null) continue; + + if (processProfiles(settingsDom.getProfiles(), mavenProject, processor, domProfileFunction)) return true; + } + return false; + } + + private static boolean processProject(MavenDomProjectModel projectDom, + MavenProject mavenProjectOrNull, + Processor processor, + Project project, + Function domProfileFunction, + Function projectDomFunction) { + + if (processProfilesXml(MavenDomUtil.getVirtualFile(projectDom), mavenProjectOrNull, processor, project, domProfileFunction)) { + return true; + } + + if (processProfiles(projectDom.getProfiles(), mavenProjectOrNull, processor, domProfileFunction)) return true; + + T t = projectDomFunction.fun(projectDom); + return t == null ? false : processor.process(t); + } + + private static boolean processProfilesXml(VirtualFile projectFile, + MavenProject mavenProjectOrNull, + Processor processor, + Project project, + Function f) { + VirtualFile profilesFile = MavenUtil.findProfilesXmlFile(projectFile); + if (profilesFile == null) return false; + + MavenDomProfiles profiles = MavenDomUtil.getMavenDomProfilesModel(project, profilesFile); + if (profiles == null) return false; + + return processProfiles(profiles, mavenProjectOrNull, processor, f); + } + + private static boolean processProfiles(MavenDomProfiles profilesDom, + MavenProject mavenProjectOrNull, + Processor processor, + Function f) { + Collection activePropfiles = mavenProjectOrNull == null ? null : mavenProjectOrNull.getActiveProfilesIds(); + for (MavenDomProfile each : profilesDom.getProfiles()) { + XmlTag idTag = each.getId().getXmlTag(); + if (idTag == null) continue; + if (activePropfiles != null && !activePropfiles.contains(idTag.getValue().getText())) continue; + + T t = f.fun(each); + if (t != null && processor.process(t)) return true; + } + return false; + } + + private abstract static class MyMavenParentProjectFileProcessor extends MavenParentProjectFileProcessor { + private final Project myProject; + + public MyMavenParentProjectFileProcessor(Project project) { + myProject = project; + } + + protected VirtualFile findManagedFile(@NotNull MavenId id) { + MavenProject project = MavenProjectsManager.getInstance(myProject).findProject(id); + return project == null ? null : project.getFile(); + } + + @Nullable + public Boolean process(@NotNull MavenDomProjectModel projectDom) { + MavenDomParent parent = projectDom.getMavenParent(); + MavenParentDesc parentDesc = null; + if (DomUtil.hasXml(parent)) { + String parentGroupId = parent.getGroupId().getStringValue(); + String parentArtifactId = parent.getArtifactId().getStringValue(); + String parentVersion = parent.getVersion().getStringValue(); + String parentRelativePath = parent.getRelativePath().getStringValue(); + if (StringUtil.isEmptyOrSpaces(parentRelativePath)) parentRelativePath = "../pom.xml"; + MavenId parentId = new MavenId(parentGroupId, parentArtifactId, parentVersion); + parentDesc = new MavenParentDesc(parentId, parentRelativePath); + } + + return process(MavenProjectsManager.getInstance(myProject).getGeneralSettings(), MavenDomUtil.getVirtualFile(projectDom), parentDesc); + } + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java new file mode 100644 index 0000000000..120bcbbfb5 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java @@ -0,0 +1,156 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.idea.maven.dom.annotator; + +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.ide.util.PsiElementListCellRenderer; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.NotNullFunction; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.dom.MavenDomBundle; +import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; +import org.jetbrains.idea.maven.dom.model.MavenDomDependency; +import org.jetbrains.idea.maven.dom.model.MavenDomDependencyManagement; +import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel; +import org.jetbrains.idea.maven.utils.MavenIcons; + +import javax.swing.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class MavenDomGutterAnnotator implements Annotator { + + private static final PsiElementListCellRenderer RENDERER = new PsiElementListCellRenderer() { + @Override + public String getElementText(XmlTag tag) { + DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag); + if (domElement != null) { + MavenDomProjectModel model = domElement.getParentOfType(MavenDomProjectModel.class, false); + if (model != null) { + String name = model.getName().getStringValue(); + if (!StringUtil.isEmptyOrSpaces(name)) { + return name; + } + } + } + + return tag.getContainingFile().getName(); + } + + @Override + protected String getContainerText(XmlTag element, String name) { + return null; + } + + @Override + protected Icon getIcon(PsiElement element) { + return MavenIcons.MAVEN_PROJECT_ICON; + } + + @Override + protected int getIconFlags() { + return 0; + } + }; + + private static final NotNullFunction> CONVERTER = + new NotNullFunction>() { + + @NotNull + public Collection fun(final MavenDomDependency pointer) { + return ContainerUtil.createMaybeSingletonList(pointer.getXmlTag()); + } + }; + + private static void annotateDependencyUsages(@NotNull MavenDomDependency dependency, AnnotationHolder holder) { + final XmlTag tag = dependency.getXmlTag(); + if (tag == null) return; + + final Set children = getDependencyUsages(dependency); + if (children.size() > 0) { + final NavigationGutterIconBuilder iconBuilder = + NavigationGutterIconBuilder.create(MavenIcons.OVERRIDEN_DEPENDENCY, CONVERTER); + iconBuilder. + setTargets(children). + setPopupTitle(MavenDomBundle.message("navigate.parent.dependency.title")). + setCellRenderer(RENDERER). + setTooltipText(MavenDomBundle.message("overriding.dependency.title")). + install(holder, dependency.getXmlTag()); + } + } + + + + private static void annotateManagedDependency(MavenDomDependency dependency, AnnotationHolder holder) { + final XmlTag tag = dependency.getXmlTag(); + if (tag == null) return; + + final List children = getManagingDependencies(dependency); + if (children.size() > 0) { + + final NavigationGutterIconBuilder iconBuilder = + NavigationGutterIconBuilder.create(MavenIcons.OVERRIDING_DEPENDENCY, CONVERTER); + iconBuilder. + setTargets(children). + setTooltipText(MavenDomBundle.message("overriden.dependency.title")). + install(holder, dependency.getXmlTag()); + } + } + + private static List getManagingDependencies(@NotNull MavenDomDependency dependency) { + Project project = dependency.getManager().getProject(); + MavenDomDependency parentDependency = MavenDomProjectProcessorUtils.searchManagingDependency(dependency, project); + + if (parentDependency != null) { + return Collections.singletonList(parentDependency); + } + return Collections.emptyList(); + } + + @NotNull + private static Set getDependencyUsages(@NotNull MavenDomDependency dependency) { + return MavenDomProjectProcessorUtils.searchDependencyUsages(dependency, dependency.getManager().getProject()); + } + + public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { + if (psiElement instanceof XmlTag) { + final DomElement element = DomManager.getDomManager(psiElement.getProject()).getDomElement((XmlTag)psiElement); + if (element instanceof MavenDomDependency) { + MavenDomDependency dependency = (MavenDomDependency)element; + if (isDependencyManagementSection(dependency)) { + annotateDependencyUsages(dependency, holder); + } else { + annotateManagedDependency(dependency, holder); + } + } + } + } + + private static boolean isDependencyManagementSection(@NotNull MavenDomDependency dependency) { + return dependency.getParentOfType(MavenDomDependencyManagement.class, false) != null; + } +} \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java index 26c7aaf787..731d627070 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/generate/MavenCodeInsightGenerateAction.java @@ -33,7 +33,7 @@ public class MavenCodeInsightGenerateAction extends GenerateDomElementAction { super(new MavenGenerateDomElementProvider(description, childElementClass, mappingId, parentFunction)); getTemplatePresentation().setIcon(ElementPresentationManager.getIconForClass(childElementClass)); - } + } public MavenCodeInsightGenerateAction(final GenerateDomElementProvider generateProvider) { super(generateProvider); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java index 3d5695e2d8..71234c65b9 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java @@ -28,8 +28,10 @@ import com.intellij.psi.xml.XmlDocument; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTagChild; +import com.intellij.util.Function; import com.intellij.util.Icons; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomUtil; import com.intellij.xml.XmlElementDescriptor; @@ -37,17 +39,16 @@ import com.intellij.xml.XmlNSDescriptor; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; import org.jetbrains.idea.maven.dom.MavenDomUtil; import org.jetbrains.idea.maven.dom.MavenSchemaProvider; import org.jetbrains.idea.maven.dom.model.*; import org.jetbrains.idea.maven.project.*; import org.jetbrains.idea.maven.utils.MavenIcons; -import org.jetbrains.idea.maven.utils.MavenUtil; import org.jetbrains.idea.maven.vfs.MavenPropertiesVirtualFileSystem; import javax.swing.*; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Set; @@ -100,13 +101,7 @@ public class MavenPropertyPsiReference extends MavenPsiReference { PsiElement result = resolveSystemPropety(); if (result != null) return result; - result = processProperties(myProjectDom, new PropertyProcessor() { - @Nullable - public PsiElement process(@NotNull XmlTag property) { - if (property.getName().equals(myText)) return property; - return null; - } - }); + result = MavenDomProjectProcessorUtils.searchProperty(myText, myProjectDom, myProject); if (result != null) return result; if (myText.startsWith("settings.")) { @@ -146,94 +141,6 @@ public class MavenPropertyPsiReference extends MavenPsiReference { } @Nullable - private T processProperties(@NotNull MavenDomProjectModel projectDom, final PropertyProcessor processor) { - T result; - MavenProject mavenProjectOrNull = MavenDomUtil.findProject(projectDom); - - result = processSettingsXmlProperties(mavenProjectOrNull, processor); - if (result != null) return result; - - result = processProjectProperties(projectDom, mavenProjectOrNull, processor); - if (result != null) return result; - - return new MyMavenParentProjectFileProcessor() { - protected T doProcessParent(VirtualFile parentFile) { - MavenDomProjectModel parentProjectDom = MavenDomUtil.getMavenDomProjectModel(myProject, parentFile); - if (parentProjectDom == null) return null; - MavenProject parentMavenProject = MavenDomUtil.findProject(parentProjectDom); - return processProjectProperties(parentProjectDom, parentMavenProject, processor); - } - }.process(projectDom); - } - - @Nullable - private T processSettingsXmlProperties(@Nullable MavenProject mavenProject, PropertyProcessor processor) { - MavenGeneralSettings settings = myProjectsManager.getGeneralSettings(); - T result; - - for (VirtualFile each : settings.getEffectiveSettingsFiles()) { - MavenDomSettingsModel settingsDom = MavenDomUtil.getMavenDomModel(myProject, each, MavenDomSettingsModel.class); - if (settingsDom == null) continue; - - result = processProfilesProperties(settingsDom.getProfiles(), mavenProject, processor); - if (result != null) return result; - } - return null; - } - - @Nullable - private T processProjectProperties(MavenDomProjectModel projectDom, - MavenProject mavenProjectOrNull, - PropertyProcessor processor) { - T result; - - result = processProfilesXmlProperties(MavenDomUtil.getVirtualFile(projectDom), mavenProjectOrNull, processor); - if (result != null) return result; - - result = processProfilesProperties(projectDom.getProfiles(), mavenProjectOrNull, processor); - if (result != null) return result; - - return processProperties(projectDom.getProperties(), processor); - } - - @Nullable - private T processProfilesXmlProperties(VirtualFile projectFile, MavenProject mavenProjectOrNull, PropertyProcessor processor) { - VirtualFile profilesFile = MavenUtil.findProfilesXmlFile(projectFile); - if (profilesFile == null) return null; - - MavenDomProfiles profiles = MavenDomUtil.getMavenDomProfilesModel(myProject, profilesFile); - if (profiles == null) return null; - - return processProfilesProperties(profiles, mavenProjectOrNull, processor); - } - - @Nullable - private T processProfilesProperties(MavenDomProfiles profilesDom, MavenProject mavenProjectOrNull, PropertyProcessor processor) { - Collection activePropfiles = mavenProjectOrNull == null ? null : mavenProjectOrNull.getActiveProfilesIds(); - for (MavenDomProfile each : profilesDom.getProfiles()) { - XmlTag idTag = each.getId().getXmlTag(); - if (idTag == null) continue; - if (activePropfiles != null && !activePropfiles.contains(idTag.getValue().getText())) continue; - - T result = processProperties(each.getProperties(), processor); - if (result != null) return result; - } - return null; - } - - @Nullable - private T processProperties(MavenDomProperties propertiesDom, PropertyProcessor processor) { - XmlTag propertiesTag = propertiesDom.getXmlTag(); - if (propertiesTag != null) { - for (XmlTag each : propertiesTag.getSubTags()) { - T result = processor.process(each); - if (result != null) return result; - } - } - return null; - } - - @Nullable private PsiElement resolveSettingsModelProperty() { if (!schemaHasProperty(MavenSchemaProvider.MAVEN_SETTINGS_SCHEMA_URL, myText)) return null; @@ -332,12 +239,12 @@ public class MavenPropertyPsiReference extends MavenPsiReference { } private void collectPropertiesVariants(final List result) { - processProperties(myProjectDom, new PropertyProcessor() { - public Object process(@NotNull XmlTag property) { - result.add(createLookupElement(property, property.getName())); - return null; + Set properties = MavenDomProjectProcessorUtils.collectProperties(myProjectDom, myProject); + result.addAll(ContainerUtil.map(properties, new Function() { + public LookupElement fun(XmlTag xmlTag) { + return createLookupElement(xmlTag, xmlTag.getName()); } - }); + })) ; } private void collectSystemEnvProperties(String propertiesFileName, String prefix, List result) { @@ -376,7 +283,7 @@ public class MavenPropertyPsiReference extends MavenPsiReference { return doProcessSchema(descriptors, null, processor, new THashSet()); } - private T doProcessSchema(XmlElementDescriptor[] descriptors, + private static T doProcessSchema(XmlElementDescriptor[] descriptors, String prefix, SchemaProcessor processor, Set recursionGuard) { @@ -403,7 +310,7 @@ public class MavenPropertyPsiReference extends MavenPsiReference { return null; } - private boolean isCollection(XmlElementDescriptor each) { + private static boolean isCollection(XmlElementDescriptor each) { XmlTag declaration = (XmlTag)each.getDeclaration(); if (declaration != null) { XmlTag complexType = declaration.findFirstSubTag("xs:complexType"); @@ -419,17 +326,12 @@ public class MavenPropertyPsiReference extends MavenPsiReference { return mySoft; } - private interface PropertyProcessor { - @Nullable - T process(@NotNull XmlTag property); - } - private interface SchemaProcessor { @Nullable T process(@NotNull String property, XmlElementDescriptor descriptor); } - private class CollectingSchemaProcessor implements SchemaProcessor { + private static class CollectingSchemaProcessor implements SchemaProcessor { private final List myResult; public CollectingSchemaProcessor(List result) { 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 aae43998a2..1a704e7b35 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 @@ -43,6 +43,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.update.Update; import gnu.trove.THashMap; import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.idea.maven.dom.MavenDomUtil; @@ -546,6 +547,12 @@ public class MavenProjectsManager extends SimpleProjectComponent implements Pers return ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(project.getFile()); } + @NotNull + public Set findInheritors(@Nullable MavenProject parent) { + if (parent == null || !isInitialized()) return Collections.emptySet(); + return myProjectsTree.findInheritors(parent); + } + public MavenProject findContainingProject(VirtualFile file) { if (!isInitialized()) return null; Module module = ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(file); 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 b73d15adb1..50f9d6a425 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 @@ -960,7 +960,7 @@ public class MavenProjectsTree { return findProject(project.getParentId()); } - private Set findInheritors(MavenProject project) { + public Set findInheritors(MavenProject project) { Set result = new THashSet(); MavenId id = project.getMavenId(); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenIcons.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenIcons.java index ebb3782152..ee7ef71b30 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenIcons.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenIcons.java @@ -37,4 +37,7 @@ public class MavenIcons { public static final Icon DEPENDENCY_ICON = IconLoader.getIcon("/nodes/ppLib.png"); public static final Icon OPEN_MODULES_ICON = IconLoader.getIcon("/images/modulesOpen.png"); public static final Icon CLOSED_MODULES_ICON = IconLoader.getIcon("/images/modulesClosed.png"); + + public static final Icon OVERRIDING_DEPENDENCY = IconLoader.getIcon("/images/overridingDependency.png"); + public static final Icon OVERRIDEN_DEPENDENCY = IconLoader.getIcon("/images/overridenDependency.png"); } diff --git a/plugins/maven/src/main/resources/DomBundle.properties b/plugins/maven/src/main/resources/DomBundle.properties index 7c13e9ff6c..3a284cc5c0 100644 --- a/plugins/maven/src/main/resources/DomBundle.properties +++ b/plugins/maven/src/main/resources/DomBundle.properties @@ -16,3 +16,6 @@ generate.dependency.group=Dependency (group) generate.plugin.artifact=Plugin (artifact) generate.plugin.group=Plugin (group) +overriden.dependency.title=Navigate to managing dependency +overriding.dependency.title=Navigate to dependency usages +navigate.parent.dependency.title=Choose dependency to navigate diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 4b03ff0157..2113cd31ed 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -88,6 +88,7 @@ + diff --git a/plugins/maven/src/main/resources/images/overridenDependency.png b/plugins/maven/src/main/resources/images/overridenDependency.png new file mode 100644 index 0000000000000000000000000000000000000000..62d6b64bbf990af081c05c97ff00e228be13a241 GIT binary patch literal 544 zcwPY@0^j|KP)^@$UJfJ=b6Sj7V$fXDG@o1S@jL z?PvJ;<0k{iQy?_}0R&d~`tjYFhYuZbRxz*sH>+psrAfJQO00a;ta_~s2 z>Spr@ia5Y*0T}=b9)JLXD}4Fv4nysXH~;?&Ycu@(_LkxG!+Q*~DkK;|a#0SF+lLWjuB{~53V=cEf@@mu?}7y$wZ z96Se>`+}|bFKP`m?I{BzBO`;Pjt2uoQ50AXAb{X*gqaLd3tgW^em0AhssT3X-NK~z>bT}V>S<@c{2|KB{mx8u{>m-C)p+0SF+luR$ioLj z=M*xulom2@ak4WQI0ne@35zFz)Bpq!*hI&a-q#mj{r~R}QtJo^9NDzM;x z?f(D&ZQ@#Afz$v55Ih_|erI6#2XyY+Zww5tzCqZ({vtdB5I|sGzkB{@&-E8SBhniB z8H#cX!HOJm`x$=z_{jkB6i5v~0D%?0etdW4;X_B9RSaxIo%8y^CV>>)I=tZt$mbw6 u00D#&JkqMV**t