Skip to content

Commit f612bdf

Browse files
Move protocol implementation into new package (microsoft#81)
* Move protocol implementation into new package Signed-off-by: Jinbo Wang <jinbwan@microsoft.com> * Remove super usage in inherited class Signed-off-by: Jinbo Wang <jinbwan@microsoft.com> * resolve merge conflict Signed-off-by: Jinbo Wang <jinbwan@microsoft.com> * Fix review comments Signed-off-by: Jinbo Wang <jinbwan@microsoft.com>
1 parent 60313c6 commit f612bdf

30 files changed

+355
-297
lines changed

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222
import com.google.gson.JsonElement;
2323
import com.microsoft.java.debug.core.adapter.AdapterUtils;
24-
import com.microsoft.java.debug.core.adapter.JsonUtils;
25-
import com.microsoft.java.debug.core.adapter.Messages.Request;
26-
import com.microsoft.java.debug.core.adapter.Messages.Response;
24+
import com.microsoft.java.debug.core.protocol.JsonUtils;
25+
import com.microsoft.java.debug.core.protocol.Messages.Request;
26+
import com.microsoft.java.debug.core.protocol.Messages.Response;
2727
import com.sun.jdi.event.Event;
2828

2929
public class UsageDataSession {

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import java.util.Map;
1717
import java.util.concurrent.ConcurrentLinkedQueue;
1818

19-
import com.microsoft.java.debug.core.adapter.JsonUtils;
19+
import com.microsoft.java.debug.core.protocol.JsonUtils;
2020

2121
public class UsageDataStore {
2222
private ConcurrentLinkedQueue<Object> queue;

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828

2929
import org.apache.commons.lang3.StringUtils;
3030

31-
import com.microsoft.java.debug.core.adapter.Messages.Response;
31+
import com.microsoft.java.debug.core.protocol.Messages.Response;
32+
import com.microsoft.java.debug.core.protocol.Responses;
33+
import com.microsoft.java.debug.core.protocol.Types;
3234

3335
public class AdapterUtils {
3436
private static final String OS_NAME = System.getProperty("os.name", "").toLowerCase();

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import java.util.logging.Logger;
2121

2222
import com.microsoft.java.debug.core.Configuration;
23-
import com.microsoft.java.debug.core.adapter.Requests.Arguments;
24-
import com.microsoft.java.debug.core.adapter.Requests.Command;
2523
import com.microsoft.java.debug.core.adapter.handler.AttachRequestHandler;
2624
import com.microsoft.java.debug.core.adapter.handler.ConfigurationDoneRequestHandler;
2725
import com.microsoft.java.debug.core.adapter.handler.DisconnectRequestHandler;
@@ -36,6 +34,11 @@
3634
import com.microsoft.java.debug.core.adapter.handler.StackTraceRequestHandler;
3735
import com.microsoft.java.debug.core.adapter.handler.ThreadsRequestHandler;
3836
import com.microsoft.java.debug.core.adapter.handler.VariablesRequestHandler;
37+
import com.microsoft.java.debug.core.protocol.Events;
38+
import com.microsoft.java.debug.core.protocol.JsonUtils;
39+
import com.microsoft.java.debug.core.protocol.Messages;
40+
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
41+
import com.microsoft.java.debug.core.protocol.Requests.Command;
3942

4043
public class DebugAdapter implements IDebugAdapter {
4144
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
import java.util.Map;
1717

1818
import com.microsoft.java.debug.core.IDebugSession;
19-
import com.microsoft.java.debug.core.adapter.Events.DebugEvent;
2019
import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter;
2120
import com.microsoft.java.debug.core.adapter.variables.VariableFormatterFactory;
21+
import com.microsoft.java.debug.core.protocol.Events.DebugEvent;
2222

2323
public class DebugAdapterContext implements IDebugAdapterContext {
2424
private static final int MAX_CACHE_ITEMS = 10000;

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
package com.microsoft.java.debug.core.adapter;
1313

14+
import com.microsoft.java.debug.core.protocol.Messages;
15+
1416
public interface IDebugAdapter {
1517
Messages.Response dispatchRequest(Messages.Request request);
1618
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import com.microsoft.java.debug.core.IDebugSession;
1818
import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter;
19+
import com.microsoft.java.debug.core.protocol.Events;
1920

2021
public interface IDebugAdapterContext {
2122
/**

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugRequestHandler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
import java.util.List;
1515

16+
import com.microsoft.java.debug.core.protocol.Messages;
17+
import com.microsoft.java.debug.core.protocol.Requests;
18+
1619
public interface IDebugRequestHandler {
1720
List<Requests.Command> getTargetCommands();
1821

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java

Lines changed: 14 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,15 @@
1111

1212
package com.microsoft.java.debug.core.adapter;
1313

14-
import java.io.BufferedReader;
15-
import java.io.BufferedWriter;
16-
import java.io.IOException;
1714
import java.io.InputStream;
18-
import java.io.InputStreamReader;
1915
import java.io.OutputStream;
20-
import java.io.OutputStreamWriter;
21-
import java.io.PrintWriter;
22-
import java.io.Reader;
23-
import java.io.Writer;
24-
import java.nio.charset.Charset;
25-
import java.nio.charset.StandardCharsets;
26-
import java.util.concurrent.ConcurrentLinkedQueue;
27-
import java.util.concurrent.atomic.AtomicInteger;
28-
import java.util.logging.Level;
29-
import java.util.logging.Logger;
30-
import java.util.regex.Matcher;
31-
import java.util.regex.Pattern;
3216

33-
import com.microsoft.java.debug.core.Configuration;
3417
import com.microsoft.java.debug.core.UsageDataSession;
18+
import com.microsoft.java.debug.core.protocol.AbstractProtocolServer;
19+
import com.microsoft.java.debug.core.protocol.Messages;
3520

36-
public class ProtocolServer {
37-
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
38-
private static final int BUFFER_SIZE = 4096;
39-
private static final String TWO_CRLF = "\r\n\r\n";
40-
private static final Pattern CONTENT_LENGTH_MATCHER = Pattern.compile("Content-Length: (\\d+)");
41-
private static final Charset PROTOCOL_ENCODING = StandardCharsets.UTF_8; // vscode protocol uses UTF-8 as encoding format.
42-
43-
private Reader reader;
44-
private Writer writer;
45-
46-
private ByteBuffer rawData;
47-
private boolean terminateSession = false;
48-
private int contentLength = -1;
49-
private AtomicInteger sequenceNumber = new AtomicInteger(1);
50-
51-
private boolean isDispatchingData;
52-
private ConcurrentLinkedQueue<Messages.Event> eventQueue;
53-
21+
public class ProtocolServer extends AbstractProtocolServer {
5422
private IDebugAdapter debugAdapter;
55-
5623
private UsageDataSession usageDataSession = new UsageDataSession();
5724

5825
/**
@@ -65,18 +32,14 @@ public class ProtocolServer {
6532
* provider context for a series of provider implementation
6633
*/
6734
public ProtocolServer(InputStream input, OutputStream output, IProviderContext context) {
68-
this.reader = new BufferedReader(new InputStreamReader(input, PROTOCOL_ENCODING));
69-
this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output, PROTOCOL_ENCODING)));
70-
this.contentLength = -1;
71-
this.rawData = new ByteBuffer();
72-
this.eventQueue = new ConcurrentLinkedQueue<>();
35+
super(input, output);
7336
this.debugAdapter = new DebugAdapter((debugEvent, willSendLater) -> {
7437
// If the protocolServer has been stopped, it'll no longer receive any event.
7538
if (!terminateSession) {
7639
if (willSendLater) {
77-
this.sendEventLater(debugEvent.type, debugEvent);
40+
sendEventLater(debugEvent.type, debugEvent);
7841
} else {
79-
this.sendEvent(debugEvent.type, debugEvent);
42+
sendEvent(debugEvent.type, debugEvent);
8043
}
8144
}
8245
}, context);
@@ -87,178 +50,25 @@ public ProtocolServer(InputStream input, OutputStream output, IProviderContext c
8750
*/
8851
public void start() {
8952
usageDataSession.reportStart();
90-
char[] buffer = new char[BUFFER_SIZE];
91-
try {
92-
while (!this.terminateSession) {
93-
int read = this.reader.read(buffer, 0, BUFFER_SIZE);
94-
if (read == -1) {
95-
break;
96-
}
97-
98-
this.rawData.append(new String(buffer, 0, read).getBytes(PROTOCOL_ENCODING));
99-
this.processData();
100-
}
101-
} catch (IOException e) {
102-
logger.log(Level.SEVERE, String.format("Read data from io exception: %s", e.toString()), e);
103-
}
53+
super.start();
10454
}
10555

10656
/**
10757
* Sets terminateSession flag to true. And the dispatcher loop will be terminated after current dispatching operation finishes.
10858
*/
10959
public void stop() {
11060
usageDataSession.reportStop();
111-
this.terminateSession = true;
61+
super.stop();
11262
usageDataSession.submitUsageData();
11363
}
11464

115-
/**
116-
* Send event to DA immediately.
117-
* @param eventType
118-
* event type
119-
* @param body
120-
* event body
121-
*/
122-
private void sendEvent(String eventType, Object body) {
123-
sendMessage(new Messages.Event(eventType, body));
124-
}
125-
126-
/**
127-
* If the the dispatcher is idle, then send the event immediately.
128-
* Else add the new event to an eventQueue first and send them when dispatcher becomes idle again.
129-
* @param eventType
130-
* event type
131-
* @param body
132-
* event content
133-
*/
134-
private void sendEventLater(String eventType, Object body) {
135-
synchronized (this) {
136-
if (this.isDispatchingData) {
137-
this.eventQueue.offer(new Messages.Event(eventType, body));
138-
} else {
139-
sendMessage(new Messages.Event(eventType, body));
140-
}
65+
protected void dispatchRequest(Messages.Request request) {
66+
Messages.Response response = this.debugAdapter.dispatchRequest(request);
67+
if (request.command.equals("disconnect")) {
68+
stop();
14169
}
70+
sendMessage(response);
71+
usageDataSession.recordResponse(response);
14272
}
14373

144-
private void sendMessage(Messages.ProtocolMessage message) {
145-
message.seq = this.sequenceNumber.getAndIncrement();
146-
147-
String jsonMessage = JsonUtils.toJson(message);
148-
byte[] jsonBytes = jsonMessage.getBytes(PROTOCOL_ENCODING);
149-
150-
String header = String.format("Content-Length: %d%s", jsonBytes.length, TWO_CRLF);
151-
byte[] headerBytes = header.getBytes(PROTOCOL_ENCODING);
152-
153-
byte[] data = new byte[headerBytes.length + jsonBytes.length];
154-
System.arraycopy(headerBytes, 0, data, 0, headerBytes.length);
155-
System.arraycopy(jsonBytes, 0, data, headerBytes.length, jsonBytes.length);
156-
157-
String utf8Data = new String(data, PROTOCOL_ENCODING);
158-
159-
try {
160-
logger.fine("\n[[RESPONSE]]\n" + new String(data));
161-
this.writer.write(utf8Data);
162-
this.writer.flush();
163-
} catch (IOException e) {
164-
logger.log(Level.SEVERE, String.format("Write data to io exception: %s", e.toString()), e);
165-
}
166-
}
167-
168-
private void processData() {
169-
while (true) {
170-
/**
171-
* In vscode debug protocol, the content length represents the message's byte length with utf8 format.
172-
*/
173-
if (this.contentLength >= 0) {
174-
if (this.rawData.length() >= this.contentLength) {
175-
byte[] buf = this.rawData.removeFirst(this.contentLength);
176-
this.contentLength = -1;
177-
dispatchRequest(new String(buf, PROTOCOL_ENCODING));
178-
continue;
179-
}
180-
} else {
181-
String rawMessage = this.rawData.getString(PROTOCOL_ENCODING);
182-
int idx = rawMessage.indexOf(TWO_CRLF);
183-
if (idx != -1) {
184-
Matcher matcher = CONTENT_LENGTH_MATCHER.matcher(rawMessage);
185-
if (matcher.find()) {
186-
this.contentLength = Integer.parseInt(matcher.group(1));
187-
int headerByteLength = rawMessage.substring(0, idx + TWO_CRLF.length()).getBytes(PROTOCOL_ENCODING).length;
188-
this.rawData.removeFirst(headerByteLength); // Remove the header from the raw message.
189-
continue;
190-
}
191-
}
192-
}
193-
break;
194-
}
195-
}
196-
197-
private void dispatchRequest(String request) {
198-
try {
199-
logger.fine("\n[REQUEST]\n" + request);
200-
Messages.Request message = JsonUtils.fromJson(request, Messages.Request.class);
201-
usageDataSession.recordRequest(message);
202-
if (message.type.equals("request")) {
203-
synchronized (this) {
204-
this.isDispatchingData = true;
205-
}
206-
207-
try {
208-
Messages.Response response = this.debugAdapter.dispatchRequest(message);
209-
if (message.command.equals("disconnect")) {
210-
this.stop();
211-
}
212-
sendMessage(response);
213-
usageDataSession.recordResponse(response);
214-
} catch (Exception e) {
215-
logger.log(Level.SEVERE, String.format("Dispatch debug protocol error: %s", e.toString()), e);
216-
}
217-
}
218-
} finally {
219-
synchronized (this) {
220-
this.isDispatchingData = false;
221-
}
222-
223-
while (this.eventQueue.peek() != null) {
224-
sendMessage(this.eventQueue.poll());
225-
}
226-
}
227-
}
228-
229-
class ByteBuffer {
230-
private byte[] buffer;
231-
232-
public ByteBuffer() {
233-
this.buffer = new byte[0];
234-
}
235-
236-
public int length() {
237-
return this.buffer.length;
238-
}
239-
240-
public String getString(Charset cs) {
241-
return new String(this.buffer, cs);
242-
}
243-
244-
public void append(byte[] b) {
245-
append(b, b.length);
246-
}
247-
248-
public void append(byte[] b, int length) {
249-
byte[] newBuffer = new byte[this.buffer.length + length];
250-
System.arraycopy(buffer, 0, newBuffer, 0, this.buffer.length);
251-
System.arraycopy(b, 0, newBuffer, this.buffer.length, length);
252-
this.buffer = newBuffer;
253-
}
254-
255-
public byte[] removeFirst(int n) {
256-
byte[] b = new byte[n];
257-
System.arraycopy(this.buffer, 0, b, 0, n);
258-
byte[] newBuffer = new byte[this.buffer.length - n];
259-
System.arraycopy(this.buffer, n, newBuffer, 0, this.buffer.length - n);
260-
this.buffer = newBuffer;
261-
return b;
262-
}
263-
}
26474
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
2929
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider;
3030
import com.microsoft.java.debug.core.adapter.IVirtualMachineManagerProvider;
31-
import com.microsoft.java.debug.core.adapter.Messages.Response;
32-
import com.microsoft.java.debug.core.adapter.Requests.Arguments;
33-
import com.microsoft.java.debug.core.adapter.Requests.AttachArguments;
34-
import com.microsoft.java.debug.core.adapter.Requests.Command;
31+
import com.microsoft.java.debug.core.protocol.Messages.Response;
32+
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
33+
import com.microsoft.java.debug.core.protocol.Requests.AttachArguments;
34+
import com.microsoft.java.debug.core.protocol.Requests.Command;
3535
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
3636

3737
public class AttachRequestHandler implements IDebugRequestHandler {

0 commit comments

Comments
 (0)