Skip to content

Prevent JSONObject/Array + Map/List combinations and unnecessary conversions back and forth #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Parse/src/main/java/com/parse/ParseAnalytics.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

Expand Down Expand Up @@ -192,16 +194,15 @@ public static Task<Void> trackEventInBackground(final String name,
if (name == null || name.trim().length() == 0) {
throw new IllegalArgumentException("A name for the custom event must be provided.");
}

final JSONObject jsonDimensions = dimensions != null
? (JSONObject) NoObjectsEncoder.get().encode(dimensions)
final Map<String, String> dimensionsCopy = dimensions != null
? Collections.unmodifiableMap(new HashMap<>(dimensions))
: null;

return ParseUser.getCurrentSessionTokenAsync().onSuccessTask(new Continuation<String, Task<Void>>() {
@Override
public Task<Void> then(Task<String> task) throws Exception {
String sessionToken = task.getResult();
return getAnalyticsController().trackEventInBackground(name, jsonDimensions, sessionToken);
return getAnalyticsController().trackEventInBackground(name, dimensionsCopy, sessionToken);
}
});
}
Expand Down
6 changes: 4 additions & 2 deletions Parse/src/main/java/com/parse/ParseAnalyticsController.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import org.json.JSONObject;

import java.util.Map;

import bolts.Task;

