diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipant.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipant.java index 51415692..a32ef7ac 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipant.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019-2022 Red Hat Inc. and others. + * Copyright (c) 2019-2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -433,6 +433,7 @@ private GAVInsertionStrategy computeGAVInsertionStrategy(ICompletionRequest requ }; } + @SuppressWarnings("deprecation") private Optional computeFilesystemParent(ICompletionRequest request) { Optional relativePath = null; if (request.getParentElement().getLocalName().equals(PARENT_ELT)) { @@ -480,7 +481,7 @@ private CompletionItem createMinimalPOMCompletionSnippet(ICompletionRequest requ private Collection collectGoals(ICompletionRequest request) { PluginDescriptor pluginDescriptor; try { - pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request, plugin); + pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request.getNode(), plugin); return collectSimpleCompletionItems(pluginDescriptor.getMojos(), MojoDescriptor::getGoal, MojoDescriptor::getDescription, request); } catch (PluginResolutionException | PluginDescriptorParsingException | InvalidPluginDescriptorException e) { @@ -495,7 +496,7 @@ private CompletionItem toGAVCompletionItem(ArtifactWithDescription artifactInfo, || DOMUtils.findChildElementText(request.getParentElement(), GROUP_ID_ELT).isPresent(); boolean insertArtifactIsEnd = !request.getParentElement().hasEndTag(); boolean insertGroupId = strategy instanceof GAVInsertionStrategy.NodeWithChildrenInsertionStrategy || !hasGroupIdSet; - boolean isExclusion = DOMUtils.findClosestParentNode(request, DOMConstants.EXCLUSIONS_ELT) != null; + boolean isExclusion = DOMUtils.findClosestParentNode(request.getNode(), DOMConstants.EXCLUSIONS_ELT) != null; boolean insertVersion = !isExclusion && (strategy instanceof GAVInsertionStrategy.NodeWithChildrenInsertionStrategy || !DOMUtils .findChildElementText(request.getParentElement().getParentElement(), VERSION_ELT).isPresent()); CompletionItem item = new CompletionItem(); @@ -725,6 +726,7 @@ private void internalCollectRemoteGAVCompletion(ICompletionRequest request, bool }); } + @SuppressWarnings("deprecation") private Collection collectSubModuleCompletion(ICompletionRequest request) { DOMDocument doc = request.getXMLDocument(); File docFolder = new File(URI.create(doc.getTextDocument().getUri())).getParentFile(); @@ -763,6 +765,7 @@ private Collection collectMojoParametersDefaultCompletion(ICompl .collect(Collectors.toList()); } + @SuppressWarnings("deprecation") private Collection collectRelativePathCompletion(ICompletionRequest request) { DOMDocument doc = request.getXMLDocument(); File docFile = new File(URI.create(doc.getTextDocument().getUri())); diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipant.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipant.java index 2895e226..424e5528 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipant.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020-2022 Red Hat Inc. and others. + * Copyright (c) 2020-2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -23,10 +23,6 @@ import org.apache.maven.Maven; import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.InvalidPluginDescriptorException; -import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginResolutionException; -import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; import org.eclipse.aether.artifact.Artifact; import org.eclipse.lemminx.dom.DOMDocument; @@ -34,7 +30,6 @@ import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; -import org.eclipse.lemminx.extensions.maven.utils.MavenPluginUtils; import org.eclipse.lemminx.extensions.maven.utils.ParticipantUtils; import org.eclipse.lemminx.services.extensions.IDefinitionParticipant; import org.eclipse.lemminx.services.extensions.IDefinitionRequest; @@ -52,6 +47,7 @@ public MavenDefinitionParticipant(MavenLemminxExtension plugin) { this.plugin = plugin; } + @SuppressWarnings("deprecation") @Override public void findDefinition(IDefinitionRequest request, List locations, CancelChecker cancelChecker) { if (!MavenLemminxExtension.match(request.getXMLDocument())) { @@ -67,7 +63,11 @@ public void findDefinition(IDefinitionRequest request, List locati } DOMElement element = ParticipantUtils.findInterestingElement(request.getNode()); - if (element != null && MODULE_ELT.equals(element.getLocalName())) { + if (element == null) { + return; + } + + if (MODULE_ELT.equals(element.getLocalName())) { File subModuleFile = new File(currentFolder, element.getFirstChild().getTextContent() + File.separator + Maven.POMv4); if (subModuleFile.isFile()) { @@ -77,9 +77,9 @@ public void findDefinition(IDefinitionRequest request, List locati } MavenProject p = plugin.getProjectCache().getLastSuccessfulMavenProject(element.getOwnerDocument()); - Dependency dependency = ParticipantUtils.getArtifactToSearch(p, request); + Dependency dependency = ParticipantUtils.getArtifactToSearch(p, request.getNode()); - DOMNode parentNode = DOMUtils.findClosestParentNode(request, PARENT_ELT); + DOMNode parentNode = DOMUtils.findClosestParentNode(request.getNode(), PARENT_ELT); if (parentNode != null && parentNode.isElement()) { // Find in workspace if (ParticipantUtils.isWellDefinedDependency(dependency)) { @@ -118,37 +118,9 @@ public void findDefinition(IDefinitionRequest request, List locati } } } - if (dependency != null && element != null) { - if (!ParticipantUtils.isWellDefinedDependency(dependency)) { - if (ParticipantUtils.isPlugin(element)) { - try { - PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request, plugin); - if (pluginDescriptor != null) { - dependency.setGroupId(pluginDescriptor.getGroupId()); - dependency.setArtifactId(pluginDescriptor.getArtifactId()); - dependency.setVersion(pluginDescriptor.getVersion()); - } - } catch (PluginResolutionException | PluginDescriptorParsingException - | InvalidPluginDescriptorException e) { - // Ignore - } - } else if (ParticipantUtils.isDependency(element)) { - if (dependency.getGroupId() == null || dependency.getVersion() == null) { - if (p != null) { - final Dependency originalDependency = dependency; - dependency = p.getDependencies().stream() - .filter(dep -> (originalDependency.getGroupId() == null - || originalDependency.getGroupId().equals(dep.getGroupId()) - && (originalDependency.getArtifactId() == null - || originalDependency.getArtifactId().equals(dep.getArtifactId())) - && (originalDependency.getVersion() == null - || originalDependency.getVersion().equals(dep.getVersion())))) - .findFirst().orElse(dependency); - } - } - } - } + dependency = ParticipantUtils.resolveDependency(p, dependency, element, plugin); + if (dependency != null) { // Find in workspace if (ParticipantUtils.isWellDefinedDependency(dependency)) { Artifact artifact = ParticipantUtils.findWorkspaceArtifact(plugin, request, dependency); @@ -158,6 +130,7 @@ public void findDefinition(IDefinitionRequest request, List locati } } + // Find in local repository File localArtifactLocation = plugin.getLocalRepositorySearcher().findLocalFile(dependency); if (localArtifactLocation != null && localArtifactLocation.isFile()) { locations.add(toLocationNoRange(localArtifactLocation, element)); diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/PluginValidator.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/PluginValidator.java index ed77ade4..a9780276 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/PluginValidator.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/PluginValidator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019-2020 Red Hat Inc. and others. + * Copyright (c) 2019-2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -42,13 +42,13 @@ public PluginValidator(MavenLemminxExtension plugin) { public Optional> validatePluginResolution(DiagnosticRequest diagnosticRequest) { try { - MavenPluginUtils.getContainingPluginDescriptor(diagnosticRequest, plugin); + MavenPluginUtils.getContainingPluginDescriptor(diagnosticRequest.getNode(), plugin); } catch (PluginResolutionException | PluginDescriptorParsingException | InvalidPluginDescriptorException e) { LOGGER.log(Level.WARNING, "Could not resolve plugin description", e); // Add artifactId diagnostic String errorMessage = e.getMessage(); - DOMNode pluginNode = DOMUtils.findClosestParentNode(diagnosticRequest, "plugin"); + DOMNode pluginNode = DOMUtils.findClosestParentNode(diagnosticRequest.getNode(), "plugin"); Optional artifactNode = pluginNode.getChildren().stream().filter(node -> !node.isComment()) .filter(node -> node.getLocalName().equals("artifactId")).findAny(); List diagnostics = new ArrayList<>(); @@ -113,7 +113,7 @@ public Optional> validateGoal(DiagnosticRequest diagnosticReque if (node.isElement() && node.hasChildNodes()) { PluginDescriptor pluginDescriptor; try { - pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(diagnosticRequest, plugin); + pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(diagnosticRequest.getNode(), plugin); if (pluginDescriptor != null) { internalValidateGoal(diagnosticRequest, pluginDescriptor).ifPresent(diagnostics::add);; } diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipant.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipant.java index e5a273cb..c6c89f36 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipant.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020-2022 Red Hat Inc. and others. + * Copyright (c) 2020-2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -20,7 +20,6 @@ import java.io.File; import java.text.MessageFormat; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -31,7 +30,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; -import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.model.Dependency; import org.apache.maven.model.InputLocation; import org.apache.maven.model.InputSource; @@ -111,7 +109,7 @@ public Hover onText(IHoverRequest request) throws Exception { } MavenProject p = plugin.getProjectCache().getLastSuccessfulMavenProject(request.getXMLDocument()); - Dependency artifactToSearch = ParticipantUtils.getArtifactToSearch(p, request); + Dependency artifactToSearch = ParticipantUtils.getArtifactToSearch(p, tag); return switch (parent.getLocalName()) { case GROUP_ID_ELT, ARTIFACT_ID_ELT, VERSION_ELT -> { @@ -184,7 +182,7 @@ private String getManagedVersionText(IHoverRequest request) { boolean isPlugin = PLUGIN_ELT.equals(element.getLocalName()); MavenProject p = plugin.getProjectCache().getLastSuccessfulMavenProject(element.getOwnerDocument()); - Dependency dependency = ParticipantUtils.getArtifactToSearch(p, request); + Dependency dependency = ParticipantUtils.getArtifactToSearch(p, request.getNode()); // Search for DEPENDENCY/PLUGIN through the parents pom's File parentPomFile = getParentPomFile(p); @@ -302,50 +300,45 @@ private Hover collectArtifactDescription(IHoverRequest request) { boolean supportsMarkdown = request.canSupportMarkupKind(MarkupKind.MARKDOWN); MavenProject p = plugin.getProjectCache().getLastSuccessfulMavenProject(request.getXMLDocument()); - Dependency artifactToSearch = ParticipantUtils.getArtifactToSearch(p, request); - boolean wellDefined = ParticipantUtils.isWellDefinedDependency(artifactToSearch); + Dependency dependency = ParticipantUtils.getArtifactToSearch(p, request.getNode()); + boolean wellDefined = ParticipantUtils.isWellDefinedDependency(dependency); + DOMElement element = ParticipantUtils.findInterestingElement(request.getNode()); + dependency = ParticipantUtils.resolveDependency(p, dependency, element, plugin); + try { ModelBuilder builder = plugin.getProjectCache().getPlexusContainer().lookup(ModelBuilder.class); - Optional localDescription = plugin.getLocalRepositorySearcher() - .getLocalArtifactsLastVersion().stream() - .filter(gav -> (artifactToSearch.getGroupId() == null - || artifactToSearch.getGroupId().equals(gav.getGroupId())) - && (artifactToSearch.getArtifactId() == null - || artifactToSearch.getArtifactId().equals(gav.getArtifactId())) - && (artifactToSearch.getVersion() == null - || artifactToSearch.getVersion().equals(gav.getVersion()))) - .sorted(Comparator.comparing((Artifact artifact) -> new DefaultArtifactVersion(artifact.getVersion())).reversed()) - .findFirst().map(plugin.getLocalRepositorySearcher()::findLocalFile).map(file -> - builder.buildRawModel(file, ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL, true).get()) - .map(model -> { - UnaryOperator toBold = supportsMarkdown ? MarkdownUtils::toBold - : UnaryOperator.identity(); - String lineBreak = MarkdownUtils.getLineBreak(supportsMarkdown); - String message = ""; - - if (model.getName() != null) { - message += toBold.apply(model.getName()); - } + // Find in local repository + File localArtifactLocation = plugin.getLocalRepositorySearcher().findLocalFile(dependency); + if (localArtifactLocation != null && localArtifactLocation.isFile()) { + Model model = builder.buildRawModel(localArtifactLocation, ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL, true).get(); + if (model != null) { + UnaryOperator toBold = supportsMarkdown ? MarkdownUtils::toBold + : UnaryOperator.identity(); + String lineBreak = MarkdownUtils.getLineBreak(supportsMarkdown); + String message = ""; + + if (model.getName() != null) { + message += toBold.apply(model.getName()); + } - if (model.getDescription() != null) { - message += lineBreak + model.getDescription(); - } + if (model.getDescription() != null) { + message += lineBreak + model.getDescription(); + } - if (!wellDefined) { - String managedVersion = getManagedVersionText(request); - if (managedVersion == null) { - managedVersion = getActualVersionText(supportsMarkdown, model); - } - if (managedVersion != null) { - message += lineBreak + managedVersion; - } + if (!wellDefined) { + String managedVersion = getManagedVersionText(request); + if (managedVersion == null) { + managedVersion = getActualVersionText(supportsMarkdown, model); + } + if (managedVersion != null) { + message += lineBreak + managedVersion; } - - return message; - }).map(message -> (message.length() > 2 ? message : null)); - if (localDescription.isPresent()) { - return new Hover(new MarkupContent(supportsMarkdown ? MarkupKind.MARKDOWN : MarkupKind.PLAINTEXT, - localDescription.get())); + } + + if (message.length() > 2) { + return new Hover(new MarkupContent(supportsMarkdown ? MarkupKind.MARKDOWN : MarkupKind.PLAINTEXT, message)); + } + } } } catch (Exception e1) { LOGGER.log(Level.SEVERE, e1.toString(), e1); @@ -358,7 +351,7 @@ private Hover collectArtifactDescription(IHoverRequest request) { private Hover collectGoal(IPositionRequest request) { DOMNode node = request.getNode(); try { - PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request, plugin); + PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(node, plugin); if (pluginDescriptor == null) { // probable incorrect pom file at this moment return null; } diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMUtils.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMUtils.java index b62afeff..be9914a3 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMUtils.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Red Hat Inc. and others. + * Copyright (c) 2020, 2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -24,17 +24,17 @@ public class DOMUtils { - public static DOMNode findClosestParentNode(final IPositionRequest request, final String localName) { - if (localName == null || request == null) { + public static DOMNode findClosestParentNode(final DOMNode node, final String localName) { + if (localName == null || node == null) { return null; } - DOMNode pluginNode = request.getNode(); - while (pluginNode != null) { - if (localName.equals(pluginNode.getLocalName())) { - return pluginNode; + DOMNode parentNode = node; + while (parentNode != null) { + if (localName.equals(parentNode.getLocalName())) { + return parentNode; } - pluginNode = pluginNode.getParentNode(); + parentNode = parentNode.getParentNode(); } return null; diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/MavenPluginUtils.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/MavenPluginUtils.java index d72714fb..d40a1f8e 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/MavenPluginUtils.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/MavenPluginUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2022 Red Hat Inc. and others. + * Copyright (c) 2020, 2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -87,12 +87,12 @@ public static MarkupContent getMarkupDescription(MojoParameter parameter, MojoPa public static Set collectPluginConfigurationParameters(IPositionRequest request, MavenLemminxExtension plugin) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { - PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request, plugin); + PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request.getNode(), plugin); if (pluginDescriptor == null) { return Collections.emptySet(); } List mojosToConsiderList = pluginDescriptor.getMojos(); - DOMNode executionElementDomNode = DOMUtils.findClosestParentNode(request, "execution"); + DOMNode executionElementDomNode = DOMUtils.findClosestParentNode(request.getNode(), "execution"); if (executionElementDomNode != null) { Set interestingMojos = executionElementDomNode.getChildren().stream() .filter(node -> GOALS_ELT.equals(node.getLocalName())).flatMap(node -> node.getChildren().stream()) @@ -108,12 +108,12 @@ public static Set collectPluginConfigurationParameters(IPositionReque public static Set collectPluginConfigurationMojoParameters(IPositionRequest request, MavenLemminxExtension plugin) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { - PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request, plugin); + PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(request.getNode(), plugin); if (pluginDescriptor == null) { return Collections.emptySet(); } List mojosToConsiderList = pluginDescriptor.getMojos(); - DOMNode executionElementDomNode = DOMUtils.findClosestParentNode(request, EXECUTION_ELT); + DOMNode executionElementDomNode = DOMUtils.findClosestParentNode(request.getNode(), EXECUTION_ELT); if (executionElementDomNode != null) { Set interestingMojos = executionElementDomNode.getChildren().stream() .filter(node -> GOALS_ELT.equals(node.getLocalName())).flatMap(node -> node.getChildren().stream()) @@ -137,15 +137,15 @@ public static RemoteRepository toRemoteRepo(Repository modelRepo) { return builder.build(); } - public static PluginDescriptor getContainingPluginDescriptor(IPositionRequest request, + public static PluginDescriptor getContainingPluginDescriptor(DOMNode node, MavenLemminxExtension lemminxMavenPlugin) throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException { MavenProject project = lemminxMavenPlugin.getProjectCache() - .getLastSuccessfulMavenProject(request.getXMLDocument()); + .getLastSuccessfulMavenProject(node.getOwnerDocument()); if (project == null) { return null; } - DOMNode pluginNode = DOMUtils.findClosestParentNode(request, PLUGIN_ELT); + DOMNode pluginNode = DOMUtils.findClosestParentNode(node, PLUGIN_ELT); if (pluginNode == null) { return null; } @@ -162,15 +162,15 @@ public static PluginDescriptor getContainingPluginDescriptor(IPositionRequest re Plugin plugin = findPluginInProject(project, pluginKey, artifactId); if (plugin == null) { - DOMNode profileNode = DOMUtils.findClosestParentNode(request, "profile"); + DOMNode profileNode = DOMUtils.findClosestParentNode(node, "profile"); if (profileNode != null) { project = profileNode.getChildren().stream() // .filter(DOMElement.class::isInstance) // .map(DOMElement.class::cast) // - .filter(node -> "id".equals(node.getLocalName())) // - .map(node -> node.getChild(0).getTextContent()) + .filter(n -> "id".equals(n.getLocalName())) // + .map(n -> n.getChild(0).getTextContent()) .filter(Objects::nonNull) - .map(profileId -> lemminxMavenPlugin.getProjectCache().getSnapshotProject(request.getXMLDocument(), profileId)) // + .map(profileId -> lemminxMavenPlugin.getProjectCache().getSnapshotProject(node.getOwnerDocument(), profileId)) // .filter(Objects::nonNull) .findFirst().orElse(null); if (project != null) { @@ -184,6 +184,11 @@ public static PluginDescriptor getContainingPluginDescriptor(IPositionRequest re PluginDescriptor pluginDescriptor = null; try { + // Fix plugin version in case its value is 'null', to initiate search for an actual version + if (plugin.getVersion() == null) { + plugin.setVersion("0.0.1-SNAPSHOT"); + } + pluginDescriptor = lemminxMavenPlugin.getMavenPluginManager().getPluginDescriptor(plugin, project.getRemotePluginRepositories().stream().collect(Collectors.toList()), lemminxMavenPlugin.getMavenSession().getRepositorySession()); @@ -225,5 +230,4 @@ private static Plugin findPluginInProject(MavenProject project, String pluginKey } return plugin.orElse(null); } - } diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtils.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtils.java index c3da7812..082723fa 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtils.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtils.java @@ -1,3 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2022, 2023 Red Hat Inc. and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Victor Rubezhny (Red Hat Inc.) - initial implementation + *******************************************************************************/ package org.eclipse.lemminx.extensions.maven.utils; import static org.eclipse.lemminx.extensions.maven.DOMConstants.ARTIFACT_ID_ELT; @@ -20,6 +32,10 @@ import org.apache.commons.lang3.Validate; import org.apache.maven.model.Dependency; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; import org.apache.maven.properties.internal.EnvironmentUtils; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -77,6 +93,48 @@ public static DOMElement findInterestingElement(DOMNode node) { return null; } + public static Dependency resolveDependency (MavenProject project, Dependency dependency, DOMElement element, + MavenLemminxExtension plugin) { + if (dependency == null || element == null) { + return null; + } + + if (isWellDefinedDependency(dependency)) { + return dependency; + } + + if (isPlugin(element)) { + try { + PluginDescriptor pluginDescriptor = MavenPluginUtils.getContainingPluginDescriptor(element, plugin); + if (pluginDescriptor != null) { + dependency.setGroupId(pluginDescriptor.getGroupId()); + dependency.setArtifactId(pluginDescriptor.getArtifactId()); + dependency.setVersion(pluginDescriptor.getVersion()); + } + } catch (PluginResolutionException | PluginDescriptorParsingException + | InvalidPluginDescriptorException e) { + // Ignore + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } else if (isDependency(element)) { + if (dependency.getGroupId() == null || dependency.getVersion() == null) { + if (project != null) { + final Dependency originalDependency = dependency; + dependency = project.getDependencies().stream() + .filter(dep -> (originalDependency.getGroupId() == null + || originalDependency.getGroupId().equals(dep.getGroupId()) + && (originalDependency.getArtifactId() == null + || originalDependency.getArtifactId().equals(dep.getArtifactId())) + && (originalDependency.getVersion() == null + || originalDependency.getVersion().equals(dep.getVersion())))) + .findFirst().orElse(dependency); + } + } + } + return dependency; + } + public static Artifact findWorkspaceArtifact(MavenLemminxExtension plugin, IPositionRequest request, Dependency artifactToSearch) { // Here we can search only if all artifact is well defined if (!isWellDefinedDependency(artifactToSearch)) { @@ -143,8 +201,8 @@ public static boolean isParentDeclaration(DOMElement element) { (element.getParentElement() != null && PARENT_ELT.equals(element.getParentElement().getLocalName())); } - public static Dependency getArtifactToSearch(MavenProject pproject, IPositionRequest request) { - Dependency artifactToSearch = MavenParseUtils.parseArtifact(request.getNode()); + public static Dependency getArtifactToSearch(MavenProject pproject, DOMNode node) { + Dependency artifactToSearch = MavenParseUtils.parseArtifact(node); if (artifactToSearch != null) { if (artifactToSearch.getGroupId() != null && artifactToSearch.getGroupId().contains("$")) { artifactToSearch = artifactToSearch.clone(); diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalPluginTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalPluginTest.java index 49708121..83514100 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalPluginTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalPluginTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019-2022 Red Hat Inc. and others. + * Copyright (c) 2019-2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -32,6 +32,7 @@ import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; import org.eclipse.lsp4j.HoverCapabilities; +import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.MarkupKind; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; @@ -225,6 +226,16 @@ public void testPluginArtifactHover() throws IOException, InterruptedException, new Position(14, 18), new SharedSettings()).getContents().getRight().getValue().contains("Maven Surefire MOJO in maven-surefire-plugin")); } + // Definition related tests + + @Test + public void testPluginArtifactDefinition() throws IOException, InterruptedException, ExecutionException, URISyntaxException, TimeoutException { + // Find Definition links + List definitions = languageService.findDefinition(createDOMDocument("/pom-plugin-artifact-hover.xml", languageService), new Position(14, 18), ()->{}); + definitions.stream().map(LocationLink::getTargetUri).forEach(u -> System.out.println("Definition Link: " + u)); + assertTrue(definitions.stream().map(LocationLink::getTargetUri).anyMatch(uri -> uri.endsWith(".pom") && uri.contains("maven-surefire-plugin"))); + } + // Diagnostic related tests @Test diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/ManagedVersionHoverTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/ManagedVersionHoverTest.java index 0a628e50..08743af3 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/ManagedVersionHoverTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/ManagedVersionHoverTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Red Hat Inc. and others. + * Copyright (c) 2022, 2023 Red Hat Inc. and others. * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ @@ -16,6 +16,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.List; import java.util.concurrent.ExecutionException; import org.eclipse.lemminx.dom.DOMDocument; @@ -24,6 +25,7 @@ import org.eclipse.lemminx.settings.SharedSettings; import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.HoverCapabilities; +import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.MarkupKind; import org.eclipse.lsp4j.Position; import org.junit.jupiter.api.AfterEach; @@ -117,6 +119,34 @@ void testManagedVersionHoverInDependencyGrandchild() throws IOException, URISynt assertTrue(value.contains("hierarchy2/pom.xml")); } + @Test + @Timeout(90000) + void testManagedVersionHoverForBomProvidedDependency() throws IOException, URISyntaxException { + System.out.println(">>> testManagedVersionHoverForBomProvidedDependency"); + DOMDocument document = createDOMDocument("/pom-bom-defined-dependency-version.xml", languageService); + Position position = new Position(25, 20); + + // Find Definition links + List definitions = languageService.findDefinition(document, position, ()->{}); + definitions.stream().map(LocationLink::getTargetUri).forEach(u -> System.out.println("Definition Link: " + u)); + assertTrue(definitions.stream().map(LocationLink::getTargetUri).anyMatch(uri -> uri.endsWith("jakarta.jakartaee-api-8.0.0.pom"))); + + // Find Hover with managed version + Hover hover = languageService.doHover(document, position, createSharedSettings()); + final String value = hover.getContents().getRight().getValue(); + System.out.println("Hover Text: [" + value + "]"); + assertNotNull(value); + assertTrue(value.contains("The managed version is")); + assertTrue(value.contains("8.0.0")); + assertTrue(value.contains("The artifact is managed in")); + assertTrue(value.contains("jakarta.platform:jakarta.jakartaee-api:8.0.0")); + + // Compare the links from definition and hover + assertTrue(definitions.stream().map(LocationLink::getTargetUri) + .anyMatch(uri -> value.replace('\\', '/').contains(uri.substring("file:/".length())))); + System.out.println("<<< testManagedVersionHoverForBomProvidedDependency"); + } + // Enable MARKDOWN format private static SharedSettings createSharedSettings() { HoverCapabilities hoverCapabilities = new HoverCapabilities(); diff --git a/lemminx-maven/src/test/resources/pom-bom-defined-dependency-version.xml b/lemminx-maven/src/test/resources/pom-bom-defined-dependency-version.xml new file mode 100644 index 00000000..f36eebcb --- /dev/null +++ b/lemminx-maven/src/test/resources/pom-bom-defined-dependency-version.xml @@ -0,0 +1,30 @@ + + 4.0.0 + org.org.eclipse.lemminx.lemminx-maven.test + bom.defined.version.test + 0.0.1-SNAPSHOT + + + 5.2022.3 + + + + + + fish.payara.api + payara-bom + ${payara-version} + pom + import + + + + + + + jakarta.platform + jakarta.jakartaee-api + provided + + + \ No newline at end of file diff --git a/lemminx-maven/src/test/resources/pom-localrepo-test-dependencies.xml b/lemminx-maven/src/test/resources/pom-localrepo-test-dependencies.xml index 497d3f48..0cca66c0 100644 --- a/lemminx-maven/src/test/resources/pom-localrepo-test-dependencies.xml +++ b/lemminx-maven/src/test/resources/pom-localrepo-test-dependencies.xml @@ -31,5 +31,29 @@ target-platform-configuration 3.0.0 + + jakarta.platform + jakarta.jakartaee-api + 8.0.0 + provided + + + + jakarta.platform. + jakarta.jakartaee-api + 10.0.0 + provided + + + fish.payara.api + payara-bom + 5.2022.3 + pom + import + \ No newline at end of file