diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenInitializationException.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenInitializationException.java new file mode 100644 index 00000000..93d9cd66 --- /dev/null +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenInitializationException.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.lemminx.extensions.maven; + +import java.util.concurrent.CancellationException; + +/** + * Exception thrown when Maven is initializing. + * + * @author Angelo ZERR + * + */ +public class MavenInitializationException extends CancellationException{ + +} diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenLemminxExtension.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenLemminxExtension.java index bd0079ff..cf8e63f0 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenLemminxExtension.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenLemminxExtension.java @@ -33,6 +33,8 @@ import java.util.Objects; import java.util.Optional; import java.util.Properties; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -108,7 +110,10 @@ * */ public class MavenLemminxExtension implements IXMLExtension { - + + // Used for tests + public static boolean initializeMavenOnBackground = true; + private static final Logger LOGGER = Logger.getLogger(MavenLemminxExtension.class.getName()); private static final String MAVEN_XMLLS_EXTENSION_REALM_ID = MavenLemminxExtension.class.getName(); @@ -136,6 +141,9 @@ public class MavenLemminxExtension implements IXMLExtension { private URIResolverExtensionManager resolverExtensionManager; private List initialWorkspaceFolders = List.of(); private LinkedHashSet currentWorkspaceFolders = new LinkedHashSet<>(); + + // Thread which loads Maven component (plexus container, maven session, etc) which can take some time. + private CompletableFuture mavenInitializer; @Override public void doSave(ISaveContext context) { @@ -189,32 +197,51 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) { } } - private synchronized void initialize() { - if (mavenSession != null) { - // already initialized - return; + private void initialize() throws MavenInitializationException { + if (!getMavenInitializer().isDone() ) { + // The Maven initialization is not ready, throws a MavenInitializationException. + throw new MavenInitializationException(); } - try { - this.container = newPlexusContainer(); - mavenRequest = initMavenRequest(container, settings); - DefaultRepositorySystemSessionFactory repositorySessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class); - RepositorySystemSession repositorySystemSession = repositorySessionFactory.newRepositorySession(mavenRequest); - MavenExecutionResult mavenResult = new DefaultMavenExecutionResult(); - // TODO: MavenSession is deprecated. Investigate for alternative - mavenSession = new MavenSession(container, repositorySystemSession, mavenRequest, mavenResult); - cache = new MavenProjectCache(this); - localRepositorySearcher = new LocalRepositorySearcher(mavenSession.getRepositorySession().getLocalRepository().getBasedir()); - if (!settings.getCentral().isSkip()) { - centralSearcher = new RemoteCentralRepositorySearcher(); + } + + private synchronized CompletableFuture getMavenInitializer() { + // Create thread which loads Maven component (plexus container, maven session, etc) which can take some time. + // We do this initialization on background to avoid breaking the XML syntax validation, XML based onXSD, XML completion based on XSD + // while Maven component is initializing. + if (mavenInitializer == null) { + mavenInitializer = CompletableFuture.runAsync(() -> { + try { + this.container = newPlexusContainer(); + mavenRequest = initMavenRequest(container, settings); + DefaultRepositorySystemSessionFactory repositorySessionFactory = container.lookup(DefaultRepositorySystemSessionFactory.class); + RepositorySystemSession repositorySystemSession = repositorySessionFactory.newRepositorySession(mavenRequest); + MavenExecutionResult mavenResult = new DefaultMavenExecutionResult(); + // TODO: MavenSession is deprecated. Investigate for alternative + mavenSession = new MavenSession(container, repositorySystemSession, mavenRequest, mavenResult); + cache = new MavenProjectCache(mavenSession); + localRepositorySearcher = new LocalRepositorySearcher(mavenSession.getRepositorySession().getLocalRepository().getBasedir()); + if (!settings.getCentral().isSkip()) { + centralSearcher = new RemoteCentralRepositorySearcher(); + } + buildPluginManager = null; + mavenPluginManager = container.lookup(MavenPluginManager.class); + buildPluginManager = container.lookup(BuildPluginManager.class); + internalDidChangeWorkspaceFolders(this.initialWorkspaceFolders.stream().map(WorkspaceFolder::getUri).map(URI::create).toArray(URI[]::new), null); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + stop(currentRegistry); + } + }); + } + if (!initializeMavenOnBackground) { + // This code is for tests + try { + mavenInitializer.get(); + } catch (InterruptedException | ExecutionException e) { + Thread.currentThread().interrupt(); } - buildPluginManager = null; - mavenPluginManager = container.lookup(MavenPluginManager.class); - buildPluginManager = container.lookup(BuildPluginManager.class); - didChangeWorkspaceFolders(this.initialWorkspaceFolders.stream().map(WorkspaceFolder::getUri).map(URI::create).toArray(URI[]::new), null); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - stop(currentRegistry); } + return mavenInitializer; } private MavenExecutionRequest initMavenRequest(PlexusContainer container, XMLMavenSettings options) throws Exception { @@ -388,6 +415,9 @@ public void stop(XMLExtensionsRegistry registry) { } this.mavenSession = null; this.currentRegistry = null; + if (mavenInitializer != null) { + mavenInitializer.cancel(true); + } } public static boolean match(DOMDocument document) { @@ -449,9 +479,17 @@ public URIResolverExtensionManager getUriResolveExtentionManager() { public LinkedHashSet getCurrentWorkspaceFolders() { return currentWorkspaceFolders; } - + public void didChangeWorkspaceFolders(URI[] added, URI[] removed) { - initialize(); + CompletableFuture initializer = getMavenInitializer(); + if (initializer.isDone()) { + internalDidChangeWorkspaceFolders(added, removed); + } else { + initializer.thenAccept(Void -> internalDidChangeWorkspaceFolders(added, removed)); + } + } + + public void internalDidChangeWorkspaceFolders(URI[] added, URI[] removed) { currentWorkspaceFolders.addAll(List.of(added != null? added : new URI[0])); currentWorkspaceFolders.removeAll(List.of(removed != null ? removed : new URI[0])); WorkspaceReader workspaceReader = mavenRequest.getWorkspaceReader(); diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenProjectCache.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenProjectCache.java index e10cd361..9d2ab237 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenProjectCache.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/MavenProjectCache.java @@ -8,7 +8,6 @@ *******************************************************************************/ package org.eclipse.lemminx.extensions.maven; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -19,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.CancellationException; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -28,6 +28,7 @@ import org.apache.maven.artifact.repository.MavenArtifactRepository; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.building.DefaultModelProblem; @@ -49,6 +50,7 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.utils.DOMModelSource; public class MavenProjectCache { @@ -58,19 +60,15 @@ public class MavenProjectCache { private final Map projectCache; private final Map> problemCache; - private final MavenLemminxExtension lemminxMavenPlugin; - private final PlexusContainer plexusContainer; - private final MavenExecutionRequest mavenRequest; + private final MavenSession mavenSession; MavenXpp3Reader mavenReader = new MavenXpp3Reader(); private ProjectBuilder projectBuilder; private final List> projectParsedListeners = new ArrayList<>(); - public MavenProjectCache(MavenLemminxExtension lemminxMavenPlugin) { - this.lemminxMavenPlugin = lemminxMavenPlugin; - this.mavenRequest = lemminxMavenPlugin.getMavenSession().getRequest(); - this.plexusContainer = lemminxMavenPlugin.getPlexusContainer(); + public MavenProjectCache(MavenSession mavenSession) { + this.mavenSession = mavenSession; this.lastCheckedVersion = new HashMap<>(); this.projectCache = new HashMap<>(); this.problemCache = new HashMap<>(); @@ -212,7 +210,11 @@ private void parseAndCache(URI uri, int version, FileModelSource source) { } } } - } catch (Exception e) { + } catch (CancellationException e){ + // The document which has been used to load Maven project is out of dated + throw e; + } + catch (Exception e) { // Do not add any info, like lastCheckedVersion or problems, to the cache // In case of project/problems etc. is not available due to an exception happened. // @@ -236,12 +238,7 @@ private void cacheProject(final MavenProject project, File file, URI uri, private void parseAndCache(DOMDocument document) { URI uri = URI.create(document.getDocumentURI()).normalize(); int version = document.getTextDocument().getVersion(); - FileModelSource source = new FileModelSource(new File(uri)) { - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(document.getText().getBytes()); - } - }; + DOMModelSource source = new DOMModelSource(document); parseAndCache(uri, version, source); } @@ -257,12 +254,13 @@ private ProjectBuildingRequest newProjectBuildingRequest() { private ProjectBuildingRequest newProjectBuildingRequest(boolean resolveDependencies) { ProjectBuildingRequest request = new DefaultProjectBuildingRequest(); + MavenExecutionRequest mavenRequest = mavenSession.getRequest(); request.setSystemProperties(mavenRequest.getSystemProperties()); request.setLocalRepository(mavenRequest.getLocalRepository()); request.setRemoteRepositories(mavenRequest.getRemoteRepositories()); request.setPluginArtifactRepositories(mavenRequest.getPluginArtifactRepositories()); // TODO more to transfer from mavenRequest to ProjectBuildingRequest? - request.setRepositorySession(lemminxMavenPlugin.getMavenSession().getRepositorySession()); + request.setRepositorySession(mavenSession.getRepositorySession()); request.setResolveDependencies(resolveDependencies); // See: https://issues.apache.org/jira/browse/MRESOLVER-374 @@ -283,7 +281,7 @@ private void initializeMavenBuildState() { } public PlexusContainer getPlexusContainer() { - return plexusContainer; + return mavenSession.getContainer(); } public Collection getProjects() { @@ -301,12 +299,11 @@ public MavenProject getSnapshotProject(DOMDocument document, String profileId, b request.setActiveProfileIds(List.of(profileId)); } try { - return projectBuilder.build(new FileModelSource(new File(document.getDocumentURI())) { - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(document.getText().getBytes()); - } - }, request).getProject(); + DOMModelSource source = new DOMModelSource(document); + return projectBuilder.build(source, request).getProject(); + } catch (CancellationException e) { + // The document which has been used to load Maven project is out of dated + throw e; } catch (ProjectBuildingException e) { List result = e.getResults(); if (result != null && result.size() == 1 && result.get(0).getProject() != null) { 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 759c39b5..eec7e4d4 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 @@ -23,6 +23,12 @@ import static org.eclipse.lemminx.extensions.maven.DOMConstants.MODULE_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.OUTPUT_DIRECTORY_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_ELT; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_EAR; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_EJB; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_JAR; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_MAVEN_PLUGIN; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_POM; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_WAR; import static org.eclipse.lemminx.extensions.maven.DOMConstants.PARENT_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.PHASE_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.PLUGINS_ELT; @@ -36,13 +42,6 @@ import static org.eclipse.lemminx.extensions.maven.DOMConstants.TEST_SOURCE_DIRECTORY_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.VERSION_ELT; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_JAR; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_WAR; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_EJB; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_EAR; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_POM; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.PACKAGING_TYPE_MAVEN_PLUGIN; - import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -102,6 +101,7 @@ import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.extensions.maven.DOMConstants; import org.eclipse.lemminx.extensions.maven.DependencyScope; +import org.eclipse.lemminx.extensions.maven.MavenInitializationException; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.MojoParameter; import org.eclipse.lemminx.extensions.maven.Phase; @@ -183,9 +183,13 @@ public void onTagOpen(ICompletionRequest request, ICompletionResponse response, return; } - DOMNode tag = request.getNode(); - if (DOMUtils.isADescendantOf(tag, CONFIGURATION_ELT)) { - collectPluginConfiguration(request).forEach(response::addCompletionItem); + try { + DOMNode tag = request.getNode(); + if (DOMUtils.isADescendantOf(tag, CONFIGURATION_ELT)) { + collectPluginConfiguration(request).forEach(response::addCompletionItem); + } + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML completion from LemMinX } } @@ -246,224 +250,228 @@ public void onXMLContent(ICompletionRequest request, ICompletionResponse respons return; } - if (request.getXMLDocument().getText().length() < 2) { - response.addCompletionItem(createMinimalPOMCompletionSnippet(request)); - } - DOMElement parent = request.getParentElement(); - if (parent == null || parent.getLocalName() == null) { - return; - } - DOMElement grandParent = parent.getParentElement(); - boolean isPlugin = ParticipantUtils.isPlugin(parent); - boolean isParentDeclaration = ParticipantUtils.isParentDeclaration(parent); - Optional groupId = grandParent == null ? Optional.empty() - : grandParent.getChildren().stream().filter(DOMNode::isElement) - .filter(node -> GROUP_ID_ELT.equals(node.getLocalName())) - .flatMap(node -> node.getChildren().stream()).map(DOMNode::getTextContent) - .filter(Objects::nonNull).map(String::trim).filter(s -> !s.isEmpty()).findFirst(); - Optional artifactId = grandParent == null ? Optional.empty() - : grandParent.getChildren().stream().filter(DOMNode::isElement) - .filter(node -> ARTIFACT_ID_ELT.equals(node.getLocalName())) - .flatMap(node -> node.getChildren().stream()).map(DOMNode::getTextContent) - .filter(Objects::nonNull).map(String::trim).filter(s -> !s.isEmpty()).findFirst(); - GAVInsertionStrategy gavInsertionStrategy = computeGAVInsertionStrategy(request); - List allArtifactInfos = Collections.synchronizedList(new ArrayList<>()); - LinkedHashMap nonArtifactCollector = new LinkedHashMap<>(); - switch (parent.getLocalName()) { - case SCOPE_ELT: - collectSimpleCompletionItems(Arrays.asList(DependencyScope.values()), DependencyScope::getName, - DependencyScope::getDescription, request).forEach(response::addCompletionAttribute); - break; - case PHASE_ELT: - collectSimpleCompletionItems(Arrays.asList(Phase.ALL_STANDARD_PHASES), phase -> phase.id, - phase -> phase.description, request).forEach(response::addCompletionAttribute); - break; - case GROUP_ID_ELT: - if (isParentDeclaration) { - Optional filesystem = computeFilesystemParent(request); - if (filesystem.isPresent()) { - filesystem.map(MavenProject::getGroupId) - .map(g -> toCompletionItem(g.toString(), null, request.getReplaceRange())) - .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) - .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); - } - // TODO localRepo - // TODO remoteRepos - } else { - // TODO if artifactId is set and match existing content, suggest only matching - // groupId - collectSimpleCompletionItems( - isPlugin ? plugin.getLocalRepositorySearcher().searchPluginGroupIds() - : plugin.getLocalRepositorySearcher().searchGroupIds(), - Function.identity(), Function.identity(), request).stream() - .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) - .forEach(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); - internalCollectRemoteGAVCompletion(request, isPlugin, allArtifactInfos, nonArtifactCollector, cancelChecker); + try { + if (request.getXMLDocument().getText().length() < 2) { + response.addCompletionItem(createMinimalPOMCompletionSnippet(request)); } - internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); - - // Sort and move nonArtifactCollector items to the response and clear nonArtifactCollector - nonArtifactCollector.entrySet().stream() - .map(entry -> entry.getValue()).forEach(response::addCompletionItem); - nonArtifactCollector.clear(); - break; - case ARTIFACT_ID_ELT: - if (isParentDeclaration) { - Optional filesystem = computeFilesystemParent(request); - if (filesystem.isPresent()) { - filesystem.map(ArtifactWithDescription::new).ifPresent(allArtifactInfos::add); - } - // TODO localRepo - // TODO remoteRepos - } else { - allArtifactInfos.addAll((isPlugin ? plugin.getLocalRepositorySearcher().getLocalPluginArtifacts() - : plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion()).stream() - .filter(gav -> !groupId.isPresent() || gav.getGroupId().equals(groupId.get())) - // TODO pass description as documentation - .map(ArtifactWithDescription::new).collect(Collectors.toList())); - internalCollectRemoteGAVCompletion(request, isPlugin, allArtifactInfos, nonArtifactCollector, cancelChecker); + DOMElement parent = request.getParentElement(); + if (parent == null || parent.getLocalName() == null) { + return; } - internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); - break; - case VERSION_ELT: - if (isParentDeclaration) { - Optional filesystem = computeFilesystemParent(request); - if (filesystem.isPresent()) { - filesystem.map(MavenProject::getVersion).map(DefaultArtifactVersion::new) - .map(version -> toCompletionItem(version.toString(), null, request.getReplaceRange())) - .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) - .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); - } - // TODO localRepo - // TODO remoteRepos - } else { - if (artifactId.isPresent()) { - plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion().stream() - .filter(gav -> gav.getArtifactId().equals(artifactId.get())) - .filter(gav -> !groupId.isPresent() || gav.getGroupId().equals(groupId.get())).findAny() - .map(Artifact::getVersion).map(DefaultArtifactVersion::new) - .map(version -> toCompletionItem(version.toString(), null, request.getReplaceRange())) - .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) - .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); + DOMElement grandParent = parent.getParentElement(); + boolean isPlugin = ParticipantUtils.isPlugin(parent); + boolean isParentDeclaration = ParticipantUtils.isParentDeclaration(parent); + Optional groupId = grandParent == null ? Optional.empty() + : grandParent.getChildren().stream().filter(DOMNode::isElement) + .filter(node -> GROUP_ID_ELT.equals(node.getLocalName())) + .flatMap(node -> node.getChildren().stream()).map(DOMNode::getTextContent) + .filter(Objects::nonNull).map(String::trim).filter(s -> !s.isEmpty()).findFirst(); + Optional artifactId = grandParent == null ? Optional.empty() + : grandParent.getChildren().stream().filter(DOMNode::isElement) + .filter(node -> ARTIFACT_ID_ELT.equals(node.getLocalName())) + .flatMap(node -> node.getChildren().stream()).map(DOMNode::getTextContent) + .filter(Objects::nonNull).map(String::trim).filter(s -> !s.isEmpty()).findFirst(); + GAVInsertionStrategy gavInsertionStrategy = computeGAVInsertionStrategy(request); + List allArtifactInfos = Collections.synchronizedList(new ArrayList<>()); + LinkedHashMap nonArtifactCollector = new LinkedHashMap<>(); + switch (parent.getLocalName()) { + case SCOPE_ELT: + collectSimpleCompletionItems(Arrays.asList(DependencyScope.values()), DependencyScope::getName, + DependencyScope::getDescription, request).forEach(response::addCompletionAttribute); + break; + case PHASE_ELT: + collectSimpleCompletionItems(Arrays.asList(Phase.ALL_STANDARD_PHASES), phase -> phase.id, + phase -> phase.description, request).forEach(response::addCompletionAttribute); + break; + case GROUP_ID_ELT: + if (isParentDeclaration) { + Optional filesystem = computeFilesystemParent(request); + if (filesystem.isPresent()) { + filesystem.map(MavenProject::getGroupId) + .map(g -> toCompletionItem(g.toString(), null, request.getReplaceRange())) + .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) + .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); + } + // TODO localRepo + // TODO remoteRepos + } else { + // TODO if artifactId is set and match existing content, suggest only matching + // groupId + collectSimpleCompletionItems( + isPlugin ? plugin.getLocalRepositorySearcher().searchPluginGroupIds() + : plugin.getLocalRepositorySearcher().searchGroupIds(), + Function.identity(), Function.identity(), request).stream() + .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) + .forEach(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); internalCollectRemoteGAVCompletion(request, isPlugin, allArtifactInfos, nonArtifactCollector, cancelChecker); } - } - internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); - - if (nonArtifactCollector.isEmpty()) { - response.addCompletionItem(toTextCompletionItem(request, "-SNAPSHOT")); - } else { + internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); + // Sort and move nonArtifactCollector items to the response and clear nonArtifactCollector - final AtomicInteger sortIndex = new AtomicInteger(0); nonArtifactCollector.entrySet().stream() - .map(entry -> entry.getValue()) - .filter(Objects::nonNull) - .filter(item -> item.getSortText() != null || item.getLabel() != null) - .sorted(new Comparator() { - // Sort in reverse order to correctly fill 'sortText' - @Override - public int compare(CompletionItem o1, CompletionItem o2) { - String sortText1 = o1.getSortText() != null ? o1.getSortText() : o1.getLabel(); - String sortText2 = o2.getSortText() != null ? o2.getSortText() : o2.getLabel(); - return new DefaultArtifactVersion(sortText2) - .compareTo(new DefaultArtifactVersion(sortText1)); - } - }) - .peek(item -> item.setSortText(String.format("%06d", (sortIndex.getAndIncrement())) + '.' + item.getLabel())) - .forEach(response::addCompletionItem); + .map(entry -> entry.getValue()).forEach(response::addCompletionItem); nonArtifactCollector.clear(); - } - break; - case MODULE_ELT: - collectSubModuleCompletion(request).forEach(response::addCompletionItem); - break; - case TARGET_PATH_ELT: - case DIRECTORY_ELT: - case SOURCE_DIRECTORY_ELT: - case SCRIPT_SOURCE_DIRECTORY_ELT: - case TEST_SOURCE_DIRECTORY_ELT: - case OUTPUT_DIRECTORY_ELT: - case TEST_OUTPUT_DIRECTORY_ELT: - collectRelativeDirectoryPathCompletion(request).forEach(response::addCompletionItem); - break; - case FILTER_ELT: - if (FILTERS_ELT.equals(grandParent.getLocalName())) { - collectRelativeFilterPathCompletion(request).forEach(response::addCompletionItem); - } - break; - case EXISTS_ELT: - case MISSING_ELT: - if (FILE_ELT.equals(grandParent.getLocalName())) { - collectRelativeAnyPathCompletion(request).forEach(response::addCompletionItem); - } - break; - case RELATIVE_PATH_ELT: - collectRelativePathCompletion(request).forEach(response::addCompletionItem); - break; - case DEPENDENCIES_ELT: - case DEPENDENCY_ELT: - // TODO completion/resolve to get description for local artifacts - allArtifactInfos.addAll(plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion().stream() - .map(ArtifactWithDescription::new).collect(Collectors.toList())); - internalCollectRemoteGAVCompletion(request, false, allArtifactInfos, nonArtifactCollector, cancelChecker); - break; - case PLUGINS_ELT: - case PLUGIN_ELT: - // TODO completion/resolve to get description for local artifacts - allArtifactInfos.addAll(plugin.getLocalRepositorySearcher().getLocalPluginArtifacts().stream() - .map(ArtifactWithDescription::new).collect(Collectors.toList())); - internalCollectRemoteGAVCompletion(request, true, allArtifactInfos, nonArtifactCollector, cancelChecker); - break; - case PARENT_ELT: - Optional filesystem = computeFilesystemParent(request); - if (filesystem.isPresent()) { - filesystem.map(ArtifactWithDescription::new).ifPresent(allArtifactInfos::add); - } else { - // TODO localRepo - // TODO remoteRepos - } - break; - case GOAL_ELT: - collectGoals(request).forEach(response::addCompletionItem); - break; - case PACKAGING_ELT: - collectPackaging(request).forEach(response::addCompletionItem); - break; - default: - Set parameters = MavenPluginUtils.collectPluginConfigurationMojoParameters(request, plugin) - .stream().filter(p -> p.name.equals(parent.getLocalName())) - .filter(p -> (p.type.startsWith(FILE_TYPE)) || - (p.type.startsWith(STRING_TYPE) && p.name.toLowerCase().endsWith(DIRECTORY_STRING_LC))) - .collect(Collectors.toSet()); - if (parameters != null && parameters.size() > 0) { - collectMojoParametersDefaultCompletion(request, parameters) - .forEach(response::addCompletionItem); - if (parameters.stream() - .anyMatch(p -> !p.name.toLowerCase().endsWith(DIRECTORY_STRING_LC))) { - // Show all files + break; + case ARTIFACT_ID_ELT: + if (isParentDeclaration) { + Optional filesystem = computeFilesystemParent(request); + if (filesystem.isPresent()) { + filesystem.map(ArtifactWithDescription::new).ifPresent(allArtifactInfos::add); + } + // TODO localRepo + // TODO remoteRepos + } else { + allArtifactInfos.addAll((isPlugin ? plugin.getLocalRepositorySearcher().getLocalPluginArtifacts() + : plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion()).stream() + .filter(gav -> !groupId.isPresent() || gav.getGroupId().equals(groupId.get())) + // TODO pass description as documentation + .map(ArtifactWithDescription::new).collect(Collectors.toList())); + internalCollectRemoteGAVCompletion(request, isPlugin, allArtifactInfos, nonArtifactCollector, cancelChecker); + } + internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); + break; + case VERSION_ELT: + if (isParentDeclaration) { + Optional filesystem = computeFilesystemParent(request); + if (filesystem.isPresent()) { + filesystem.map(MavenProject::getVersion).map(DefaultArtifactVersion::new) + .map(version -> toCompletionItem(version.toString(), null, request.getReplaceRange())) + .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) + .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); + } + // TODO localRepo + // TODO remoteRepos + } else { + if (artifactId.isPresent()) { + plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion().stream() + .filter(gav -> gav.getArtifactId().equals(artifactId.get())) + .filter(gav -> !groupId.isPresent() || gav.getGroupId().equals(groupId.get())).findAny() + .map(Artifact::getVersion).map(DefaultArtifactVersion::new) + .map(version -> toCompletionItem(version.toString(), null, request.getReplaceRange())) + .filter(completionItem -> !nonArtifactCollector.containsKey(completionItem.getLabel())) + .ifPresent(completionItem -> nonArtifactCollector.put(completionItem.getLabel(), completionItem)); + internalCollectRemoteGAVCompletion(request, isPlugin, allArtifactInfos, nonArtifactCollector, cancelChecker); + } + } + internalCollectWorkspaceArtifacts(request, allArtifactInfos, nonArtifactCollector, groupId, artifactId); + + if (nonArtifactCollector.isEmpty()) { + response.addCompletionItem(toTextCompletionItem(request, "-SNAPSHOT")); + } else { + // Sort and move nonArtifactCollector items to the response and clear nonArtifactCollector + final AtomicInteger sortIndex = new AtomicInteger(0); + nonArtifactCollector.entrySet().stream() + .map(entry -> entry.getValue()) + .filter(Objects::nonNull) + .filter(item -> item.getSortText() != null || item.getLabel() != null) + .sorted(new Comparator() { + // Sort in reverse order to correctly fill 'sortText' + @Override + public int compare(CompletionItem o1, CompletionItem o2) { + String sortText1 = o1.getSortText() != null ? o1.getSortText() : o1.getLabel(); + String sortText2 = o2.getSortText() != null ? o2.getSortText() : o2.getLabel(); + return new DefaultArtifactVersion(sortText2) + .compareTo(new DefaultArtifactVersion(sortText1)); + } + }) + .peek(item -> item.setSortText(String.format("%06d", (sortIndex.getAndIncrement())) + '.' + item.getLabel())) + .forEach(response::addCompletionItem); + nonArtifactCollector.clear(); + } + break; + case MODULE_ELT: + collectSubModuleCompletion(request).forEach(response::addCompletionItem); + break; + case TARGET_PATH_ELT: + case DIRECTORY_ELT: + case SOURCE_DIRECTORY_ELT: + case SCRIPT_SOURCE_DIRECTORY_ELT: + case TEST_SOURCE_DIRECTORY_ELT: + case OUTPUT_DIRECTORY_ELT: + case TEST_OUTPUT_DIRECTORY_ELT: + collectRelativeDirectoryPathCompletion(request).forEach(response::addCompletionItem); + break; + case FILTER_ELT: + if (FILTERS_ELT.equals(grandParent.getLocalName())) { + collectRelativeFilterPathCompletion(request).forEach(response::addCompletionItem); + } + break; + case EXISTS_ELT: + case MISSING_ELT: + if (FILE_ELT.equals(grandParent.getLocalName())) { collectRelativeAnyPathCompletion(request).forEach(response::addCompletionItem); + } + break; + case RELATIVE_PATH_ELT: + collectRelativePathCompletion(request).forEach(response::addCompletionItem); + break; + case DEPENDENCIES_ELT: + case DEPENDENCY_ELT: + // TODO completion/resolve to get description for local artifacts + allArtifactInfos.addAll(plugin.getLocalRepositorySearcher().getLocalArtifactsLastVersion().stream() + .map(ArtifactWithDescription::new).collect(Collectors.toList())); + internalCollectRemoteGAVCompletion(request, false, allArtifactInfos, nonArtifactCollector, cancelChecker); + break; + case PLUGINS_ELT: + case PLUGIN_ELT: + // TODO completion/resolve to get description for local artifacts + allArtifactInfos.addAll(plugin.getLocalRepositorySearcher().getLocalPluginArtifacts().stream() + .map(ArtifactWithDescription::new).collect(Collectors.toList())); + internalCollectRemoteGAVCompletion(request, true, allArtifactInfos, nonArtifactCollector, cancelChecker); + break; + case PARENT_ELT: + Optional filesystem = computeFilesystemParent(request); + if (filesystem.isPresent()) { + filesystem.map(ArtifactWithDescription::new).ifPresent(allArtifactInfos::add); } else { - // Show only directories - collectRelativeDirectoryPathCompletion(request).forEach(response::addCompletionItem); + // TODO localRepo + // TODO remoteRepos } - } - } - if (!allArtifactInfos.isEmpty()) { - Comparator artifactInfoComparator = Comparator - .comparing(artifact -> new DefaultArtifactVersion(artifact.artifact.getVersion())); - final Comparator highestVersionWithDescriptionComparator = artifactInfoComparator - .thenComparing( - artifactInfo -> artifactInfo.description != null ? artifactInfo.description : ""); - allArtifactInfos.stream() - .collect(Collectors.groupingBy(artifact -> artifact.artifact.getGroupId() + ":" + artifact.artifact.getArtifactId())) - .values().stream() - .map(artifacts -> Collections.max(artifacts, highestVersionWithDescriptionComparator)) - .map(artifactInfo -> toGAVCompletionItem(artifactInfo, request, gavInsertionStrategy)) - .filter(completionItem -> !response.hasAttribute(completionItem.getLabel())) + break; + case GOAL_ELT: + collectGoals(request).forEach(response::addCompletionItem); + break; + case PACKAGING_ELT: + collectPackaging(request).forEach(response::addCompletionItem); + break; + default: + Set parameters = MavenPluginUtils.collectPluginConfigurationMojoParameters(request, plugin) + .stream().filter(p -> p.name.equals(parent.getLocalName())) + .filter(p -> (p.type.startsWith(FILE_TYPE)) || + (p.type.startsWith(STRING_TYPE) && p.name.toLowerCase().endsWith(DIRECTORY_STRING_LC))) + .collect(Collectors.toSet()); + if (parameters != null && parameters.size() > 0) { + collectMojoParametersDefaultCompletion(request, parameters) .forEach(response::addCompletionItem); - } - if (request.getNode().isText()) { - completeProperties(request).forEach(response::addCompletionAttribute); + if (parameters.stream() + .anyMatch(p -> !p.name.toLowerCase().endsWith(DIRECTORY_STRING_LC))) { + // Show all files + collectRelativeAnyPathCompletion(request).forEach(response::addCompletionItem); + } else { + // Show only directories + collectRelativeDirectoryPathCompletion(request).forEach(response::addCompletionItem); + } + } + } + if (!allArtifactInfos.isEmpty()) { + Comparator artifactInfoComparator = Comparator + .comparing(artifact -> new DefaultArtifactVersion(artifact.artifact.getVersion())); + final Comparator highestVersionWithDescriptionComparator = artifactInfoComparator + .thenComparing( + artifactInfo -> artifactInfo.description != null ? artifactInfo.description : ""); + allArtifactInfos.stream() + .collect(Collectors.groupingBy(artifact -> artifact.artifact.getGroupId() + ":" + artifact.artifact.getArtifactId())) + .values().stream() + .map(artifacts -> Collections.max(artifacts, highestVersionWithDescriptionComparator)) + .map(artifactInfo -> toGAVCompletionItem(artifactInfo, request, gavInsertionStrategy)) + .filter(completionItem -> !response.hasAttribute(completionItem.getLabel())) + .forEach(response::addCompletionItem); + } + if (request.getNode().isText()) { + completeProperties(request).forEach(response::addCompletionAttribute); + } + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML completion from LemMinX } } 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 cc5e7c96..1e9f1b91 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 @@ -31,6 +31,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.DOMNode; +import org.eclipse.lemminx.extensions.maven.MavenInitializationException; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; import org.eclipse.lemminx.extensions.maven.utils.ParticipantUtils; @@ -176,8 +177,8 @@ public void findDefinition(IDefinitionRequest request, List locati return; } } - } catch (CancellationException e) { - LOGGER.log(Level.FINER, e.toString(), e); + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML definition from LemMinX } } diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MavenDiagnosticParticipant.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MavenDiagnosticParticipant.java index 8429ef41..f24b8bab 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MavenDiagnosticParticipant.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MavenDiagnosticParticipant.java @@ -31,6 +31,7 @@ import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; +import org.eclipse.lemminx.extensions.maven.MavenInitializationException; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.services.extensions.diagnostics.IDiagnosticsParticipant; import org.eclipse.lsp4j.Diagnostic; @@ -54,50 +55,54 @@ public void doDiagnostics(DOMDocument xmlDocument, List diagnostics, return; } - Collection problems = plugin.getProjectCache().getProblemsFor(xmlDocument); - if (problems != null) { - problems.stream().map(this::toDiagnostic).forEach(diagnostics::add); - } - - cancelChecker.checkCanceled(); - DOMElement documentElement = xmlDocument.getDocumentElement(); - if (documentElement == null) { - return; - } - Map>>> tagDiagnostics = configureDiagnosticFunctions(cancelChecker); - - // Validate project element - cancelChecker.checkCanceled(); - if (PROJECT_ELT.equals(documentElement.getNodeName())) { - ProjectValidator projectValidator = new ProjectValidator(plugin, cancelChecker); - projectValidator.validateProject(new DiagnosticRequest(documentElement, xmlDocument)) - .ifPresent(diagnosticList ->{ - cancelChecker.checkCanceled(); - diagnostics.addAll(diagnosticList.stream() - .filter(diagnostic -> !diagnostics.contains(diagnostic)).collect(Collectors.toList())); - }); - } - - cancelChecker.checkCanceled(); - Deque nodes = new ArrayDeque<>(); - documentElement.getChildren().stream().filter(DOMElement.class::isInstance).forEach(nodes::push); - while (!nodes.isEmpty()) { + try { + Collection problems = plugin.getProjectCache().getProblemsFor(xmlDocument); + if (problems != null) { + problems.stream().map(this::toDiagnostic).forEach(diagnostics::add); + } + + cancelChecker.checkCanceled(); + DOMElement documentElement = xmlDocument.getDocumentElement(); + if (documentElement == null) { + return; + } + Map>>> tagDiagnostics = configureDiagnosticFunctions(cancelChecker); + + // Validate project element cancelChecker.checkCanceled(); - DOMNode node = nodes.pop(); - String nodeName = node.getLocalName(); - if (nodeName != null) { - tagDiagnostics.entrySet().stream().filter(entry -> nodeName.equals(entry.getKey())) - .map(entry -> entry.getValue().apply(new DiagnosticRequest(node, xmlDocument))) - .filter(Optional::isPresent).map(dl -> dl.get()).forEach(diagnosticList -> { - cancelChecker.checkCanceled(); - diagnostics.addAll(diagnosticList.stream() + if (PROJECT_ELT.equals(documentElement.getNodeName())) { + ProjectValidator projectValidator = new ProjectValidator(plugin, cancelChecker); + projectValidator.validateProject(new DiagnosticRequest(documentElement, xmlDocument)) + .ifPresent(diagnosticList ->{ + cancelChecker.checkCanceled(); + diagnostics.addAll(diagnosticList.stream() .filter(diagnostic -> !diagnostics.contains(diagnostic)).collect(Collectors.toList())); - });; + }); } + cancelChecker.checkCanceled(); - if (node.hasChildNodes()) { - node.getChildren().stream().filter(DOMElement.class::isInstance).forEach(nodes::push); + Deque nodes = new ArrayDeque<>(); + documentElement.getChildren().stream().filter(DOMElement.class::isInstance).forEach(nodes::push); + while (!nodes.isEmpty()) { + cancelChecker.checkCanceled(); + DOMNode node = nodes.pop(); + String nodeName = node.getLocalName(); + if (nodeName != null) { + tagDiagnostics.entrySet().stream().filter(entry -> nodeName.equals(entry.getKey())) + .map(entry -> entry.getValue().apply(new DiagnosticRequest(node, xmlDocument))) + .filter(Optional::isPresent).map(dl -> dl.get()).forEach(diagnosticList -> { + cancelChecker.checkCanceled(); + diagnostics.addAll(diagnosticList.stream() + .filter(diagnostic -> !diagnostics.contains(diagnostic)).collect(Collectors.toList())); + });; + } + cancelChecker.checkCanceled(); + if (node.hasChildNodes()) { + node.getChildren().stream().filter(DOMElement.class::isInstance).forEach(nodes::push); + } } + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML diagnostics from LemMinX } } 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 2a07ab9f..accdb776 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 @@ -53,6 +53,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.DOMNode; +import org.eclipse.lemminx.extensions.maven.MavenInitializationException; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.MojoParameter; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -90,8 +91,8 @@ public Hover onTag(IHoverRequest request, CancelChecker cancelChecker) throws Ex if (DOMUtils.isADescendantOf(request.getNode(), CONFIGURATION_ELT)) { return collectPluginConfiguration(request, cancelChecker); } - } catch (CancellationException e) { - LOGGER.log(Level.FINER, e.toString(), e); + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML hover from LemMinX } return null; } @@ -154,8 +155,8 @@ yield hoverForProject(request, // TODO consider incomplete GAV (eg plugins), by querying the "key" against project default -> null; }; - } catch (CancellationException e) { - LOGGER.log(Level.FINER, e.toString(), e); + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML hover from LemMinX } return null; } @@ -444,7 +445,7 @@ private Hover collectArtifactDescription(IHoverRequest request, CancelChecker ca } } catch (CancellationException e) { // Log at FINER level and return null - LOGGER.log(Level.FINER, e.toString(), e); + throw e; } catch (Exception e1) { LOGGER.log(Level.SEVERE, e1.toString(), e1); } diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipant.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipant.java index 0fe380ff..ead259a7 100644 --- a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipant.java +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipant.java @@ -29,6 +29,7 @@ import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.dom.DOMText; +import org.eclipse.lemminx.extensions.maven.MavenInitializationException; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; import org.eclipse.lemminx.extensions.maven.utils.ParticipantUtils; @@ -59,111 +60,121 @@ public MavenPropertyRenameParticipant(MavenLemminxExtension plugin) { @Override public Either prepareRename(IPrepareRenameRequest request, CancelChecker cancelChecker) { - DOMDocument document = request.getXMLDocument(); - DOMNode node = request.getNode(); - int offset = request.getOffset(); - - String propertyName = null; - Range propertyRange = null; - if (node instanceof DOMText textNode) { - Map.Entry mavenProperty = getMavenProperty(textNode, offset); - if (mavenProperty != null) { - cancelChecker.checkCanceled(); - propertyName = mavenProperty.getValue(); - propertyRange = mavenProperty.getKey(); + try { + DOMDocument document = request.getXMLDocument(); + DOMNode node = request.getNode(); + int offset = request.getOffset(); + + String propertyName = null; + Range propertyRange = null; + if (node instanceof DOMText textNode) { + Map.Entry mavenProperty = getMavenProperty(textNode, offset); + if (mavenProperty != null) { + cancelChecker.checkCanceled(); + propertyName = mavenProperty.getValue(); + propertyRange = mavenProperty.getKey(); + } + } else if (node instanceof DOMElement element) { + Range range = getMavenPropertyDefinitionRange(offset, element); + if (range != null) { + cancelChecker.checkCanceled(); + propertyName = element.getNodeName(); + propertyRange =range; + } } - } else if (node instanceof DOMElement element) { - Range range = getMavenPropertyDefinitionRange(offset, element); - if (range != null) { - cancelChecker.checkCanceled(); - propertyName = element.getNodeName(); - propertyRange =range; + + if (propertyName == null || propertyRange == null) { + return null; } - } - - if (propertyName == null || propertyRange == null) { + + // Check Maven property + cancelChecker.checkCanceled(); + MavenProject project = plugin.getProjectCache().getLastSuccessfulMavenProject(document); + + cancelChecker.checkCanceled(); + Map properties = ParticipantUtils.getMavenProjectProperties(project); + + cancelChecker.checkCanceled(); + return properties.get(propertyName) == null ? null : Either.forLeft(propertyRange); + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML prepare rename from LemMinX return null; } - - // Check Maven property - cancelChecker.checkCanceled(); - MavenProject project = plugin.getProjectCache().getLastSuccessfulMavenProject(document); - - cancelChecker.checkCanceled(); - Map properties = ParticipantUtils.getMavenProjectProperties(project); - - cancelChecker.checkCanceled(); - return properties.get(propertyName) == null ? null : Either.forLeft(propertyRange); } @Override public void doRename(IRenameRequest request, IRenameResponse renameResponse, CancelChecker cancelChecker) { - DOMDocument document = request.getXMLDocument(); - DOMNode node = request.getNode(); - int offset = request.getOffset(); - String newPropertyName = request.getNewText(); - - String propertyName = null; - if (node instanceof DOMText textNode) { - Map.Entry mavenProperty = getMavenProperty(textNode, offset); - if (mavenProperty != null) { - cancelChecker.checkCanceled(); - propertyName = mavenProperty.getValue(); + try { + DOMDocument document = request.getXMLDocument(); + DOMNode node = request.getNode(); + int offset = request.getOffset(); + String newPropertyName = request.getNewText(); + + String propertyName = null; + if (node instanceof DOMText textNode) { + Map.Entry mavenProperty = getMavenProperty(textNode, offset); + if (mavenProperty != null) { + cancelChecker.checkCanceled(); + propertyName = mavenProperty.getValue(); + } + } else if (node instanceof DOMElement element) { + Range range = getMavenPropertyDefinitionRange(offset, element); + if (range != null) { + cancelChecker.checkCanceled(); + propertyName = element.getNodeName(); + } } - } else if (node instanceof DOMElement element) { - Range range = getMavenPropertyDefinitionRange(offset, element); - if (range != null) { - cancelChecker.checkCanceled(); - propertyName = element.getNodeName(); + + if (propertyName == null) { + return; } - } - - if (propertyName == null) { - return; - } - - // Check Maven property - cancelChecker.checkCanceled(); - MavenProject thisProject = plugin.getProjectCache().getLastSuccessfulMavenProject(document); - if (thisProject == null) { - return; - } - - cancelChecker.checkCanceled(); - Map properties = ParticipantUtils.getMavenProjectProperties(thisProject); - if (properties.get(propertyName) == null) { - return; - } - - cancelChecker.checkCanceled(); - LinkedHashSet projects = new LinkedHashSet<>(); - projects.add(thisProject); - plugin.getCurrentWorkspaceProjects().stream().forEach(child -> - projects.addAll(findParentsOfChildProject(thisProject, child))); - - URI thisProjectUri = ParticipantUtils.normalizedUri(document.getDocumentURI()); - final String oldPropertyName = propertyName; - projects.stream().forEach(project -> { + + // Check Maven property cancelChecker.checkCanceled(); - URI projectUri = ParticipantUtils.normalizedUri(project.getFile().toURI().toString()); - DOMDocument projectDocumentt = null; - if (projectUri.equals(thisProjectUri)) { - projectDocumentt = document; - } else { - projectDocumentt = org.eclipse.lemminx.utils.DOMUtils.loadDocument( - project.getFile().toURI().toString(), - request.getNode().getOwnerDocument().getResolverExtensionManager()); + MavenProject thisProject = plugin.getProjectCache().getLastSuccessfulMavenProject(document); + if (thisProject == null) { + return; } - + cancelChecker.checkCanceled(); - // Collect Text Edits for the document - List projectTextEdits = new ArrayList<>(); - collectPropertyElementTextEdits(projectDocumentt, oldPropertyName, newPropertyName, projectTextEdits, cancelChecker); - collectPropertyUseTextEdits(projectDocumentt.getDocumentElement(), oldPropertyName, newPropertyName, projectTextEdits, cancelChecker); - VersionedTextDocumentIdentifier projectVersionedTextDocumentIdentifier = new VersionedTextDocumentIdentifier( - projectDocumentt.getTextDocument().getUri(), projectDocumentt.getTextDocument().getVersion()); - renameResponse.addTextDocumentEdit(new TextDocumentEdit(projectVersionedTextDocumentIdentifier, projectTextEdits)); - }); + Map properties = ParticipantUtils.getMavenProjectProperties(thisProject); + if (properties.get(propertyName) == null) { + return; + } + + cancelChecker.checkCanceled(); + LinkedHashSet projects = new LinkedHashSet<>(); + projects.add(thisProject); + plugin.getCurrentWorkspaceProjects().stream().forEach(child -> + projects.addAll(findParentsOfChildProject(thisProject, child))); + + URI thisProjectUri = ParticipantUtils.normalizedUri(document.getDocumentURI()); + final String oldPropertyName = propertyName; + projects.stream().forEach(project -> { + cancelChecker.checkCanceled(); + URI projectUri = ParticipantUtils.normalizedUri(project.getFile().toURI().toString()); + DOMDocument projectDocumentt = null; + if (projectUri.equals(thisProjectUri)) { + projectDocumentt = document; + } else { + projectDocumentt = org.eclipse.lemminx.utils.DOMUtils.loadDocument( + project.getFile().toURI().toString(), + request.getNode().getOwnerDocument().getResolverExtensionManager()); + } + + cancelChecker.checkCanceled(); + // Collect Text Edits for the document + List projectTextEdits = new ArrayList<>(); + collectPropertyElementTextEdits(projectDocumentt, oldPropertyName, newPropertyName, projectTextEdits, cancelChecker); + collectPropertyUseTextEdits(projectDocumentt.getDocumentElement(), oldPropertyName, newPropertyName, projectTextEdits, cancelChecker); + VersionedTextDocumentIdentifier projectVersionedTextDocumentIdentifier = new VersionedTextDocumentIdentifier( + projectDocumentt.getTextDocument().getUri(), projectDocumentt.getTextDocument().getVersion()); + renameResponse.addTextDocumentEdit(new TextDocumentEdit(projectVersionedTextDocumentIdentifier, projectTextEdits)); + }); + } catch(MavenInitializationException e) { + // Maven is initializing, catch the error to avoid breaking XML rename from LemMinX + + } } /* diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMInputStream.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMInputStream.java new file mode 100644 index 00000000..e796288e --- /dev/null +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMInputStream.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.lemminx.extensions.maven.utils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.CancellationException; + +import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lsp4j.jsonrpc.CancelChecker; + +/** + * {@link InputStream} implementation whichuses the content of the + * {@link DOMDocument} and throws a {@link CancellationException} while the + * stream is reading as soon as the DOM document has the content which is + * updated (when user type something in the XML editor). + * + * @author azerr + * + */ +class DOMInputStream extends ByteArrayInputStream { + + private final CancelChecker cancelChecker; + + public DOMInputStream(DOMDocument document) { + super(document.getText().getBytes()); + this.cancelChecker = document.getCancelChecker(); + } + + @Override + public synchronized int read() { + checkCanceled(); + return super.read(); + } + + @Override + public int read(byte[] b) throws IOException { + checkCanceled(); + return super.read(b); + } + + @Override + public synchronized int read(byte[] b, int off, int len) { + checkCanceled(); + return super.read(b, off, len); + } + + @Override + public synchronized byte[] readAllBytes() { + checkCanceled(); + return super.readAllBytes(); + } + + @Override + public int readNBytes(byte[] b, int off, int len) { + checkCanceled(); + return super.readNBytes(b, off, len); + } + + @Override + public byte[] readNBytes(int len) throws IOException { + checkCanceled(); + return super.readNBytes(len); + } + + @Override + public synchronized void reset() { + checkCanceled(); + super.reset(); + } + + @Override + public void mark(int readAheadLimit) { + checkCanceled(); + super.mark(readAheadLimit); + } + + @Override + public void close() throws IOException { + checkCanceled(); + super.close(); + } + + @Override + public boolean markSupported() { + checkCanceled(); + return super.markSupported(); + } + + @Override + public synchronized long skip(long n) { + checkCanceled(); + return super.skip(n); + } + + @Override + public void skipNBytes(long n) throws IOException { + checkCanceled(); + super.skipNBytes(n); + } + + @Override + public synchronized long transferTo(OutputStream out) throws IOException { + checkCanceled(); + return super.transferTo(out); + } + + @Override + public synchronized int available() { + checkCanceled(); + return super.available(); + } + + private void checkCanceled() { + if (cancelChecker != null) { + cancelChecker.checkCanceled(); + } + } + +} diff --git a/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMModelSource.java b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMModelSource.java new file mode 100644 index 00000000..67ed4ccb --- /dev/null +++ b/lemminx-maven/src/main/java/org/eclipse/lemminx/extensions/maven/utils/DOMModelSource.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.lemminx.extensions.maven.utils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelSource; +import org.eclipse.lemminx.dom.DOMDocument; + +/** + * A Maven {@link ModelSource} implementation based on LemMinx + * {@link DOMDocument}. + * + * This class provides the capability to use the content of the DOM document and + * cancel the load of the Maven Project as soon as the DOM document has the + * content which is updated (when user type something in the XML editor). + * + * @author azerr + * + */ +public class DOMModelSource extends FileModelSource { + + private final DOMDocument document; + + public DOMModelSource(DOMDocument document) { + super(new File(URI.create(document.getDocumentURI()).normalize())); + this.document = document; + } + + @Override + public InputStream getInputStream() throws IOException { + return new DOMInputStream(document); + } +} 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 68edc9ce..6769f9de 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 @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.concurrent.CancellationException; import java.util.Map.Entry; import java.util.Optional; import java.util.logging.Level; @@ -179,6 +180,8 @@ public static Artifact findWorkspaceArtifact(MavenLemminxExtension plugin, IPosi if (result !=null) { return result.getArtifact(); } + } catch (CancellationException e) { + throw e; } catch (ArtifactResolutionException | ComponentLookupException e) { // can happen LOGGER.log(Level.FINEST, e.getMessage(), e); diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/InitMavenRequestTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/InitMavenRequestTest.java index 6aa95133..9dbf3503 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/InitMavenRequestTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/InitMavenRequestTest.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.util.Properties; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -32,6 +33,11 @@ public class InitMavenRequestTest { private static final String MAVEN_PROJECTBASEDIR_ENV_VARIABLE_NAME = "MAVEN_PROJECTBASEDIR"; private static final String HOME_ENV_VARIABLE_NAME = isWindows() ? "HOMEPATH" : "HOME"; + @BeforeAll + public static void setUp() { + MavenLemminxExtension.initializeMavenOnBackground = false; + } + @Test public void testUserSettingsWithSystemProperty() throws Exception { final File localSettingsFile = generateSettingsXml(TEST_DUMMY_PROPERTY_NAME); diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenLanguageService.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenLanguageService.java new file mode 100644 index 00000000..706a930b --- /dev/null +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenLanguageService.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 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 + *******************************************************************************/ +package org.eclipse.lemminx.extensions.maven; + +import org.eclipse.lemminx.services.XMLLanguageService; + +/** + * Extends {@link XMLLanguageService} to do the Maven initialization synchronously. + * + * @author Angelo ZERR + * + */ +public class MavenLanguageService extends XMLLanguageService{ + + public MavenLanguageService() { + MavenLemminxExtension.initializeMavenOnBackground = false; + } + +} diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenProjectCacheTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenProjectCacheTest.java index 3713eea5..480d6dce 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenProjectCacheTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/MavenProjectCacheTest.java @@ -47,6 +47,7 @@ public void testSimpleProjectIsParsed() throws Exception { String content = Files.readString(new File(uri).toPath(), StandardCharsets.UTF_8); DOMDocument doc = new DOMDocument(new TextDocument(content, uri.toString()), null); MavenLemminxExtension plugin = new MavenLemminxExtension(); + plugin.initializeMavenOnBackground = false; MavenProjectCache cache = plugin.getProjectCache(); MavenProject project = cache.getLastSuccessfulMavenProject(doc); assertNotNull(project); @@ -59,6 +60,7 @@ public void testOnBuildError_ResolveProjectFromDocumentBytes() throws Exception String content = Files.readString(pomFile.toPath(), StandardCharsets.UTF_8); DOMDocument doc = new DOMDocument(new TextDocument(content, uri.toString()), null); MavenLemminxExtension plugin = new MavenLemminxExtension(); + plugin.initializeMavenOnBackground = false; MavenProjectCache cache = plugin.getProjectCache(); MavenProject project = cache.getLastSuccessfulMavenProject(doc); assertNotNull(project); @@ -68,6 +70,7 @@ public void testOnBuildError_ResolveProjectFromDocumentBytes() throws Exception public void testParentChangeReflectedToChild() throws IOException, InterruptedException, ExecutionException, URISyntaxException, Exception { MavenLemminxExtension plugin = new MavenLemminxExtension(); + plugin.initializeMavenOnBackground = false; MavenProjectCache cache = plugin.getProjectCache(); DOMDocument doc = getDocument("/pom-with-properties-in-parent.xml"); MavenProject project = cache.getLastSuccessfulMavenProject(doc); @@ -89,7 +92,7 @@ public void testParentChangeReflectedToChild() @Test public void testAddFolders_didChangeWorkspaceFolders() throws Exception { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); IWorkspaceServiceParticipant workspaceService = languageService.getWorkspaceServiceParticipants().stream().filter(MavenWorkspaceService.class::isInstance).findAny().get(); assertNotNull(workspaceService); @@ -114,7 +117,7 @@ public void testAddFolders_didChangeWorkspaceFolders() throws Exception { // @Test public void testRemoveFolders_didChangeWorkspaceFolders() throws Exception { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); IWorkspaceServiceParticipant workspaceService = languageService.getWorkspaceServiceParticipants().stream().filter(MavenWorkspaceService.class::isInstance).findAny().get(); assertNotNull(workspaceService); @@ -148,6 +151,7 @@ public void testRemoveFolders_didChangeWorkspaceFolders() throws Exception { public void testNormilizePathsAreUsedInCache() throws IOException, InterruptedException, ExecutionException, URISyntaxException, Exception { MavenLemminxExtension plugin = new MavenLemminxExtension(); + plugin.initializeMavenOnBackground = false; MavenProjectCache cache = plugin.getProjectCache(); int initialProjectsSize = cache.getProjects().size(); 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 83514100..a5b01410 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 @@ -24,6 +24,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -62,7 +63,7 @@ private SharedSettings getMarkdownSharedSettings () { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalRepoTests.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalRepoTests.java index 3067c458..fb2cc479 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalRepoTests.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/LocalRepoTests.java @@ -15,6 +15,7 @@ import java.net.URISyntaxException; import java.util.concurrent.ExecutionException; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -35,7 +36,7 @@ public class LocalRepoTests { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/PluginResolutionTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/PluginResolutionTest.java index 0da927e4..cf9bd54c 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/PluginResolutionTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/PluginResolutionTest.java @@ -25,6 +25,7 @@ import org.apache.maven.shared.utils.io.FileUtils; import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.participants.diagnostics.MavenDiagnosticParticipant; @@ -51,7 +52,7 @@ public class PluginResolutionTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); languageService.initializeIfNeeded(); File mavenRepo = languageService.getExtensions().stream() // .filter(MavenLemminxExtension.class::isInstance) // diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/SimpleModelTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/SimpleModelTest.java index bcd3335a..eefe784b 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/SimpleModelTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/SimpleModelTest.java @@ -33,6 +33,7 @@ import org.eclipse.lemminx.dom.DOMNode; import org.eclipse.lemminx.dom.DOMParser; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenWorkspaceService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -69,7 +70,7 @@ public class SimpleModelTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); MavenLemminxTestsUtils.prefetchMavenXSD(); } diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionParticipantTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionParticipantTest.java index 264249d5..ebdda0b0 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionParticipantTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionParticipantTest.java @@ -12,11 +12,9 @@ import static org.eclipse.lemminx.XMLAssert.ca; import static org.eclipse.lemminx.XMLAssert.d; import static org.eclipse.lemminx.XMLAssert.teOp; - import static org.eclipse.lemminx.extensions.maven.participants.codeaction.MavenNoGrammarConstraintsCodeAction.XSI_VALUE_PATTERN; import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import static org.eclipse.lemminx.extensions.maven.utils.ParticipantUtils.getDocumentLineSeparator; - import static org.junit.jupiter.api.Assertions.assertIterableEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -37,6 +35,8 @@ import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSyntaxErrorCode; import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationRootSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; +import org.eclipse.lemminx.extensions.maven.MavenSyntaxErrorCode; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -53,13 +53,11 @@ import com.google.gson.Gson; -import org.eclipse.lemminx.extensions.maven.MavenSyntaxErrorCode; - @ExtendWith(NoMavenCentralExtension.class) public class MavenCodeActionParticipantTest { private static final String POM_FILE = "file:///pom.xml"; - private XMLLanguageService xmlLanguageService = new XMLLanguageService(); + private XMLLanguageService xmlLanguageService = new MavenLanguageService(); private SharedSettings sharedSettings = new SharedSettings(); // EDITOR_HINT_MISSING_SCHEMA == NoGrammarConstraints @@ -319,7 +317,7 @@ public static List testCodeActionsFor(String xml, Diagnostic diagnos assertNotNull(range, "Range cannot be null"); if (xmlLanguageService == null) { - xmlLanguageService = new XMLLanguageService(); + xmlLanguageService = new MavenLanguageService(); } ContentModelSettings cmSettings = new ContentModelSettings(); diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionPropertyRefactoringTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionPropertyRefactoringTest.java index ec257ddb..02927e0b 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionPropertyRefactoringTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/codeaction/MavenCodeActionPropertyRefactoringTest.java @@ -29,6 +29,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.dom.LineIndentInfo; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenWorkspaceService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -47,7 +48,7 @@ @ExtendWith(NoMavenCentralExtension.class) public class MavenCodeActionPropertyRefactoringTest { - private XMLLanguageService xmlLanguageService = new XMLLanguageService(); + private XMLLanguageService xmlLanguageService = new MavenLanguageService(); private SharedSettings sharedSettings = new SharedSettings(); // diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantDuplicationTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantDuplicationTest.java index b86c64ee..a06030f8 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantDuplicationTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantDuplicationTest.java @@ -29,6 +29,8 @@ import java.util.stream.Stream; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; + import org.eclipse.lemminx.extensions.maven.searcher.RemoteCentralRepositorySearcher; import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils; import org.eclipse.lemminx.services.XMLLanguageService; @@ -45,7 +47,7 @@ public class MavenCompletionParticipantDuplicationTest { @BeforeAll public static void setUp() throws IOException, URISyntaxException { RemoteCentralRepositorySearcher.disableCentralSearch = false; - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); // "Build" test project - instead of real build we'll // set up the local repository with a required test artifact diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantTest.java index b6cde144..2d5a74c7 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/MavenCompletionParticipantTest.java @@ -14,7 +14,9 @@ import java.util.Arrays; +import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -24,6 +26,11 @@ public class MavenCompletionParticipantTest { // We must use this System.lineSeparator() as line delimiter only for those cases, // where a text editor line doesn't have a line ending separator set private static String LINE_DELIMTER = System.lineSeparator(); + + @BeforeAll + public static void setUp() { + MavenLemminxExtension.initializeMavenOnBackground = false; + } @Test public void testOneExistingDependencyDependenciesCompletion() throws Exception { diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathWebResourcesTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathWebResourcesTest.java index 01f0a98b..9cc91b7f 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathWebResourcesTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathWebResourcesTest.java @@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -33,7 +34,7 @@ public class PathWebResourcesTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathsTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathsTest.java index e786b4ce..6009f029 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathsTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/PathsTest.java @@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -33,7 +34,7 @@ public class PathsTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/RemoteCentralRepoAssistanceTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/RemoteCentralRepoAssistanceTest.java index 0aa1215d..dd8e244e 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/RemoteCentralRepoAssistanceTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/completion/RemoteCentralRepoAssistanceTest.java @@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.searcher.RemoteCentralRepositorySearcher; import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils; import org.eclipse.lemminx.services.XMLLanguageService; @@ -40,7 +41,7 @@ static void setup() { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionCancellationTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionCancellationTest.java deleted file mode 100644 index ce8a804d..00000000 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionCancellationTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright (c) 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 - *******************************************************************************/ -package org.eclipse.lemminx.extensions.maven.participants.definition; - -import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import org.eclipse.lemminx.commons.BadLocationException; -import org.eclipse.lemminx.commons.TextDocument; -import org.eclipse.lemminx.dom.DOMDocument; -import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; -import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.CancelCheckerCallCounter; -import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.PhaseCancelChecker; -import org.eclipse.lemminx.services.XMLLanguageService; -import org.eclipse.lsp4j.LocationLink; -import org.eclipse.lsp4j.Position; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -@ExtendWith(NoMavenCentralExtension.class) -public class MavenDefinitionCancellationTest { - private XMLLanguageService languageService; - - @BeforeEach - public void setUp() throws IOException { - languageService = new XMLLanguageService(); - } - - @AfterEach - public void tearDown() throws InterruptedException, ExecutionException { - languageService.dispose(); - languageService = null; - } - - @Test - public void testDefinitionCancellationOnDependency() - throws BadLocationException, IOException, URISyntaxException { - DOMDocument document = createDOMDocument("/pom-localrepo-test-dependencies.xml", languageService); - String text = document.getText(); - // Will test an offset somewhere in the middle of the property name - int offset = text.indexOf("maven-compiler-plugin") - + "".length() + "maven-compiler-plugin".length() / 2; - TextDocument textDocument = document.getTextDocument(); - Position offsetPosition = textDocument.positionAt(offset); - - // Should return some hover - CancelCheckerCallCounter cancelCheckerCallCounter = new CancelCheckerCallCounter(); - List definitions = languageService.findDefinition(document, offsetPosition, cancelCheckerCallCounter); - assertNotNull(definitions, "Definition Participant returned a null result"); - assertTrue(definitions.size() > 0, "Definition Participant didn't return any Location Link"); - int numberOfChecks = cancelCheckerCallCounter.getCounterValue(); - assertTrue( (numberOfChecks > 0), "No cancellation checks performed during the processing"); - - // Should not return any hover - for (int i = 1; i <= numberOfChecks; i++) { - PhaseCancelChecker phaseChacker = new PhaseCancelChecker(i); - definitions = languageService.findDefinition(document, offsetPosition, phaseChacker); - assertNotNull(definitions, "Definition Participant returned a null result"); - assertTrue(definitions.size() == 0, "Definition Participant is not canceled at phase " + i); - } - } - - @Test - public void testDefinitionCancellationOnParent() - throws BadLocationException, IOException, URISyntaxException { - DOMDocument document = createDOMDocument("/parent-from-repo.pom", languageService); - String text = document.getText(); - // Will test an offset somewhere in the middle of the property name - int offset = text.indexOf("spring-boot-starter-parent") - + "".length() + "spring-boot-starter-parent".length() / 2; - TextDocument textDocument = document.getTextDocument(); - Position offsetPosition = textDocument.positionAt(offset); - - // Should return some hover - CancelCheckerCallCounter cancelCheckerCallCounter = new CancelCheckerCallCounter(); - List definitions = languageService.findDefinition(document, offsetPosition, cancelCheckerCallCounter); - assertNotNull(definitions, "Definition Participant returned a null result"); - assertTrue(definitions.size() > 0, "Definition Participant didn't return any Location Link"); - int numberOfChecks = cancelCheckerCallCounter.getCounterValue(); - assertTrue( (numberOfChecks > 0), "No cancellation checks performed during the processing"); - - // Should not return any hover - for (int i = 1; i <= numberOfChecks; i++) { - PhaseCancelChecker phaseChacker = new PhaseCancelChecker(i); - definitions = languageService.findDefinition(document, offsetPosition, phaseChacker); - assertNotNull(definitions, "Definition Participant returned a null result"); - assertTrue(definitions.size() == 0, "Definition Participant is not canceled at phase " + i); - } - } -} diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipantTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipantTest.java index 5c24e726..37ed16d1 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipantTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenDefinitionParticipantTest.java @@ -13,6 +13,7 @@ import java.util.List; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lsp4j.LocationLink; @@ -25,14 +26,14 @@ public class MavenDefinitionParticipantTest { @Test public void testFullyQualifiedDependency() throws Exception { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); List definitions = languageService.findDefinition(createDOMDocument("/pom-localrepo-test-dependencies.xml", languageService), new Position(14, 20), ()->{}); assertTrue(definitions.stream().map(LocationLink::getTargetUri).anyMatch(uri -> uri.endsWith("maven-compiler-plugin-3.8.1.pom"))); } @Test public void testDependencyWithVersionAsProperty() throws Exception { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); List definitions = languageService.findDefinition(createDOMDocument("/pom-localrepo-test-dependencies-propertyVersion.xml", languageService), new Position(17, 20), ()->{}); assertTrue(definitions.stream().map(LocationLink::getTargetUri).anyMatch(uri -> uri.endsWith("maven-compiler-plugin-3.8.1.pom")), definitions.toString()); } @@ -40,7 +41,7 @@ public void testDependencyWithVersionAsProperty() throws Exception { @Test public void testParentFromRepo() throws Exception { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); List definitions = languageService.findDefinition(createDOMDocument("/parent-from-repo.pom", languageService), new Position(6, 30), ()->{}); assertTrue(definitions.stream().map(LocationLink::getTargetUri).anyMatch(uri -> uri.endsWith("spring-boot-starter-parent-2.6.2.pom"))); } diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenHyperlinkDetectorParticipantTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenHyperlinkDetectorParticipantTest.java index 7a3e5805..8eae964d 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenHyperlinkDetectorParticipantTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/MavenHyperlinkDetectorParticipantTest.java @@ -14,6 +14,7 @@ import java.util.List; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lsp4j.LocationLink; import org.eclipse.lsp4j.Position; @@ -25,7 +26,7 @@ public class MavenHyperlinkDetectorParticipantTest { @Test public void testPluginManagementPluginFullyQualified() throws Exception { System.out.println("testPluginManagementFullyQualifiedPlugin()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); // System.out.println("testPluginManagementFullyQualifiedPlugin(): TEXT: " + document.getText()); List definitions = languageService.findDefinition(document, new Position(14, 32), ()->{}); @@ -37,7 +38,7 @@ public void testPluginManagementPluginFullyQualified() throws Exception { @Test public void testPluginManagementPluginWithVersionAsProperty() throws Exception { System.out.println("testPluginManagementPluginWithVersionAsProperty()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(19, 32), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginManagementPluginWithVersionAsProperty(): " + uri)); @@ -48,7 +49,7 @@ public void testPluginManagementPluginWithVersionAsProperty() throws Exception { @Test public void testPluginManagementPluginWithNoGroupId() throws Exception { System.out.println("testPluginManagementPluginWithNoGroupId()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(23, 32), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginManagementPluginWithNoGroupId(): " + uri)); @@ -59,7 +60,7 @@ public void testPluginManagementPluginWithNoGroupId() throws Exception { @Test public void testPluginFullyQualified() throws Exception { System.out.println("testPluginFullyQualified()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(31, 28), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginFullyQualified(): " + uri)); @@ -70,7 +71,7 @@ public void testPluginFullyQualified() throws Exception { @Test public void testPluginWithVersionAsProperty() throws Exception { System.out.println("testPluginWithVersionAsProperty()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(36, 28), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginWithVersionAsProperty(): " + uri)); @@ -81,7 +82,7 @@ public void testPluginWithVersionAsProperty() throws Exception { @Test public void testPluginWithNoGroupId() throws Exception { System.out.println("testPluginWithNoGroupId()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(40, 28), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginWithNoGroupId(): " + uri)); @@ -92,7 +93,7 @@ public void testPluginWithNoGroupId() throws Exception { @Test public void testPluginWithNoVersion() throws Exception { System.out.println("testPluginWithNoVersion()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(45, 28), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginWithNoVersion(): " + uri)); @@ -103,7 +104,7 @@ public void testPluginWithNoVersion() throws Exception { @Test public void testPluginWithNoGroupIdNoVersion() throws Exception { System.out.println("testPluginWithNoGroupIdNoVersion()"); - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument document = createDOMDocument("/pom-remote-test-plugin-hypertlink.xml", languageService); List definitions = languageService.findDefinition(document, new Position(48, 28), ()->{}); definitions.stream().map(LocationLink::getTargetUri).forEach(uri -> System.out.println("testPluginWithNoGroupIdNoVersion(): " + uri)); diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/WorkspaceProjectsHyperlinkDetectorTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/WorkspaceProjectsHyperlinkDetectorTest.java index 2aaed375..64ca7309 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/WorkspaceProjectsHyperlinkDetectorTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/definition/WorkspaceProjectsHyperlinkDetectorTest.java @@ -24,6 +24,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.extensions.maven.DOMConstants; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenWorkspaceService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -64,7 +65,7 @@ public class WorkspaceProjectsHyperlinkDetectorTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MatchTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MatchTest.java index 7bdeeb88..94940874 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MatchTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/diagnostics/MatchTest.java @@ -14,6 +14,7 @@ import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMParser; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager; @@ -26,7 +27,7 @@ public class MatchTest { @Test public void testDoesntFailNonHierarchicalURIs() { - XMLLanguageService languageService = new XMLLanguageService(); + XMLLanguageService languageService = new MavenLanguageService(); DOMDocument doc = DOMParser.getInstance().parse("blah", "untitled:Untitled-1", new URIResolverExtensionManager()); List doDiagnostics = languageService.doDiagnostics(doc, new XMLValidationSettings(), Map.of(), () -> { diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/DownloadArtifactsTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/DownloadArtifactsTest.java index 61f48951..59cfab45 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/DownloadArtifactsTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/DownloadArtifactsTest.java @@ -19,6 +19,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils; @@ -39,7 +40,7 @@ public class DownloadArtifactsTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach 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 2bcd2753..52029399 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 @@ -20,6 +20,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -41,7 +42,7 @@ class ManagedVersionHoverTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverCancellationTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverCancellationTest.java index 2e04932b..118c9418 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverCancellationTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverCancellationTest.java @@ -20,6 +20,7 @@ import org.eclipse.lemminx.commons.BadLocationException; import org.eclipse.lemminx.commons.TextDocument; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.CancelCheckerCallCounter; import org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.PhaseCancelChecker; @@ -38,7 +39,7 @@ public class MavenHoverCancellationTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipantVerionWithPropertyTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipantVerionWithPropertyTest.java index e63b852c..7601fad1 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipantVerionWithPropertyTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenHoverParticipantVerionWithPropertyTest.java @@ -16,6 +16,7 @@ import java.util.concurrent.ExecutionException; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.searcher.RemoteCentralRepositorySearcher; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lemminx.settings.SharedSettings; @@ -31,7 +32,7 @@ class MavenHoverParticipantVerionWithPropertyTest { @BeforeEach public void setUp() throws IOException { RemoteCentralRepositorySearcher.disableCentralSearch = false; - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenPropertyHoverTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenPropertyHoverTest.java index 4bbb5e54..59cce16b 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenPropertyHoverTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/MavenPropertyHoverTest.java @@ -8,9 +8,9 @@ *******************************************************************************/ package org.eclipse.lemminx.extensions.maven.participants.hover; -import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import static org.eclipse.lemminx.XMLAssert.assertHover; import static org.eclipse.lemminx.XMLAssert.r; +import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import java.io.File; import java.io.IOException; @@ -20,6 +20,7 @@ import org.eclipse.lemminx.commons.BadLocationException; import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.MarkdownUtils; import org.eclipse.lemminx.extensions.maven.utils.ParticipantUtils; @@ -37,7 +38,7 @@ public class MavenPropertyHoverTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/WorkspaceProjectsHoverTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/WorkspaceProjectsHoverTest.java index afa82a16..b8e8749f 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/WorkspaceProjectsHoverTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/hover/WorkspaceProjectsHoverTest.java @@ -8,11 +8,11 @@ *******************************************************************************/ package org.eclipse.lemminx.extensions.maven.participants.hover; +import static org.eclipse.lemminx.XMLAssert.assertHover; +import static org.eclipse.lemminx.XMLAssert.r; import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.eclipse.lemminx.XMLAssert.assertHover; -import static org.eclipse.lemminx.XMLAssert.r; import java.io.File; import java.io.IOException; @@ -27,6 +27,7 @@ import org.eclipse.lemminx.dom.DOMElement; import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings; import org.eclipse.lemminx.extensions.maven.DOMConstants; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenWorkspaceService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -70,7 +71,7 @@ public class WorkspaceProjectsHoverTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); localRepoDirectory = System.getProperty("maven.repo.local") != null ? new File(System.getProperty("maven.repo.local")).getAbsoluteFile() : diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipantTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipantTest.java index aa4a800b..1baf93e0 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipantTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/participants/rename/MavenPropertyRenameParticipantTest.java @@ -11,7 +11,6 @@ import static org.eclipse.lemminx.extensions.maven.DOMConstants.PROPERTIES_ELT; import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import static org.eclipse.lemminx.utils.TextEditUtils.creatTextDocumentEdit; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -28,6 +27,7 @@ import org.eclipse.lemminx.commons.TextDocument; import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMElement; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenWorkspaceService; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; import org.eclipse.lemminx.extensions.maven.utils.DOMUtils; @@ -47,7 +47,7 @@ @ExtendWith(NoMavenCentralExtension.class) public class MavenPropertyRenameParticipantTest { - private XMLLanguageService xmlLanguageService = new XMLLanguageService(); + private XMLLanguageService xmlLanguageService = new MavenLanguageService(); @Test public void testRenameMavenProperty() throws Exception { diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/MavenLemminxTestsUtils.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/MavenLemminxTestsUtils.java index f85afb92..ff35ec57 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/MavenLemminxTestsUtils.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/MavenLemminxTestsUtils.java @@ -17,11 +17,11 @@ import java.util.Arrays; import java.util.List; import java.util.Map.Entry; +import java.util.Properties; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.Properties; import org.eclipse.lemminx.commons.TextDocument; import org.eclipse.lemminx.dom.DOMDocument; diff --git a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtilsTest.java b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtilsTest.java index a63812f5..e61785c3 100644 --- a/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtilsTest.java +++ b/lemminx-maven/src/test/java/org/eclipse/lemminx/extensions/maven/utils/ParticipantUtilsTest.java @@ -8,8 +8,8 @@ *******************************************************************************/ package org.eclipse.lemminx.extensions.maven.utils; -import static org.eclipse.lemminx.extensions.maven.DOMConstants.GROUP_ID_ELT; import static org.eclipse.lemminx.extensions.maven.DOMConstants.DEPENDENCY_ELT; +import static org.eclipse.lemminx.extensions.maven.DOMConstants.GROUP_ID_ELT; import static org.eclipse.lemminx.extensions.maven.utils.MavenLemminxTestsUtils.createDOMDocument; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -26,6 +26,7 @@ import org.apache.maven.project.MavenProject; import org.eclipse.lemminx.dom.DOMDocument; import org.eclipse.lemminx.dom.DOMNode; +import org.eclipse.lemminx.extensions.maven.MavenLanguageService; import org.eclipse.lemminx.extensions.maven.MavenLemminxExtension; import org.eclipse.lemminx.extensions.maven.MavenProjectCache; import org.eclipse.lemminx.extensions.maven.NoMavenCentralExtension; @@ -41,7 +42,7 @@ public class ParticipantUtilsTest { @BeforeEach public void setUp() throws IOException { - languageService = new XMLLanguageService(); + languageService = new MavenLanguageService(); } @AfterEach