/** package */ class ParseAnalyticsController {
Expand All @@ -21,8 +23,8 @@ public ParseAnalyticsController(ParseEventuallyQueue eventuallyQueue) {
}

public Task<Void> trackEventInBackground(final String name,
JSONObject jsonDimensions, String sessionToken) {
ParseRESTCommand command = ParseRESTAnalyticsCommand.trackEventCommand(name, jsonDimensions,
Map<String, String> dimensions, String sessionToken) {
ParseRESTCommand command = ParseRESTAnalyticsCommand.trackEventCommand(name, dimensions,
sessionToken);

Task<JSONObject> eventuallyTask = eventuallyQueue.enqueueEventuallyAsync(command, null);
Expand Down
12 changes: 8 additions & 4 deletions Parse/src/main/java/com/parse/ParseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
package com.parse;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Collections;
Expand Down Expand Up @@ -104,13 +103,18 @@ public Task<ParseConfig> then(Task<Void> task) throws Exception {
});
}

/* package */ ParseConfig(JSONObject object, ParseDecoder decoder) {
Map<String, Object> decodedObject = (Map<String, Object>) decoder.decode(object);
@SuppressWarnings("unchecked")
/* package */ static ParseConfig decode(JSONObject json, ParseDecoder decoder) {
Map<String, Object> decodedObject = (Map<String, Object>) decoder.decode(json);
Map<String, Object> decodedParams = (Map<String, Object>) decodedObject.get("params");
if (decodedParams == null) {
throw new RuntimeException("Object did not contain the 'params' key.");
}
this.params = Collections.unmodifiableMap(decodedParams);
return new ParseConfig(decodedParams);
}

/* package */ ParseConfig(Map<String, Object> params) {
this.params = Collections.unmodifiableMap(params);
}

/* package */ ParseConfig() {
Expand Down
2 changes: 1 addition & 1 deletion Parse/src/main/java/com/parse/ParseConfigController.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public Task<ParseConfig> getAsync(String sessionToken) {
public Task<ParseConfig> then(Task<JSONObject> task) throws Exception {
JSONObject result = task.getResult();

final ParseConfig config = new ParseConfig(result, ParseDecoder.get());
final ParseConfig config = ParseConfig.decode(result, ParseDecoder.get());
return currentConfigController.setCurrentConfigAsync(config).continueWith(new Continuation<Void, ParseConfig>() {
@Override
public ParseConfig then(Task<Void> task) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public ParseConfig call() throws Exception {
} catch (IOException | JSONException e) {
return null;
}
return new ParseConfig(json, ParseDecoder.get());
return ParseConfig.decode(json, ParseDecoder.get());
}

/* package */ void clearCurrentConfigForTesting() {
Expand Down
39 changes: 13 additions & 26 deletions Parse/src/main/java/com/parse/ParseEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

Expand All @@ -29,11 +28,19 @@
/** package */ abstract class ParseEncoder {

/* package */ static boolean isValidType(Object value) {
return value instanceof JSONObject || value instanceof JSONArray || value instanceof String
|| value instanceof Number || value instanceof Boolean || value == JSONObject.NULL
|| value instanceof ParseObject || value instanceof ParseACL || value instanceof ParseFile
|| value instanceof ParseGeoPoint || value instanceof Date || value instanceof byte[]
|| value instanceof List || value instanceof Map || value instanceof ParseRelation;
return value instanceof String
|| value instanceof Number
|| value instanceof Boolean
|| value instanceof Date
|| value instanceof List
|| value instanceof Map
|| value instanceof byte[]
|| value == JSONObject.NULL
|| value instanceof ParseObject
|| value instanceof ParseACL
|| value instanceof ParseFile
|| value instanceof ParseGeoPoint
|| value instanceof ParseRelation;
}

public Object encode(Object object) {
Expand Down Expand Up @@ -92,17 +99,6 @@ public Object encode(Object object) {
return json;
}

if (object instanceof JSONObject) {
JSONObject map = (JSONObject) object;
JSONObject json = new JSONObject();
Iterator<?> keys = map.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
json.put(key, encode(map.opt(key)));
}
return json;
}

if (object instanceof Collection) {
JSONArray array = new JSONArray();
for (Object item : (Collection<?>) object) {
Expand All @@ -111,15 +107,6 @@ public Object encode(Object object) {
return array;
}

if (object instanceof JSONArray) {
JSONArray array = (JSONArray) object;
JSONArray json = new JSONArray();
for (int i = 0; i < array.length(); ++i) {
json.put(encode(array.opt(i)));
}
return json;
}

if (object instanceof ParseRelation) {
ParseRelation<?> relation = (ParseRelation<?>) object;
return relation.encodeToJSON(this);
Expand Down
20 changes: 8 additions & 12 deletions Parse/src/main/java/com/parse/ParseObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -2918,6 +2918,14 @@ public void put(String key, Object value) {
throw new IllegalArgumentException("value may not be null.");
}

if (value instanceof JSONObject) {
ParseDecoder decoder = ParseDecoder.get();
value = decoder.convertJSONObjectToMap((JSONObject) value);
} else if (value instanceof JSONArray){
ParseDecoder decoder = ParseDecoder.get();
value = decoder.convertJSONArrayToList((JSONArray) value);
}

if (!ParseEncoder.isValidType(value)) {
throw new IllegalArgumentException("invalid type for value: " + value.getClass().toString());
}
Expand Down Expand Up @@ -3166,12 +3174,6 @@ public JSONArray getJSONArray(String key) {
public <T> List<T> getList(String key) {
synchronized (mutex) {
Object value = estimatedData.get(key);

if (value instanceof JSONArray) {
ParseDecoder decoder = ParseDecoder.get();
value = decoder.convertJSONArrayToList((JSONArray) value);
}

if (!(value instanceof List)) {
return null;
}
Expand All @@ -3192,12 +3194,6 @@ public <T> List<T> getList(String key) {
public <V> Map<String, V> getMap(String key) {
synchronized (mutex) {
Object value = estimatedData.get(key);

if (value instanceof JSONObject) {
ParseDecoder decoder = ParseDecoder.get();
value = decoder.convertJSONObjectToMap((JSONObject) value);
}

if (!(value instanceof Map)) {
return null;
}
Expand Down
67 changes: 35 additions & 32 deletions Parse/src/main/java/com/parse/ParseRESTAnalyticsCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

import com.parse.http.ParseHttpRequest;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/** package */ class ParseRESTAnalyticsCommand extends ParseRESTCommand {
Expand All @@ -26,43 +26,46 @@
// Tracks the AppOpened event
/* package for test */ static final String EVENT_APP_OPENED = "AppOpened";

public ParseRESTAnalyticsCommand(
String httpPath,
ParseHttpRequest.Method httpMethod,
Map<String, ?> parameters,
String sessionToken) {
super(httpPath, httpMethod, parameters, sessionToken);
}
private static final String PATH = "events/%s";

public static ParseRESTAnalyticsCommand trackAppOpenedCommand(String pushHash,
String sessionToken) {
Map<String, String> parameters = null;
if (pushHash != null) {
parameters = new HashMap<>();
parameters.put("push_hash", pushHash);
}
return trackEventCommand(EVENT_APP_OPENED, parameters, sessionToken);
private static final String KEY_AT = "at";
private static final String KEY_PUSH_HASH = "push_hash";
private static final String KEY_DIMENSIONS = "dimensions";

public static ParseRESTAnalyticsCommand trackAppOpenedCommand(
String pushHash, String sessionToken) {
return trackEventCommand(EVENT_APP_OPENED, pushHash, null, sessionToken);
}

public static ParseRESTAnalyticsCommand trackEventCommand(String eventName, JSONObject dimensions,
String sessionToken) {
Map<String, Object> parameters = null;
if (dimensions != null) {
parameters = new HashMap<>();
parameters.put("dimensions", dimensions);
}
return trackEventCommand(eventName, parameters, sessionToken);
public static ParseRESTAnalyticsCommand trackEventCommand(
String eventName, Map<String, String> dimensions, String sessionToken) {
return trackEventCommand(eventName, null, dimensions, sessionToken);
}

/* package */ static ParseRESTAnalyticsCommand trackEventCommand(String eventName,
Map<String, ?> parameters, String sessionToken) {
String httpPath = String.format("events/%s", Uri.encode(eventName));
Map<String, Object> commandParameters = new HashMap<>();
if (parameters != null) {
commandParameters.putAll(parameters);
/* package */ static ParseRESTAnalyticsCommand trackEventCommand(
String eventName, String pushHash, Map<String, String> dimensions, String sessionToken) {
String httpPath = String.format(PATH, Uri.encode(eventName));
JSONObject parameters = new JSONObject();
try {
parameters.put(KEY_AT, NoObjectsEncoder.get().encode(new Date()));
if (pushHash != null) {
parameters.put(KEY_PUSH_HASH, pushHash);
}
if (dimensions != null) {
parameters.put(KEY_DIMENSIONS, NoObjectsEncoder.get().encode(dimensions));
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
commandParameters.put("at", NoObjectsEncoder.get().encode(new Date()));
return new ParseRESTAnalyticsCommand(
httpPath, ParseHttpRequest.Method.POST, commandParameters, sessionToken);
httpPath, ParseHttpRequest.Method.POST, parameters, sessionToken);
}

public ParseRESTAnalyticsCommand(
String httpPath,
ParseHttpRequest.Method httpMethod,
JSONObject parameters,
String sessionToken) {
super(httpPath, httpMethod, parameters, sessionToken);
}
}
2 changes: 1 addition & 1 deletion Parse/src/main/java/com/parse/ParseRESTCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public ParseRESTCommand(
sessionToken);
}

protected ParseRESTCommand(
public ParseRESTCommand(
String httpPath,
ParseHttpRequest.Method httpMethod,
JSONObject jsonParameters,
Expand Down
12 changes: 5 additions & 7 deletions Parse/src/main/java/com/parse/ParseRESTObjectBatchCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import bolts.Continuation;
import bolts.Task;
Expand Down Expand Up @@ -59,7 +57,8 @@ public static List<Task<JSONObject>> executeBatch(
tasks.add(tcs.getTask());
}

List<JSONObject> requests = new ArrayList<>(batchSize);
JSONObject parameters = new JSONObject();
JSONArray requests = new JSONArray();
try {
for (ParseRESTObjectCommand command : commands) {
JSONObject requestParameters = new JSONObject();
Expand All @@ -69,14 +68,13 @@ public static List<Task<JSONObject>> executeBatch(
if (body != null) {
requestParameters.put("body", body);
}
requests.add(requestParameters);
requests.put(requestParameters);
}
parameters.put("requests", requests);
} catch (JSONException e) {
throw new RuntimeException(e);
}

Map<String, List<JSONObject>> parameters = new HashMap<>();
parameters.put("requests", requests);
ParseRESTCommand command = new ParseRESTObjectBatchCommand(
"batch", ParseHttpRequest.Method.POST, parameters, sessionToken);

Expand Down Expand Up @@ -132,7 +130,7 @@ public Void then(Task<JSONObject> task) throws Exception {
private ParseRESTObjectBatchCommand(
String httpPath,
ParseHttpRequest.Method httpMethod,
Map<String, ?> parameters,
JSONObject parameters,
String sessionToken) {
super(httpPath, httpMethod, parameters, sessionToken);
}
Expand Down
Loading