Skip to content

Commit

Permalink
validate element in plugin <configuration> and plugin goals
Browse files Browse the repository at this point in the history
Fix #9

Signed-off-by: Andrew Obuchowicz <aobuchow@redhat.com>
  • Loading branch information
AObuchow committed Apr 28, 2020
1 parent 2d2d7d5 commit bca9145
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,50 @@

import java.util.List;

import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.dom.LineIndentInfo;
import org.eclipse.lemminx.services.extensions.IPositionRequest;
import org.eclipse.lemminx.utils.XMLPositionUtility;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;

public class DiagnosticRequest {
public class DiagnosticRequest implements IPositionRequest {
private DOMNode node;
private DOMDocument xmlDocument;
private List<Diagnostic> diagnostics;

public DiagnosticRequest(DOMNode node, DOMDocument xmlDocument, List<Diagnostic> diagnostics) {
this.setNode(node);
this.setDOMDocument(xmlDocument);
this.setXMLDocument(xmlDocument);
this.setDiagnostics(diagnostics);
}

public DOMDocument getDOMDocument() {
public DOMDocument getXMLDocument() {
return xmlDocument;
}

public void setDOMDocument(DOMDocument xmlDocument) {
private void setXMLDocument(DOMDocument xmlDocument) {
this.xmlDocument = xmlDocument;
}

@Override
public DOMNode getNode() {
return node;
}

public void setNode(DOMNode node) {
private void setNode(DOMNode node) {
this.node = node;
}

public List<Diagnostic> getDiagnostics() {
return diagnostics;
}

public void setDiagnostics(List<Diagnostic> diagnostics) {
private void setDiagnostics(List<Diagnostic> diagnostics) {
this.diagnostics = diagnostics;
}

Expand All @@ -57,4 +62,40 @@ public Range getRange() {
((DOMElement) node).getEndTagOpenOffset(), xmlDocument);
}

@Override
public int getOffset() {
return 0;
}

@Override
public Position getPosition() {
return null;
}

@Override
public DOMElement getParentElement() {
return this.node.getParentElement();
}

@Override
public String getCurrentTag() {
return this.node.getLocalName();
}

@Override
public String getCurrentAttributeName() {
return null;
}

@Override
public LineIndentInfo getLineIndentInfo() throws BadLocationException {
return null;
}

@Override
public <T> T getComponent(Class clazz) {
// TODO: Not sure how to implement this..
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.apache.maven.model.building.ModelProblem;
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.plugin.MavenPluginManager;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
Expand All @@ -31,9 +32,11 @@
public class MavenDiagnosticParticipant implements IDiagnosticsParticipant {

private MavenProjectCache projectCache;
MavenPluginManager pluginManager;

public MavenDiagnosticParticipant(MavenProjectCache projectCache) {
public MavenDiagnosticParticipant(MavenProjectCache projectCache, MavenPluginManager pluginManager) {
this.projectCache = projectCache;
this.pluginManager = pluginManager;
}

@Override
Expand Down Expand Up @@ -79,24 +82,13 @@ public void doDiagnostics(DOMDocument xmlDocument, List<Diagnostic> diagnostics,

private HashMap<String, Function<DiagnosticRequest, Diagnostic>> configureDiagnosticFunctions(
DOMDocument xmlDocument) {
// SubModuleValidator subModuleValidator= new SubModuleValidator();
// try {
// subModuleValidator.setPomFile(new File(xmlDocument.getDocumentURI().substring(5)));
// } catch (IOException | XmlPullParserException e) {
// // TODO: Use plug-in error logger
// e.printStackTrace();
// }
//Function<DiagnosticRequest, Diagnostic> versionFunc = VersionValidator::validateVersion;
//Function<DiagnosticRequest, Diagnostic> submoduleExistenceFunc = subModuleValidator::validateSubModuleExistence;
// Below is a mock Diagnostic function which creates a warning between inside
// <configuration> tags
//Function<DiagnosticRequest, Diagnostic> configFunc = diagnosticReq -> new Diagnostic(diagnosticReq.getRange(),
// "Configuration Error", DiagnosticSeverity.Warning, xmlDocument.getDocumentURI(), "XML");
PluginValidator pluginValidator = new PluginValidator(projectCache, pluginManager);
Function<DiagnosticRequest, Diagnostic> validatePluginConfiguration = pluginValidator::validateConfiguration;
Function<DiagnosticRequest, Diagnostic> validatePluginGoal = pluginValidator::validateGoal;

HashMap<String, Function<DiagnosticRequest, Diagnostic>> tagDiagnostics = new HashMap<>();
//tagDiagnostics.put("version", versionFunc);
//tagDiagnostics.put("configuration", configFunc);
//tagDiagnostics.put("module", submoduleExistenceFunc);
tagDiagnostics.put("configuration", validatePluginConfiguration);
tagDiagnostics.put("goal", validatePluginGoal);
return tagDiagnostics;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
}
completionParticipant = new MavenCompletionParticipant(cache, localRepositorySearcher, indexSearcher, mavenPluginManager);
registry.registerCompletionParticipant(completionParticipant);
diagnosticParticipant = new MavenDiagnosticParticipant(cache);
diagnosticParticipant = new MavenDiagnosticParticipant(cache, mavenPluginManager);
registry.registerDiagnosticsParticipant(diagnosticParticipant);
hoverParticipant = new MavenHoverParticipant(cache, localRepositorySearcher, indexSearcher, mavenPluginManager);
registry.registerHoverParticipant(hoverParticipant);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2019-2020 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
*******************************************************************************/
package org.eclipse.lemminx.maven;

import java.util.List;

import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.descriptor.Parameter;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;

public class PluginValidator {
private final MavenProjectCache cache;
private final MavenPluginManager pluginManager;

public PluginValidator(MavenProjectCache cache, MavenPluginManager pluginManager) {
this.cache = cache;
this.pluginManager = pluginManager;
}

public Diagnostic validateConfiguration(DiagnosticRequest diagnosticRequest) {
DOMNode node = diagnosticRequest.getNode();
if (node == null) {
return null;
}
if (node.isElement() && node.hasChildNodes()) {
List<Parameter> parameters = MavenPluginUtils.collectPluginConfigurationParameters(diagnosticRequest, cache,
pluginManager);
for (DOMNode childNode : node.getChildren()) {
DiagnosticRequest childDiagnosticReq = new DiagnosticRequest(childNode,
diagnosticRequest.getXMLDocument(), diagnosticRequest.getDiagnostics());
Diagnostic diag = internalValidateConfiguration(childDiagnosticReq, parameters);
if (diag != null) {
diagnosticRequest.getDiagnostics().add(diag);
}
}
}
return null;
}

public Diagnostic validateGoal(DiagnosticRequest diagnosticRequest) {
DOMNode node = diagnosticRequest.getNode();
if (node == null) {
return null;
}
if (node.isElement() && node.hasChildNodes()) {
List<Parameter> parameters = MavenPluginUtils.collectPluginConfigurationParameters(diagnosticRequest, cache,
pluginManager);
Diagnostic diag = internalValidateGoal(diagnosticRequest, parameters);
if (diag != null) {
diagnosticRequest.getDiagnostics().add(diag);
}
}
return null;
}

private static Diagnostic internalValidateGoal(DiagnosticRequest diagnosticReq, List<Parameter> parameters) {
DOMNode node = diagnosticReq.getNode();
if (!node.hasChildNodes()) {
return null;
}
for (Parameter parameter : parameters) {
if (node.getChild(0).getNodeValue().equals(parameter.getName())) {
return null;
}
}
return new Diagnostic(diagnosticReq.getRange(), "Invalid goal for this plugin", DiagnosticSeverity.Warning,
diagnosticReq.getXMLDocument().getDocumentURI(), "XML");

}

private static Diagnostic internalValidateConfiguration(DiagnosticRequest diagnosticReq,
List<Parameter> parameters) {
DOMNode node = diagnosticReq.getNode();
if (node.getLocalName() == null) {
return null;
}
for (Parameter parameter : parameters) {
if (node.getLocalName().equals(parameter.getName())) {
return null;
}
}
return new Diagnostic(diagnosticReq.getRange(), "Invalid plugin configuration: " + diagnosticReq.getCurrentTag(), DiagnosticSeverity.Warning,
diagnosticReq.getXMLDocument().getDocumentURI(), "XML");

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void setPomFile(File pomFile) throws FileNotFoundException, IOException,

public Diagnostic validateSubModuleExistence(DiagnosticRequest diagnosticRequest) {
DOMNode node = diagnosticRequest.getNode();
DOMDocument xmlDocument = diagnosticRequest.getDOMDocument();
DOMDocument xmlDocument = diagnosticRequest.getXMLDocument();
Diagnostic diagnostic = null;
Range range = diagnosticRequest.getRange();
String tagContent = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class VersionValidator {

public static Diagnostic validateVersion(DiagnosticRequest diagnosticRequest) {
DOMNode node = diagnosticRequest.getNode();
DOMDocument xmlDocument = diagnosticRequest.getDOMDocument();
DOMDocument xmlDocument = diagnosticRequest.getXMLDocument();
Dependency model = MavenParseUtils.parseArtifact(node);
Artifact artifact = null;
Range range = diagnosticRequest.getRange();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings;
import org.eclipse.lemminx.services.XMLLanguageService;
import org.eclipse.lemminx.settings.SharedSettings;
import org.eclipse.lemminx.settings.XMLHoverSettings;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.TextEdit;
import org.junit.After;
Expand Down Expand Up @@ -86,4 +89,22 @@ public void testPluginArtifactHover() throws IOException, InterruptedException,
assertTrue(languageService.doHover(createDOMDocument("/pom-plugin-artifact-hover.xml", languageService),
new Position(14, 18), new XMLHoverSettings()).getContents().getRight().getValue().contains("Maven Surefire MOJO in maven-surefire-plugin"));
}

// Diagnostic related tests

@Test(timeout=30000)
public void testPluginConfigurationDiagnostics() throws IOException, InterruptedException, ExecutionException, URISyntaxException {
DOMDocument document = createDOMDocument("/pom-plugin-configuration-diagnostic.xml", languageService);
assertTrue(languageService.doDiagnostics(document, () -> {}, new XMLValidationSettings()).stream().map(Diagnostic::getMessage)
.anyMatch(message -> message.contains("Invalid plugin configuration")));
assertTrue(languageService.doDiagnostics(document, () -> {}, new XMLValidationSettings()).size() == 2);
}

@Test
public void testPluginGoalDiagnostics() throws IOException, InterruptedException, ExecutionException, URISyntaxException {
DOMDocument document = createDOMDocument("/pom-plugin-goal-diagnostic.xml", languageService);
assertTrue(languageService.doDiagnostics(document, () -> {}, new XMLValidationSettings()).stream().map(Diagnostic::getMessage)
.anyMatch(message -> message.contains("Invalid goal for this plugin")));
assertTrue(languageService.doDiagnostics(document, () -> {}, new XMLValidationSettings()).size() == 2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>org.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version> <!-- Same version as in actual pom.xml that builds project -->
<configuration>
<dependenciesToScan>
<dependency>org.acme:project-a</dependency>
</dependenciesToScan>
<notValidConfig><!-- This tag should cause a warning --></notValidConfig>
<anotherNotValidConfig><!-- This tag should cause a warning --></anotherNotValidConfig>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>soffid</id>
<layout>m2</layout>
<url>http://www.soffid.com/maven/</url>
</repository>
</repositories>

</project>
37 changes: 37 additions & 0 deletions lemminx-maven/src/test/resources/pom-plugin-goal-diagnostic.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>org.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version> <!-- Need to be same as in lemminx-maven pom so we're sure version in in local repo -->
<executions>
<execution>
<id>execution1</id>
<goals><goal>test</goal></goals>
</execution>
<execution>
<id>execution2</id>
<goals><goal>invalid-goal</goal></goals>
<configuration>

</configuration>
</execution>
<execution>
<id>execution3</id>
<goals><goal>another-invalid-goal</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

0 comments on commit bca9145

Please sign in to comment.