Skip to content

Commit 0c95f3e

Browse files
committed
Issue 522 - Allow custom notifications
The public `void notify(String method, Object parameter)` method is added to `JavaClientConnection` thus allowing sending the notifications from a Server to a Client Fixes eclipse-jdtls#522 Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
1 parent edffe44 commit 0c95f3e

File tree

4 files changed

+147
-27
lines changed

4 files changed

+147
-27
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JavaClientConnection.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016-2017 Red Hat Inc. and others.
2+
* Copyright (c) 2016-2018 Red Hat Inc. and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -24,6 +24,7 @@
2424
import org.eclipse.lsp4j.ShowMessageRequestParams;
2525
import org.eclipse.lsp4j.UnregistrationParams;
2626
import org.eclipse.lsp4j.WorkspaceEdit;
27+
import org.eclipse.lsp4j.jsonrpc.Endpoint;
2728
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
2829
import org.eclipse.lsp4j.services.LanguageClient;
2930

@@ -179,4 +180,14 @@ public void disconnect() {
179180
}
180181
}
181182

183+
/**
184+
* Sends a Notification from a server to a client
185+
*
186+
* @param method
187+
* @param parameter
188+
*
189+
*/
190+
public void notify(String method, Object parameter) {
191+
((Endpoint)client).notify(method, parameter);
192+
}
182193
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Red Hat Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.eclipse.jdt.ls.core.internal;
12+
13+
import static org.junit.Assert.assertEquals;
14+
import static org.junit.Assert.assertNotNull;
15+
16+
import java.util.Collections;
17+
import java.util.List;
18+
19+
import org.eclipse.jdt.core.ElementChangedEvent;
20+
import org.eclipse.jdt.core.ICompilationUnit;
21+
import org.eclipse.jdt.core.IElementChangedListener;
22+
import org.eclipse.jdt.core.IJavaProject;
23+
import org.eclipse.jdt.core.IPackageFragment;
24+
import org.eclipse.jdt.core.IPackageFragmentRoot;
25+
import org.eclipse.jdt.core.JavaCore;
26+
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
27+
import org.eclipse.jdt.ls.core.internal.preferences.Preferences;
28+
import org.eclipse.jdt.ls.core.internal.preferences.Preferences.Severity;
29+
import org.junit.After;
30+
import org.junit.Before;
31+
import org.junit.Test;
32+
import org.junit.runner.RunWith;
33+
import org.mockito.Mockito;
34+
import org.mockito.runners.MockitoJUnitRunner;
35+
36+
@RunWith(MockitoJUnitRunner.class)
37+
public class ServerToClientNotificationTest extends AbstractProjectsManagerBasedTest {
38+
private JavaClientConnection javaClient;
39+
40+
@Before
41+
public void setup() throws Exception {
42+
mockPreferences();
43+
44+
javaClient = new JavaClientConnection(client);
45+
}
46+
47+
@After
48+
public void tearDown() throws Exception {
49+
javaClient.disconnect();
50+
for (ICompilationUnit cu : JavaCore.getWorkingCopies(null)) {
51+
cu.discardWorkingCopy();
52+
}
53+
}
54+
55+
private Preferences mockPreferences() {
56+
Preferences mockPreferences = Mockito.mock(Preferences.class);
57+
Mockito.when(preferenceManager.getPreferences()).thenReturn(mockPreferences);
58+
Mockito.when(preferenceManager.getPreferences(Mockito.any())).thenReturn(mockPreferences);
59+
Mockito.when(mockPreferences.getIncompleteClasspathSeverity()).thenReturn(Severity.ignore);
60+
return mockPreferences;
61+
}
62+
63+
@Test
64+
public void testSendNotification() throws Exception {
65+
IElementChangedListener listener = new IElementChangedListener() {
66+
67+
@Override
68+
public void elementChanged(ElementChangedEvent event) {
69+
// This should sent Java Model events to a client
70+
javaClient.notify("notify", event);
71+
}
72+
};
73+
try {
74+
JavaCore.addElementChangedListener(listener);
75+
IJavaProject javaProject = newDefaultProject();
76+
IPackageFragmentRoot sourceFolder = javaProject.getPackageFragmentRoot(javaProject.getProject().getFolder("src"));
77+
IPackageFragment pack1 = sourceFolder.createPackageFragment("java", false, null);
78+
79+
// @formatter:off
80+
String standaloneFileContent =
81+
"package java;\n"+
82+
"public class Foo extends UnknownType {"+
83+
" public void method1(){\n"+
84+
" super.whatever();"+
85+
" }\n"+
86+
"}";
87+
// @formatter:on
88+
ICompilationUnit cu1 = pack1.createCompilationUnit("Foo.java", standaloneFileContent, false, null);
89+
90+
// Check if all the events are received and events aren't nulls
91+
List<ElementChangedEvent> eventReports = getClientRequests("notify");
92+
assertEquals(7, eventReports.size());
93+
94+
for (ElementChangedEvent notification : eventReports) {
95+
assertNotNull(notification);
96+
}
97+
} finally {
98+
JavaCore.removeElementChangedListener(listener);
99+
}
100+
}
101+
102+
@SuppressWarnings("unchecked")
103+
private <T> List<T> getClientRequests(String name) {
104+
List<?> requests = clientRequests.get(name);
105+
return requests != null ? (List<T>) requests : Collections.emptyList();
106+
}
107+
}

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/DocumentLifeCycleHandlerTest.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2017 Red Hat Inc. and others.
2+
* Copyright (c) 2017-2018 Red Hat Inc. and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -403,7 +403,7 @@ public void testDidOpenStandaloneFile() throws Exception {
403403

404404
openDocument(cu1, cu1.getSource(), 1);
405405

406-
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("publishDiagnostics");
406+
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("textDocument/publishDiagnostics");
407407
assertEquals(1, diagnosticReports.size());
408408
PublishDiagnosticsParams diagParam = diagnosticReports.get(0);
409409
assertEquals(0, diagParam.getDiagnostics().size());
@@ -420,13 +420,13 @@ public void testDidOpenNotOnClasspath() throws Exception {
420420
Job.getJobManager().join(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, monitor);
421421
assertEquals(project, cu.getJavaProject().getProject());
422422
assertEquals(source, cu.getSource());
423-
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("publishDiagnostics");
423+
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("textDocument/publishDiagnostics");
424424
assertEquals(1, diagnosticReports.size());
425425
PublishDiagnosticsParams diagParam = diagnosticReports.get(0);
426426
assertEquals(1, diagParam.getDiagnostics().size());
427427
closeDocument(cu);
428428
Job.getJobManager().join(DocumentLifeCycleHandler.DOCUMENT_LIFE_CYCLE_JOBS, monitor);
429-
diagnosticReports = getClientRequests("publishDiagnostics");
429+
diagnosticReports = getClientRequests("textDocument/publishDiagnostics");
430430
assertEquals(2, diagnosticReports.size());
431431
diagParam = diagnosticReports.get(1);
432432
assertEquals(0, diagParam.getDiagnostics().size());
@@ -452,7 +452,7 @@ public void testDidOpenStandaloneFileWithSyntaxError() throws Exception {
452452

453453
openDocument(cu1, cu1.getSource(), 1);
454454

455-
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("publishDiagnostics");
455+
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("textDocument/publishDiagnostics");
456456
assertEquals(1, diagnosticReports.size());
457457
PublishDiagnosticsParams diagParam = diagnosticReports.get(0);
458458
assertEquals("Unexpected number of errors " + diagParam.getDiagnostics(), 1, diagParam.getDiagnostics().size());
@@ -485,7 +485,7 @@ public void testDidOpenStandaloneFileWithNonSyntaxErrors() throws Exception {
485485

486486
openDocument(cu1, cu1.getSource(), 1);
487487

488-
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("publishDiagnostics");
488+
List<PublishDiagnosticsParams> diagnosticReports = getClientRequests("textDocument/publishDiagnostics");
489489
assertEquals(1, diagnosticReports.size());
490490
PublishDiagnosticsParams diagParam = diagnosticReports.get(0);
491491

@@ -705,7 +705,7 @@ class ExpectedProblemReport {
705705
}
706706

707707
private void assertNewProblemReported(ExpectedProblemReport... expectedReports) {
708-
List<PublishDiagnosticsParams> diags = getClientRequests("publishDiagnostics");
708+
List<PublishDiagnosticsParams> diags = getClientRequests("textDocument/publishDiagnostics");
709709
assertEquals(expectedReports.length, diags.size());
710710

711711
for (int i = 0; i < expectedReports.length; i++) {

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/AbstractProjectsManagerBasedTest.java

+21-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2016-2017 Red Hat Inc. and others.
2+
* Copyright (c) 2016-2018 Red Hat Inc. and others.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
@@ -18,9 +18,6 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21-
import java.lang.reflect.InvocationHandler;
22-
import java.lang.reflect.Method;
23-
import java.lang.reflect.Proxy;
2421
import java.net.URI;
2522
import java.nio.file.Paths;
2623
import java.util.ArrayList;
@@ -31,6 +28,7 @@
3128
import java.util.List;
3229
import java.util.Map;
3330
import java.util.Set;
31+
import java.util.concurrent.CompletableFuture;
3432

3533
import org.apache.commons.io.FileUtils;
3634
import org.eclipse.core.resources.IFile;
@@ -64,6 +62,8 @@
6462
import org.eclipse.jdt.ls.core.internal.preferences.ClientPreferences;
6563
import org.eclipse.jdt.ls.core.internal.preferences.PreferenceManager;
6664
import org.eclipse.jdt.ls.core.internal.preferences.Preferences;
65+
import org.eclipse.lsp4j.jsonrpc.Endpoint;
66+
import org.eclipse.lsp4j.jsonrpc.services.ServiceEndpoints;
6767
import org.junit.After;
6868
import org.junit.Before;
6969
import org.mockito.Mock;
@@ -86,22 +86,24 @@ public abstract class AbstractProjectsManagerBasedTest {
8686
protected SimpleLogListener logListener;
8787

8888
protected Map<String, List<Object>> clientRequests = new HashMap<>();
89-
protected JavaLanguageClient client = (JavaLanguageClient) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { JavaLanguageClient.class }, new InvocationHandler() {
89+
protected JavaLanguageClient client =
90+
ServiceEndpoints.toServiceObject(new Endpoint() {
9091

91-
@Override
92-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
93-
if (args.length == 1) {
94-
String name = method.getName();
95-
List<Object> params = clientRequests.get(name);
96-
if (params == null) {
97-
params = new ArrayList<>();
98-
clientRequests.put(name, params);
99-
}
100-
params.add(args[0]);
101-
}
102-
return null;
103-
}
104-
});
92+
@Override
93+
public CompletableFuture<?> request(String method, Object parameter) {
94+
return null;
95+
}
96+
97+
@Override
98+
public void notify(String method, Object parameter) {
99+
List<Object> params = clientRequests.get(method);
100+
if (params == null) {
101+
params = new ArrayList<>();
102+
clientRequests.put(method, params);
103+
}
104+
params.add(parameter);
105+
}
106+
}, JavaLanguageClient.class);
105107

106108
@Before
107109
public void initProjectManager() throws CoreException {

0 commit comments

Comments
 (0)