Skip to content

Commit 7dad90a

Browse files
committed
Improve metadata serialization for events
1 parent e08ccc4 commit 7dad90a

File tree

2 files changed

+63
-25
lines changed

2 files changed

+63
-25
lines changed

tmc-plugin/src/fi/helsinki/cs/tmc/model/ServerAccess.java

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import fi.helsinki.cs.tmc.utilities.ByteArrayGsonSerializer;
1717
import fi.helsinki.cs.tmc.utilities.CancellableCallable;
1818
import fi.helsinki.cs.tmc.utilities.ExceptionUtils;
19+
import fi.helsinki.cs.tmc.utilities.JsonMaker;
20+
import fi.helsinki.cs.tmc.utilities.JsonMakerGsonSerializer;
1921
import fi.helsinki.cs.tmc.utilities.UriUtils;
2022
import fi.helsinki.cs.tmc.utilities.http.FailedHttpResponseException;
2123
import fi.helsinki.cs.tmc.utilities.http.HttpTasks;
@@ -37,13 +39,13 @@
3739
*/
3840
public class ServerAccess {
3941
public static final int API_VERSION = 7;
40-
42+
4143
private TmcSettings settings;
4244
private CourseListParser courseListParser;
4345
private CourseInfoParser courseInfoParser;
4446
private ReviewListParser reviewListParser;
4547
private String clientVersion;
46-
48+
4749
public ServerAccess() {
4850
this(TmcSettings.getDefault());
4951
}
@@ -64,30 +66,30 @@ public ServerAccess(
6466
this.reviewListParser = reviewListParser;
6567
this.clientVersion = getClientVersion();
6668
}
67-
69+
6870
private static String getClientVersion() {
6971
return Modules.getDefault().ownerOf(ServerAccess.class).getSpecificationVersion().toString();
7072
}
71-
73+
7274
public void setSettings(TmcSettings settings) {
7375
this.settings = settings;
7476
}
75-
77+
7678
private String getCourseListUrl() {
7779
return addApiCallQueryParameters(settings.getServerBaseUrl() + "/courses.json");
7880
}
79-
81+
8082
private String addApiCallQueryParameters(String url) {
8183
url = UriUtils.withQueryParam(url, "api_version", ""+API_VERSION);
8284
url = UriUtils.withQueryParam(url, "client", "netbeans_plugin");
8385
url = UriUtils.withQueryParam(url, "client_version", clientVersion);
8486
return url;
8587
}
86-
88+
8789
private HttpTasks createHttpTasks() {
8890
return new HttpTasks().setCredentials(settings.getUsername(), settings.getPassword());
8991
}
90-
92+
9193
public boolean hasEnoughSettings() {
9294
return
9395
!settings.getUsername().isEmpty() &&
@@ -101,7 +103,7 @@ public boolean needsOnlyPassword() {
101103
settings.getPassword().isEmpty() &&
102104
!settings.getServerBaseUrl().isEmpty();
103105
}
104-
106+
105107
public CancellableCallable<List<Course>> getDownloadingCourseListTask() {
106108
final CancellableCallable<String> download = createHttpTasks().getForText(getCourseListUrl());
107109
return new CancellableCallable<List<Course>>() {
@@ -142,7 +144,7 @@ public boolean cancel() {
142144
}
143145
};
144146
}
145-
147+
146148
public CancellableCallable<Void> getUnlockingTask(Course course) {
147149
Map<String, String> params = Collections.emptyMap();
148150
final CancellableCallable<String> download = createHttpTasks().postForText(getUnlockUrl(course), params);
@@ -163,16 +165,16 @@ public boolean cancel() {
163165
}
164166
};
165167
}
166-
168+
167169
private String getUnlockUrl(Course course) {
168170
return addApiCallQueryParameters(course.getUnlockUrl());
169171
}
170-
172+
171173
public CancellableCallable<byte[]> getDownloadingExerciseZipTask(Exercise exercise) {
172174
String zipUrl = exercise.getDownloadUrl();
173175
return createHttpTasks().getForBinary(zipUrl);
174176
}
175-
177+
176178
public CancellableCallable<byte[]> getDownloadingExerciseSolutionZipTask(Exercise exercise) {
177179
String zipUrl = exercise.getSolutionDownloadUrl();
178180
return createHttpTasks().getForBinary(zipUrl);
@@ -188,7 +190,7 @@ public CancellableCallable<SubmissionResponse> getSubmittingExerciseTask(final E
188190

189191
final CancellableCallable<String> upload =
190192
createHttpTasks().uploadFileForTextDownload(submitUrl, params, "submission[file]", sourceZip);
191-
193+
192194
return new CancellableCallable<SubmissionResponse>() {
193195
@Override
194196
public SubmissionResponse call() throws Exception {
@@ -198,7 +200,7 @@ public SubmissionResponse call() throws Exception {
198200
} catch (FailedHttpResponseException ex) {
199201
return checkForObsoleteClient(ex);
200202
}
201-
203+
202204
JsonObject respJson = new JsonParser().parse(response).getAsJsonObject();
203205
if (respJson.get("error") != null) {
204206
throw new RuntimeException("Server responded with error: " + respJson.get("error"));
@@ -230,11 +232,11 @@ public SubmissionResponse(URI submissionUrl, URI pasteUrl) {
230232
this.pasteUrl = pasteUrl;
231233
}
232234
}
233-
235+
234236
public CancellableCallable<String> getSubmissionFetchTask(String submissionUrl) {
235237
return createHttpTasks().getForText(submissionUrl);
236238
}
237-
239+
238240
public CancellableCallable<List<Review>> getDownloadingReviewListTask(Course course) {
239241
String url = addApiCallQueryParameters(course.getReviewsUrl());
240242
final CancellableCallable<String> download = createHttpTasks().getForText(url);
@@ -255,7 +257,7 @@ public boolean cancel() {
255257
}
256258
};
257259
}
258-
260+
259261
public CancellableCallable<Void> getMarkingReviewAsReadTask(Review review, boolean read) {
260262
String url = addApiCallQueryParameters(review.getUpdateUrl() + ".json");
261263
Map<String, String> params = new HashMap<String, String>();
@@ -265,7 +267,7 @@ public CancellableCallable<Void> getMarkingReviewAsReadTask(Review review, boole
265267
} else {
266268
params.put("mark_as_unread", "1");
267269
}
268-
270+
269271
final CancellableCallable<String> task = createHttpTasks().postForText(url, params);
270272
return new CancellableCallable<Void>() {
271273
@Override
@@ -280,20 +282,20 @@ public boolean cancel() {
280282
}
281283
};
282284
}
283-
285+
284286
public CancellableCallable<String> getFeedbackAnsweringJob(String answerUrl, List<FeedbackAnswer> answers) {
285287
final String submitUrl = addApiCallQueryParameters(answerUrl);
286-
288+
287289
Map<String, String> params = new HashMap<String, String>();
288290
for (int i = 0; i < answers.size(); ++i) {
289291
String keyPrefix = "answers[" + i + "]";
290292
FeedbackAnswer answer = answers.get(i);
291293
params.put(keyPrefix + "[question_id]", "" + answer.getQuestion().getId());
292294
params.put(keyPrefix + "[answer]", answer.getAnswer());
293295
}
294-
296+
295297
final CancellableCallable<String> upload = createHttpTasks().postForText(submitUrl, params);
296-
298+
297299
return new CancellableCallable<String>() {
298300
@Override
299301
public String call() throws Exception {
@@ -310,7 +312,7 @@ public boolean cancel() {
310312
}
311313
};
312314
}
313-
315+
314316
public CancellableCallable<Object> getSendEventLogJob(String spywareServerUrl, List<LoggableEvent> events) {
315317
String url = addApiCallQueryParameters(spywareServerUrl);
316318

@@ -347,8 +349,10 @@ private byte[] eventListToPostBody(List<LoggableEvent> events) throws IOExceptio
347349
GZIPOutputStream gzos = new GZIPOutputStream(bufferBos);
348350
OutputStreamWriter bufferWriter = new OutputStreamWriter(gzos, Charset.forName("UTF-8"));
349351

352+
350353
Gson gson = new GsonBuilder()
351354
.registerTypeAdapter(byte[].class, new ByteArrayGsonSerializer())
355+
.registerTypeAdapter(JsonMaker.class, new JsonMakerGsonSerializer())
352356
.create();
353357

354358
gson.toJson(events, new TypeToken<List<LoggableEvent>>(){}.getType(), bufferWriter);
@@ -357,7 +361,7 @@ private byte[] eventListToPostBody(List<LoggableEvent> events) throws IOExceptio
357361

358362
return bufferBos.toByteArray();
359363
}
360-
364+
361365
private <T> T checkForObsoleteClient(FailedHttpResponseException ex) throws ObsoleteClientException, FailedHttpResponseException {
362366
if (ex.getStatusCode() == 404) {
363367
boolean obsolete;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package fi.helsinki.cs.tmc.utilities;
2+
3+
import com.google.gson.JsonDeserializationContext;
4+
import com.google.gson.JsonDeserializer;
5+
import com.google.gson.JsonElement;
6+
import com.google.gson.JsonNull;
7+
import com.google.gson.JsonParseException;
8+
import com.google.gson.JsonPrimitive;
9+
import com.google.gson.JsonSerializationContext;
10+
import com.google.gson.JsonSerializer;
11+
import java.lang.reflect.Type;
12+
import java.nio.charset.Charset;
13+
import org.apache.commons.codec.binary.Base64;
14+
15+
/**
16+
* Converts JsonMaker to byte[] to base64 in JSON.
17+
*/
18+
19+
public class JsonMakerGsonSerializer implements JsonSerializer<JsonMaker> /*, JsonDeserializer<JsonMaker> */ {
20+
@Override
21+
public JsonElement serialize(JsonMaker data, Type type, JsonSerializationContext jsc) {
22+
23+
if (data == null) {
24+
return JsonNull.INSTANCE;
25+
} else {
26+
return new JsonPrimitive(Base64.encodeBase64String(data.toString().getBytes(Charset.forName("UTF-8"))));
27+
}
28+
}
29+
30+
// @Override
31+
// public JsonMaker deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
32+
// return null;
33+
// }
34+
}

0 commit comments

Comments
 (0)