-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make the remove maven listener a process in the launch
Currently m2e uses an additional socket connection to receive project events from the remote maven project. This is not visible to the user and requires some internal maps to maintain state. This refactors this into a more generic event facility and make it visible as a Process in the debug view, this also has the advantage that the process itself can be used to maintain the state.
- Loading branch information
Showing
14 changed files
with
515 additions
and
245 deletions.
There are no files selected for viewing
Submodule m2e-core-tests
updated
24 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
....launching/src/org/eclipse/m2e/internal/launch/MavenBuildConnectionLaunchParticipant.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2022, 2024 Hannes Wellmann 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 | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Hannes Wellmann - initial API and implementation | ||
* Christoph Läubrich - refactor into {@link IMavenLaunchParticipant} | ||
********************************************************************************/ | ||
|
||
package org.eclipse.m2e.internal.launch; | ||
|
||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.eclipse.core.runtime.CoreException; | ||
import org.eclipse.core.runtime.IProgressMonitor; | ||
import org.eclipse.debug.core.DebugPlugin; | ||
import org.eclipse.debug.core.ILaunch; | ||
import org.eclipse.debug.core.ILaunchConfiguration; | ||
import org.eclipse.debug.core.ILaunchesListener2; | ||
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; | ||
|
||
import org.eclipse.m2e.core.internal.launch.MavenEmbeddedRuntime; | ||
import org.eclipse.m2e.internal.maven.listener.M2EMavenBuildDataBridge; | ||
|
||
|
||
public class MavenBuildConnectionLaunchParticipant implements IMavenLaunchParticipant { | ||
|
||
static { | ||
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(new ILaunchesListener2() { | ||
public void launchesRemoved(ILaunch[] launches) { | ||
ensureClosed(launches); | ||
} | ||
|
||
private void ensureClosed(ILaunch[] launches) { | ||
Arrays.stream(launches).flatMap(l -> MavenBuildConnectionProcess.get(l).stream()) | ||
.forEach(MavenBuildConnectionProcess::terminate); | ||
} | ||
|
||
public void launchesTerminated(ILaunch[] launches) { | ||
ensureClosed(launches); | ||
} | ||
|
||
public void launchesAdded(ILaunch[] launches) { // ignore | ||
} | ||
|
||
public void launchesChanged(ILaunch[] launches) { // ignore | ||
} | ||
}); | ||
} | ||
|
||
public String getProgramArguments(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) { | ||
try { | ||
if(MavenLaunchUtils.getMavenRuntime(launch.getLaunchConfiguration()) instanceof MavenEmbeddedRuntime) { | ||
|
||
MavenBuildConnectionProcess process = new MavenBuildConnectionProcess(launch); | ||
return M2EMavenBuildDataBridge.prepareConnection(launch.getLaunchConfiguration().getName(), process); | ||
} | ||
} catch(CoreException | IOException ex) { // ignore | ||
} | ||
return null; | ||
} | ||
|
||
public String getVMArguments(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) { | ||
return null; | ||
} | ||
|
||
public List<ISourceLookupParticipant> getSourceLookupParticipants(ILaunchConfiguration configuration, ILaunch launch, | ||
IProgressMonitor monitor) { | ||
return List.of(); | ||
} | ||
|
||
} |
155 changes: 155 additions & 0 deletions
155
...clipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenBuildConnectionProcess.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/******************************************************************************** | ||
* Copyright (c) 2024 Christoph Läubrich 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 | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Christoph Läubrich - initial API and implementation | ||
********************************************************************************/ | ||
|
||
package org.eclipse.m2e.internal.launch; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import org.eclipse.debug.core.DebugEvent; | ||
import org.eclipse.debug.core.DebugPlugin; | ||
import org.eclipse.debug.core.ILaunch; | ||
import org.eclipse.debug.core.model.IProcess; | ||
import org.eclipse.debug.core.model.IStreamsProxy; | ||
|
||
import org.eclipse.m2e.core.embedder.ArtifactKey; | ||
import org.eclipse.m2e.internal.maven.listener.MavenBuildConnection; | ||
import org.eclipse.m2e.internal.maven.listener.MavenBuildConnectionListener; | ||
import org.eclipse.m2e.internal.maven.listener.MavenProjectBuildData; | ||
|
||
|
||
/** | ||
* This is the representation of the MavenBuildConnection we use to communicate with the remote maven process. | ||
*/ | ||
public class MavenBuildConnectionProcess implements IProcess, MavenBuildConnectionListener { | ||
|
||
Map<ArtifactKey, CompletableFuture<MavenProjectBuildData>> projects = new ConcurrentHashMap<>(); | ||
|
||
private ILaunch launch; | ||
|
||
private MavenBuildConnection connection; | ||
|
||
private Map<String, String> attributes = new HashMap<>(); | ||
|
||
private AtomicBoolean terminated = new AtomicBoolean(); | ||
|
||
private String label; | ||
|
||
/** | ||
* @param launch | ||
*/ | ||
public MavenBuildConnectionProcess(ILaunch launch) { | ||
this.launch = launch; | ||
} | ||
|
||
public <T> T getAdapter(Class<T> adapter) { | ||
return null; | ||
} | ||
|
||
public boolean canTerminate() { | ||
return false; | ||
} | ||
|
||
public boolean isTerminated() { | ||
return connection != null && connection.isCompleted(); | ||
} | ||
|
||
public void terminate() { | ||
if(connection != null && terminated.compareAndSet(false, true)) { | ||
connection.close(); | ||
fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); | ||
for(CompletableFuture<MavenProjectBuildData> future : projects.values()) { | ||
future.cancel(true); | ||
} | ||
} | ||
} | ||
|
||
public String getLabel() { | ||
// TODO fetch the maven version from the remove process like mvn -V ... | ||
if(label != null) { | ||
return "Maven<" + label + ">"; | ||
} | ||
return "Maven"; | ||
} | ||
|
||
public ILaunch getLaunch() { | ||
return launch; | ||
} | ||
|
||
public IStreamsProxy getStreamsProxy() { | ||
return null; | ||
} | ||
|
||
public void setAttribute(String key, String value) { | ||
attributes.put(key, value); | ||
fireEvent(new DebugEvent(this, DebugEvent.CHANGE)); | ||
} | ||
|
||
public String getAttribute(String key) { | ||
return attributes.get(key); | ||
} | ||
|
||
public int getExitValue() { | ||
return 0; | ||
} | ||
|
||
private static void fireEvent(DebugEvent event) { | ||
DebugPlugin manager = DebugPlugin.getDefault(); | ||
if(manager != null) { | ||
manager.fireDebugEventSet(new DebugEvent[] {event}); | ||
} | ||
} | ||
|
||
public static Optional<MavenBuildConnectionProcess> get(ILaunch launch) { | ||
for(IProcess process : launch.getProcesses()) { | ||
if(process instanceof MavenBuildConnectionProcess p) { | ||
return Optional.of(p); | ||
} | ||
} | ||
return Optional.empty(); | ||
} | ||
|
||
/** | ||
* @param launch2 | ||
* @param groupId | ||
* @param artifactId | ||
* @param version | ||
* @return | ||
*/ | ||
public CompletableFuture<MavenProjectBuildData> getBuildProject(String groupId, String artifactId, String version) { | ||
return projects.computeIfAbsent(new ArtifactKey(groupId, artifactId, version, null), | ||
x -> new CompletableFuture<>()); | ||
} | ||
|
||
public void onOpen(String label, MavenBuildConnection connection) { | ||
this.label = label; | ||
this.connection = connection; | ||
getLaunch().addProcess(this); | ||
fireEvent(new DebugEvent(this, DebugEvent.CREATE)); | ||
|
||
} | ||
|
||
public void onClose() { | ||
terminate(); | ||
} | ||
|
||
public void onData(MavenProjectBuildData buildData) { | ||
projects.computeIfAbsent(new ArtifactKey(buildData.groupId, buildData.artifactId, buildData.version, null), x -> new CompletableFuture<>()) | ||
.complete(buildData); | ||
} | ||
|
||
} |
107 changes: 0 additions & 107 deletions
107
...se.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenBuildProjectDataConnection.java
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.