Skip to content
This repository was archived by the owner on Oct 20, 2022. It is now read-only.

Commit 3952285

Browse files
author
shubay
committed
Fix JSON format, change date encoding to a string representation. Fixes issue 12.
1 parent 6b047a6 commit 3952285

File tree

4 files changed

+126
-119
lines changed

4 files changed

+126
-119
lines changed

src/main/java/com/google/visualization/datasource/render/JsonRenderer.java

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ public static String getSignature(DataTable data) {
7878
private static String getFaultString(ReasonType reasonType, String description) {
7979
List<String> objectParts = Lists.newArrayList();
8080
if (reasonType != null) {
81-
objectParts.add("reason:'" + reasonType.lowerCaseString() + "'");
82-
objectParts.add("message:'" + EscapeUtil.jsonEscape(
83-
reasonType.getMessageForReasonType(null)) + "'");
81+
objectParts.add("\"reason\":\"" + reasonType.lowerCaseString() + "\"");
82+
objectParts.add("\"message\":\"" + EscapeUtil.jsonEscape(
83+
reasonType.getMessageForReasonType(null)) + "\"");
8484
}
8585

8686
if (description != null) {
87-
objectParts.add("detailed_message:'" + EscapeUtil.jsonEscape(description)
88-
+ "'");
87+
objectParts.add("\"detailed_message\":\"" + EscapeUtil.jsonEscape(description)
88+
+ "\"");
8989
}
9090
return new StrBuilder("{").appendWithSeparators(objectParts, ",").append("}").toString();
9191
}
@@ -108,12 +108,12 @@ public static CharSequence renderJsonResponse(
108108
if (isJsonp) {
109109
sb.append(dsParams.getResponseHandler()).append("(");
110110
}
111-
sb.append("{version:'0.6'");
111+
sb.append("{\"version\":\"0.6\"");
112112

113113
// If no reqId found in the request, do not return reqId in the response.
114114
String requestId = dsParams.getRequestId();
115115
if (requestId != null) {
116-
sb.append(",reqId:'").append(EscapeUtil.jsonEscape(requestId)).append("'");
116+
sb.append(",\"reqId\":\"").append(EscapeUtil.jsonEscape(requestId)).append("\"");
117117
}
118118

119119
// Check signature.
@@ -128,7 +128,7 @@ public static CharSequence renderJsonResponse(
128128
}
129129

130130
StatusType statusType = responseStatus.getStatusType();
131-
sb.append(",status:'").append(statusType.lowerCaseString()).append("'");
131+
sb.append(",\"status\":\"").append(statusType.lowerCaseString()).append("\"");
132132

133133
// There are reason and messages if the status is WARNING/ERROR.
134134
if (statusType != StatusType.OK) {
@@ -141,10 +141,10 @@ public static CharSequence renderJsonResponse(
141141
warningJsonStrings.add(getFaultString(warning.getReasonType(), warning.getMessage()));
142142
}
143143
}
144-
sb.append(",warnings:[").appendWithSeparators(warningJsonStrings, ",").append("]");
144+
sb.append(",\"warnings\":[").appendWithSeparators(warningJsonStrings, ",").append("]");
145145

146146
} else { // Status is error.
147-
sb.append(",errors:[");
147+
sb.append(",\"errors\":[");
148148
sb.append(getFaultString(responseStatus.getReasonType(), responseStatus.getDescription()));
149149
sb.append("]");
150150
}
@@ -153,8 +153,8 @@ public static CharSequence renderJsonResponse(
153153
if ((statusType != StatusType.ERROR) && (data != null)) {
154154
// MessageType OK or WARNING,
155155
// so need to attach a data table (and a signature).
156-
sb.append(",sig:'").append(JsonRenderer.getSignature(data)).append("'");
157-
sb.append(",table:").append(JsonRenderer.renderDataTable(data, true, true));
156+
sb.append(",\"sig\":\"").append(JsonRenderer.getSignature(data)).append("\"");
157+
sb.append(",\"table\":").append(JsonRenderer.renderDataTable(data, true, true));
158158
}
159159

160160
sb.append("}");
@@ -185,7 +185,7 @@ public static CharSequence renderDataTable(DataTable dataTable, boolean includeV
185185

186186
StringBuilder sb = new StringBuilder();
187187
sb.append("{");
188-
sb.append("cols:["); // column descriptions.
188+
sb.append("\"cols\":["); // column descriptions.
189189

190190
ColumnDescription col;
191191
for (int colId = 0; colId < columnDescriptions.size(); colId++) {
@@ -198,7 +198,7 @@ public static CharSequence renderDataTable(DataTable dataTable, boolean includeV
198198
sb.append("]"); // columns.
199199

200200
if (includeValues) {
201-
sb.append(",rows:[");
201+
sb.append(",\"rows\":[");
202202
List<TableCell> cells;
203203
TableCell cell;
204204
ColumnDescription columnDescription;
@@ -207,7 +207,7 @@ public static CharSequence renderDataTable(DataTable dataTable, boolean includeV
207207
for (int rowId = 0; rowId < rows.size(); rowId++) {
208208
TableRow tableRow = rows.get(rowId);
209209
cells = tableRow.getCells();
210-
sb.append("{c:[");
210+
sb.append("{\"c\":[");
211211
for (int cellId = 0; cellId < cells.size(); cellId++) {
212212
cell = cells.get(cellId);
213213
if (cellId < (cells.size() - 1)) {
@@ -223,7 +223,7 @@ public static CharSequence renderDataTable(DataTable dataTable, boolean includeV
223223
// Row properties.
224224
String customPropertiesString = getPropertiesMapString(tableRow.getCustomProperties());
225225
if (customPropertiesString != null) {
226-
sb.append(",p:").append(customPropertiesString);
226+
sb.append(",\"p\":").append(customPropertiesString);
227227
}
228228

229229
sb.append("}"); // cells.
@@ -238,7 +238,7 @@ public static CharSequence renderDataTable(DataTable dataTable, boolean includeV
238238
// Table properties.
239239
String customPropertiesString = getPropertiesMapString(dataTable.getCustomProperties());
240240
if (customPropertiesString != null) {
241-
sb.append(",p:").append(customPropertiesString);
241+
sb.append(",\"p\":").append(customPropertiesString);
242242
}
243243

244244
sb.append("}"); // table.
@@ -276,20 +276,20 @@ public static StringBuilder appendCellJson(TableCell cell,
276276
valueJson.append(((BooleanValue) value).getValue());
277277
break;
278278
case DATE:
279-
valueJson.append("new Date(");
279+
valueJson.append("\"Date(");
280280
dateValue = (DateValue) value;
281281
valueJson.append(dateValue.getYear()).append(",");
282282
valueJson.append(dateValue.getMonth()).append(",");
283283
valueJson.append(dateValue.getDayOfMonth());
284-
valueJson.append(")");
284+
valueJson.append(")\"");
285285
break;
286286
case NUMBER:
287287
valueJson.append(((NumberValue) value).getValue());
288288
break;
289289
case TEXT:
290-
valueJson.append("'");
290+
valueJson.append("\"");
291291
valueJson.append(EscapeUtil.jsonEscape(value.toString()));
292-
valueJson.append("'");
292+
valueJson.append("\"");
293293
break;
294294
case TIMEOFDAY:
295295
valueJson.append("[");
@@ -302,7 +302,7 @@ public static StringBuilder appendCellJson(TableCell cell,
302302
break;
303303
case DATETIME:
304304
calendar = ((DateTimeValue) value).getCalendar();
305-
valueJson.append("new Date(");
305+
valueJson.append("\"Date(");
306306
valueJson.append(calendar.get(GregorianCalendar.YEAR)).append(",");
307307
valueJson.append(calendar.get(GregorianCalendar.MONTH)).append(",");
308308
valueJson.append(calendar.get(GregorianCalendar.DAY_OF_MONTH));
@@ -311,7 +311,7 @@ public static StringBuilder appendCellJson(TableCell cell,
311311
valueJson.append(",");
312312
valueJson.append(calendar.get(GregorianCalendar.MINUTE)).append(",");
313313
valueJson.append(calendar.get(GregorianCalendar.SECOND));
314-
valueJson.append(")");
314+
valueJson.append(")\"");
315315
break;
316316
default:
317317
throw new IllegalArgumentException("Illegal value Type " + type);
@@ -335,14 +335,14 @@ public static StringBuilder appendCellJson(TableCell cell,
335335
if ((isLastColumn) || (!isJsonNull)) {
336336
sb.append("{");
337337
// Value
338-
sb.append("v:").append(valueJson);
338+
sb.append("\"v\":").append(valueJson);
339339
// Formatted value
340340
if ((includeFormatting) && (!escapedFormattedString.equals(""))) {
341-
sb.append(",f:'").append(escapedFormattedString).append("'");
341+
sb.append(",\"f\":\"").append(escapedFormattedString).append("\"");
342342
}
343343
String customPropertiesString = getPropertiesMapString(cell.getCustomProperties());
344344
if (customPropertiesString != null) {
345-
sb.append(",p:").append(customPropertiesString);
345+
sb.append(",\"p\":").append(customPropertiesString);
346346
}
347347
sb.append("}");
348348
}
@@ -360,14 +360,14 @@ public static StringBuilder appendCellJson(TableCell cell,
360360
public static StringBuilder appendColumnDescriptionJson(
361361
ColumnDescription col, StringBuilder sb) {
362362
sb.append("{");
363-
sb.append("id:'").append(EscapeUtil.jsonEscape(col.getId())).append("',");
364-
sb.append("label:'").append(EscapeUtil.jsonEscape(col.getLabel())).append("',");
365-
sb.append("type:'").append(col.getType().getTypeCodeLowerCase()).append("',");
366-
sb.append("pattern:'").append(EscapeUtil.jsonEscape(col.getPattern())).append("'");
363+
sb.append("\"id\":\"").append(EscapeUtil.jsonEscape(col.getId())).append("\",");
364+
sb.append("\"label\":\"").append(EscapeUtil.jsonEscape(col.getLabel())).append("\",");
365+
sb.append("\"type\":\"").append(col.getType().getTypeCodeLowerCase()).append("\",");
366+
sb.append("\"pattern\":\"").append(EscapeUtil.jsonEscape(col.getPattern())).append("\"");
367367

368368
String customPropertiesString = getPropertiesMapString(col.getCustomProperties());
369369
if (customPropertiesString != null) {
370-
sb.append(",p:").append(customPropertiesString);
370+
sb.append(",\"p\":").append(customPropertiesString);
371371
}
372372

373373
sb.append("}");
@@ -386,9 +386,9 @@ private static String getPropertiesMapString(Map<String, String> propertiesMap)
386386
if ((propertiesMap != null) && (!propertiesMap.isEmpty())) {
387387
List<String> customPropertiesStrings = Lists.newArrayList();
388388
for (Map.Entry<String, String> entry : propertiesMap.entrySet()) {
389-
customPropertiesStrings.add("'"
390-
+ EscapeUtil.jsonEscape(entry.getKey()) + "':'"
391-
+ EscapeUtil.jsonEscape(entry.getValue()) + "'");
389+
customPropertiesStrings.add("\""
390+
+ EscapeUtil.jsonEscape(entry.getKey()) + "\":\""
391+
+ EscapeUtil.jsonEscape(entry.getValue()) + "\"");
392392
}
393393
customPropertiesString = new StrBuilder("{")
394394
.appendWithSeparators(customPropertiesStrings, ",").append("}").toString();

src/test/java/com/google/visualization/datasource/DataSourceHelperTest.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,12 @@ public void testGenerateResponse() throws DataSourceException {
184184
new DataSourceParameters(null),
185185
ULocale.UK);
186186
assertEquals(
187-
"{version:'0.6',status:'ok',sig:'730893465',"
188-
+ "table:{cols:[{id:'col1',label:'column1',type:'number',pattern:''},"
189-
+ "{id:'col2',label:'column2',type:'boolean',pattern:''},"
190-
+ "{id:'col3',label:'column3',type:'string',pattern:''}],"
191-
+ "rows:[{c:[{v:7.0},{v:false},{v:'Why?'}]}]}}",
187+
"{\"version\":\"0.6\",\"status\":\"ok\",\"sig\":\"1548939605\","
188+
+ "\"table\":{\"cols\":[{\"id\":\"col1\",\"label\":\"column1\",\"type\":\"number\","
189+
+ "\"pattern\":\"\"},"
190+
+ "{\"id\":\"col2\",\"label\":\"column2\",\"type\":\"boolean\",\"pattern\":\"\"},"
191+
+ "{\"id\":\"col3\",\"label\":\"column3\",\"type\":\"string\",\"pattern\":\"\"}],"
192+
+ "\"rows\":[{\"c\":[{\"v\":7.0},{\"v\":false},{\"v\":\"Why?\"}]}]}}",
192193
DataSourceHelper.generateResponse(dataTable, dataSourceRequest));
193194

194195
// With reqId:666;
@@ -197,11 +198,12 @@ public void testGenerateResponse() throws DataSourceException {
197198
new DataSourceParameters("reqId:666"),
198199
ULocale.UK);
199200
assertEquals(
200-
"{version:'0.6',reqId:'666',status:'ok',sig:'730893465',"
201-
+ "table:{cols:[{id:'col1',label:'column1',type:'number',pattern:''},"
202-
+ "{id:'col2',label:'column2',type:'boolean',pattern:''},"
203-
+ "{id:'col3',label:'column3',type:'string',pattern:''}],"
204-
+ "rows:[{c:[{v:7.0},{v:false},{v:'Why?'}]}]}}",
201+
"{\"version\":\"0.6\",\"reqId\":\"666\",\"status\":\"ok\",\"sig\":\"1548939605\","
202+
+ "\"table\":{\"cols\":[{\"id\":\"col1\",\"label\":\"column1\",\"type\":\"number\","
203+
+ "\"pattern\":\"\"},"
204+
+ "{\"id\":\"col2\",\"label\":\"column2\",\"type\":\"boolean\",\"pattern\":\"\"},"
205+
+ "{\"id\":\"col3\",\"label\":\"column3\",\"type\":\"string\",\"pattern\":\"\"}],"
206+
+ "\"rows\":[{\"c\":[{\"v\":7.0},{\"v\":false},{\"v\":\"Why?\"}]}]}}",
205207
DataSourceHelper.generateResponse(dataTable, dataSourceRequest));
206208

207209
// With out:json;
@@ -210,11 +212,12 @@ public void testGenerateResponse() throws DataSourceException {
210212
new DataSourceParameters("out:json"),
211213
ULocale.UK);
212214
assertEquals(
213-
"{version:'0.6',status:'ok',sig:'730893465',"
214-
+ "table:{cols:[{id:'col1',label:'column1',type:'number',pattern:''},"
215-
+ "{id:'col2',label:'column2',type:'boolean',pattern:''},"
216-
+ "{id:'col3',label:'column3',type:'string',pattern:''}],"
217-
+ "rows:[{c:[{v:7.0},{v:false},{v:'Why?'}]}]}}",
215+
"{\"version\":\"0.6\",\"status\":\"ok\",\"sig\":\"1548939605\","
216+
+ "\"table\":{\"cols\":[{\"id\":\"col1\",\"label\":\"column1\",\"type\":\"number\","
217+
+ "\"pattern\":\"\"},"
218+
+ "{\"id\":\"col2\",\"label\":\"column2\",\"type\":\"boolean\",\"pattern\":\"\"},"
219+
+ "{\"id\":\"col3\",\"label\":\"column3\",\"type\":\"string\",\"pattern\":\"\"}],"
220+
+ "\"rows\":[{\"c\":[{\"v\":7.0},{\"v\":false},{\"v\":\"Why?\"}]}]}}",
218221
DataSourceHelper.generateResponse(dataTable, dataSourceRequest));
219222

220223
// With out:jsonp;
@@ -223,11 +226,12 @@ public void testGenerateResponse() throws DataSourceException {
223226
new DataSourceParameters("out:jsonp"),
224227
ULocale.UK);
225228
assertEquals(
226-
"google.visualization.Query.setResponse({version:'0.6',status:'ok',"
227-
+ "sig:'730893465',table:{cols:[{id:'col1',label:'column1',type:'number',pattern:''},"
228-
+ "{id:'col2',label:'column2',type:'boolean',pattern:''},"
229-
+ "{id:'col3',label:'column3',type:'string',pattern:''}],"
230-
+ "rows:[{c:[{v:7.0},{v:false},{v:'Why?'}]}]}});",
229+
"google.visualization.Query.setResponse({\"version\":\"0.6\",\"status\":\"ok\","
230+
+ "\"sig\":\"1548939605\",\"table\":{\"cols\":[{\"id\":\"col1\",\"label\":\"column1\","
231+
+ "\"type\":\"number\",\"pattern\":\"\"},"
232+
+ "{\"id\":\"col2\",\"label\":\"column2\",\"type\":\"boolean\",\"pattern\":\"\"},"
233+
+ "{\"id\":\"col3\",\"label\":\"column3\",\"type\":\"string\",\"pattern\":\"\"}],"
234+
+ "\"rows\":[{\"c\":[{\"v\":7.0},{\"v\":false},{\"v\":\"Why?\"}]}]}});",
231235
DataSourceHelper.generateResponse(dataTable, dataSourceRequest));
232236

233237
// Now with out:csv;

src/test/java/com/google/visualization/datasource/ResponseWriterTest.java

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ public void testSetServletResponseJson() throws DataSourceException {
8787
DataSourceParameters dsParams = new DataSourceParameters("responseHandler:babylon;out:json");
8888
ResponseStatus responseStatus = new ResponseStatus(StatusType.OK, null, null);
8989

90-
String expected = "{version:'0.6',status:'ok',"
91-
+ "sig:'314016083',table:"
92-
+ "{cols:[{id:'A',label:'col0',type:'string',pattern:''},"
93-
+ "{id:'B',label:'col1',type:'number',pattern:''},"
94-
+ "{id:'C',label:'col2',type:'boolean',pattern:''}],"
95-
+ "rows:[{c:[{v:'aaa'},{v:222.0,f:'222'},{v:false}]},"
96-
+ "{c:[{v:''},{v:111.0},{v:true}]},"
97-
+ "{c:[{v:'bbb'},{v:333.0},{v:true}]},"
98-
+ "{c:[{v:'ddd'},{v:222.0},{v:false}]}]}}";
90+
String expected = "{\"version\":\"0.6\",\"status\":\"ok\","
91+
+ "\"sig\":\"2087475733\",\"table\":"
92+
+ "{\"cols\":[{\"id\":\"A\",\"label\":\"col0\",\"type\":\"string\",\"pattern\":\"\"},"
93+
+ "{\"id\":\"B\",\"label\":\"col1\",\"type\":\"number\",\"pattern\":\"\"},"
94+
+ "{\"id\":\"C\",\"label\":\"col2\",\"type\":\"boolean\",\"pattern\":\"\"}],"
95+
+ "\"rows\":[{\"c\":[{\"v\":\"aaa\"},{\"v\":222.0,\"f\":\"222\"},{\"v\":false}]},"
96+
+ "{\"c\":[{\"v\":\"\"},{\"v\":111.0},{\"v\":true}]},"
97+
+ "{\"c\":[{\"v\":\"bbb\"},{\"v\":333.0},{\"v\":true}]},"
98+
+ "{\"c\":[{\"v\":\"ddd\"},{\"v\":222.0},{\"v\":false}]}]}}";
9999

100100
assertEquals(expected, JsonRenderer.renderJsonResponse(
101101
dsParams, responseStatus, data, false).toString());
@@ -107,15 +107,15 @@ public void testSetServletResponseJson() throws DataSourceException {
107107
dsParams = new DataSourceParameters("reqId:90210;responseHandler:babylon;");
108108
responseStatus = new ResponseStatus(StatusType.OK, null, null);
109109

110-
expected = "{version:'0.6',reqId:'90210',status:'ok',"
111-
+ "sig:'314016083',table:"
112-
+ "{cols:[{id:'A',label:'col0',type:'string',pattern:''},"
113-
+ "{id:'B',label:'col1',type:'number',pattern:''},"
114-
+ "{id:'C',label:'col2',type:'boolean',pattern:''}],"
115-
+ "rows:[{c:[{v:'aaa'},{v:222.0,f:'222'},{v:false}]},"
116-
+ "{c:[{v:''},{v:111.0},{v:true}]},"
117-
+ "{c:[{v:'bbb'},{v:333.0},{v:true}]},"
118-
+ "{c:[{v:'ddd'},{v:222.0},{v:false}]}]}}";
110+
expected = "{\"version\":\"0.6\",\"reqId\":\"90210\",\"status\":\"ok\","
111+
+ "\"sig\":\"2087475733\",\"table\":"
112+
+ "{\"cols\":[{\"id\":\"A\",\"label\":\"col0\",\"type\":\"string\",\"pattern\":\"\"},"
113+
+ "{\"id\":\"B\",\"label\":\"col1\",\"type\":\"number\",\"pattern\":\"\"},"
114+
+ "{\"id\":\"C\",\"label\":\"col2\",\"type\":\"boolean\",\"pattern\":\"\"}],"
115+
+ "\"rows\":[{\"c\":[{\"v\":\"aaa\"},{\"v\":222.0,\"f\":\"222\"},{\"v\":false}]},"
116+
+ "{\"c\":[{\"v\":\"\"},{\"v\":111.0},{\"v\":true}]},"
117+
+ "{\"c\":[{\"v\":\"bbb\"},{\"v\":333.0},{\"v\":true}]},"
118+
+ "{\"c\":[{\"v\":\"ddd\"},{\"v\":222.0},{\"v\":false}]}]}}";
119119

120120
assertEquals(expected, JsonRenderer.renderJsonResponse(
121121
dsParams, responseStatus, data, false).toString());
@@ -132,9 +132,9 @@ public void testGenerateJsonResponseError() throws DataSourceException {
132132
ReasonType.INTERNAL_ERROR,
133133
"this is me not you why it is that not knowing me cave man");
134134

135-
String expected = "{version:'0.6',reqId:'90210',status:'error',errors:"
136-
+ "[{reason:'internal_error',message:'Internal error',detailed_message:'this is me not "
137-
+ "you why it is that not knowing me cave man'}]}";
135+
String expected = "{\"version\":\"0.6\",\"reqId\":\"90210\",\"status\":\"error\",\"errors\":"
136+
+ "[{\"reason\":\"internal_error\",\"message\":\"Internal error\","
137+
+ "\"detailed_message\":\"this is me not you why it is that not knowing me cave man\"}]}";
138138
assertEquals(
139139
expected,
140140
JsonRenderer.renderJsonResponse(dsParams, responseStatus, data, false).toString());

0 commit comments

Comments
 (0)