Skip to content

Commit

Permalink
Progress report notifications
Browse files Browse the repository at this point in the history
Fixes eclipse-jdtls#404

Signed-off-by: Fred Bricon <[email protected]>
  • Loading branch information
fbricon committed Mar 19, 2018
1 parent ddca6ba commit a0d10d2
Show file tree
Hide file tree
Showing 9 changed files with 450 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,21 @@
import org.eclipse.lsp4j.jsonrpc.CancelChecker;

/**
* Progress monitor wrapping a {@link CancelChecker}. Cancelling the
* CancelChecker will also cancel this monitor.
*
* @author Gorkem Ercan
*/
public class CancellableProgressMonitor extends NullProgressMonitor {

private final CancelChecker cancelChecker;
/**
*
*/

private boolean done;

public CancellableProgressMonitor(CancelChecker checker) {
this.cancelChecker = checker;
}

/* (non-Javadoc)
* @see org.eclipse.core.runtime.NullProgressMonitor#isCanceled()
*/
@Override
public boolean isCanceled() {
if (super.isCanceled()) {
Expand All @@ -46,4 +45,14 @@ public boolean isCanceled() {
}
return false;
}

@Override
public void done() {
super.done();
done = true;
}

public boolean isDone() {
return done;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2018 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal;

/**
* Holds commonly used constants in jdt.ls
*
* @author Fred Bricon
*/
public interface IConstants {

/**
* Plugin id
*/
public static final String PLUGIN_ID = "org.eclipse.jdt.ls.core";

/**
* Jobs family id
*/
public static final String JOBS_FAMILY = PLUGIN_ID + ".jobs";

/**
* Update project job family id
*/
public static final String UPDATE_PROJECT_FAMILY = JOBS_FAMILY + ".updateProject";

/**
* Update workspace folders job family id
*/
public static final String UPDATE_WORKSPACE_FOLDERS_FAMILY = JOBS_FAMILY + ".updateWorkspaceFolders";
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ public interface JavaLanguageClient extends LanguageClient {
void sendStatusReport(StatusReport report);

/**
* The actionable notification is sent from a server to a client to ask
* the client to display a particular message in the user interface, and possible
* The progress report notification is sent from a server to be handled by the
* client.
*/
@JsonNotification("language/progressReport")
void sendProgressReport(ProgressReport report);

/**
* The actionable notification is sent from a server to a client to ask the
* client to display a particular message in the user interface, and possible
* commands to execute. The commands must be implemented on the client side.
*/
@JsonNotification("language/actionableNotification")
Expand Down Expand Up @@ -107,9 +114,19 @@ public void sendStatus(ServiceStatus serverStatus, String status) {
client.sendStatusReport( $.withMessage(status).withType(serverStatus.name()));
}

/**
* Sends a progress report to the client to be presented to users
*
* @param progressReport
* The progress report to send back to the client
*/
public void sendProgressReport(ProgressReport progressReport) {
client.sendProgressReport(progressReport);
}

/**
* Sends a message to the client to be presented to users, with possible commands to execute
* Sends a message to the client to be presented to users, with possible
* commands to execute
*/
public void sendActionableNotification(MessageType severity, String message, Object data, List<Command> commands) {
ActionableNotification notification = new ActionableNotification().withSeverity(severity).withMessage(message).withData(data).withCommands(commands);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ public class JavaLanguageServerPlugin implements BundleActivator {
**/
public static final String SERVER_SOURCE_ID = "Java";

public static final String PLUGIN_ID = "org.eclipse.jdt.ls.core";
/**
* Use IConstants.PLUGIN_ID
*/
@Deprecated
public static final String PLUGIN_ID = IConstants.PLUGIN_ID;

private static JavaLanguageServerPlugin pluginInstance;
private static BundleContext context;
private ServiceTracker<IProxyService, IProxyService> proxyServiceTracker = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2017 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

/**
* Progress Report sent to clients.
*
* @author Fred Bricon
*/
public class ProgressReport {

@SerializedName("id")
@Expose
private String id;

@SerializedName("task")
@Expose
private String task;

@SerializedName("status")
@Expose
private String status;

@SerializedName("totalWork")
@Expose
private int totalWork;

@SerializedName("workDone")
@Expose
private int workDone;

@SerializedName("complete")
@Expose
private boolean complete;

public ProgressReport(String progressId) {
this.id = progressId;
}

/**
* @return the task
*/
public String getTask() {
return task;
}

/**
* @param task
* the task to set
*/
public void setTask(String task) {
this.task = task;
}

/**
* @return the status
*/
public String getStatus() {
return status;
}

/**
* @param status
* the status to set
*/
public void setStatus(String status) {
this.status = status;
}

/**
* @return the complete
*/
public boolean isComplete() {
return complete;
}

/**
* @param complete
* the complete to set
*/
public void setComplete(boolean complete) {
this.complete = complete;
}

/**
* @return the totalWork
*/
public int getTotalWork() {
return totalWork;
}

/**
* @param totalWork
* the totalWork to set
*/
public void setTotalWork(int totalWork) {
this.totalWork = totalWork;
}

/**
* @return the workDone
*/
public int getWorkDone() {
return workDone;
}

/**
* @param workDone
* the workDone to set
*/
public void setWorkDone(int workDone) {
this.workDone = workDone;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

Expand All @@ -27,7 +28,6 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
Expand Down Expand Up @@ -84,8 +84,8 @@ InitializeResult initialize(InitializeParams param) {
Map<?, ?> initializationOptions = this.getInitializationOptions(param);

Collection<IPath> rootPaths = new ArrayList<>();
Collection<String> workspaceFolders = getWorkspaceFolders(initializationOptions);
if (workspaceFolders != null && !workspaceFolders.isEmpty()) {
Collection<String> workspaceFolders = getInitializationOption(initializationOptions, "workspaceFolders");
if (!workspaceFolders.isEmpty()) {
for (String uri : workspaceFolders) {
IPath filePath = ResourceUtils.filePathFromURI(uri);
if (filePath != null) {
Expand Down Expand Up @@ -125,7 +125,7 @@ InitializeResult initialize(InitializeParams param) {
JavaLanguageServerPlugin.getLanguageServer().setParentProcessId(processId.longValue());
}
try {
Collection<String> bundleList = getBundleList(initializationOptions);
Collection<String> bundleList = getInitializationOption(initializationOptions, BUNDLES_KEY);
BundleUtils.loadBundles(bundleList);
} catch (CoreException e) {
// The additional plug-ins should not affect the main language server loading.
Expand Down Expand Up @@ -204,7 +204,7 @@ private void triggerInitialization(Collection<IPath> roots) {
public IStatus runInWorkspace(IProgressMonitor monitor) {
long start = System.currentTimeMillis();
connection.sendStatus(ServiceStatus.Starting, "Init...");
SubMonitor subMonitor = SubMonitor.convert(new ServerStatusMonitor(), 100);
SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
try {
projectsManager.setAutoBuilding(false);
projectsManager.initializeProjects(roots, subMonitor);
Expand Down Expand Up @@ -237,23 +237,14 @@ public boolean belongsTo(Object family) {
return JSONUtility.toModel(params.getInitializationOptions(), Map.class);
}

private Collection<String> getWorkspaceFolders(Map<?, ?> initializationOptions) {
private Collection<String> getInitializationOption(Map<?, ?> initializationOptions, String key) {
if (initializationOptions != null) {
Object folders = initializationOptions.get("workspaceFolders");
if (folders instanceof Collection<?>) {
return (Collection<String>) folders;
}
}
return null;
}
private Collection<String> getBundleList(Map<?, ?> initializationOptions) {
if (initializationOptions != null) {
Object bundleObject = initializationOptions.get(BUNDLES_KEY);
Object bundleObject = initializationOptions.get(key);
if (bundleObject instanceof Collection<?>) {
return (Collection<String>) bundleObject;
}
}
return null;
return Collections.emptyList();
}

public static void removeWorkspaceDiagnosticsHandler() {
Expand All @@ -268,42 +259,4 @@ public void addWorkspaceDiagnosticsHandler() {
workspaceDiagnosticsHandler = new WorkspaceDiagnosticsHandler(connection, projectsManager);
ResourcesPlugin.getWorkspace().addResourceChangeListener(workspaceDiagnosticsHandler, IResourceChangeEvent.POST_CHANGE);
}

private class ServerStatusMonitor extends NullProgressMonitor {
private final static long DELAY = 200;

private double totalWork;
private String subtask;
private double progress;
private long lastReport = 0;

@Override
public void beginTask(String task, int totalWork) {
this.totalWork = totalWork;
sendProgress();
}

@Override
public void subTask(String name) {
this.subtask = name;
sendProgress();
}

@Override
public void worked(int work) {
progress += work;
sendProgress();
}

private void sendProgress() {
// throttle the sending of progress
long currentTime = System.currentTimeMillis();
if (lastReport == 0 || currentTime - lastReport > DELAY) {
lastReport = currentTime;
String message = this.subtask == null || this.subtask.length() == 0 ? "" : (" - " + this.subtask);
connection.sendStatus(ServiceStatus.Starting, String.format("%.0f%% Starting Java Language Server %s", progress / totalWork * 100, message));
}
}

}
}
Loading

0 comments on commit a0d10d2

Please sign in to comment.