diff --git a/Parse/src/main/java/com/parse/ParseFieldOperation.java b/Parse/src/main/java/com/parse/ParseFieldOperation.java index bd33d7139..34abc67b4 100644 --- a/Parse/src/main/java/com/parse/ParseFieldOperation.java +++ b/Parse/src/main/java/com/parse/ParseFieldOperation.java @@ -81,236 +81,3 @@ Object apply(Object oldValue, String key); } -final class ParseFieldOperations { - private ParseFieldOperations() { - } - - /** - * A function that creates a ParseFieldOperation from a JSONObject or a Parcel. - */ - private interface ParseFieldOperationFactory { - ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) throws JSONException; - ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder); - } - - // A map of all known decoders. - private static Map opDecoderMap = new HashMap<>(); - - /** - * Registers a single factory for a given __op field value. - */ - private static void registerDecoder(String opName, ParseFieldOperationFactory factory) { - opDecoderMap.put(opName, factory); - } - - /** - * Registers a list of default decoder functions that convert a JSONObject with an __op field, - * or a Parcel with a op name string, into a ParseFieldOperation. - */ - static void registerDefaultDecoders() { - registerDecoder(ParseRelationOperation.OP_NAME_BATCH, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - ParseFieldOperation op = null; - JSONArray ops = object.getJSONArray("ops"); - for (int i = 0; i < ops.length(); ++i) { - ParseFieldOperation nextOp = ParseFieldOperations.decode(ops.getJSONObject(i), decoder); - op = nextOp.mergeWithPrevious(op); - } - return op; - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - // Decode AddRelation and then RemoveRelation - ParseFieldOperation add = ParseFieldOperations.decode(source, decoder); - ParseFieldOperation remove = ParseFieldOperations.decode(source, decoder); - return remove.mergeWithPrevious(add); - } - }); - - registerDecoder(ParseDeleteOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - return ParseDeleteOperation.getInstance(); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - return ParseDeleteOperation.getInstance(); - } - }); - - registerDecoder(ParseIncrementOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - return new ParseIncrementOperation((Number) decoder.decode(object.opt("amount"))); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - return new ParseIncrementOperation((Number) decoder.decode(source)); - } - }); - - registerDecoder(ParseAddOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - return new ParseAddOperation((Collection) decoder.decode(object.opt("objects"))); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - int size = source.readInt(); - List list = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - list.set(i, decoder.decode(source)); - } - return new ParseAddOperation(list); - } - }); - - registerDecoder(ParseAddUniqueOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - return new ParseAddUniqueOperation((Collection) decoder.decode(object.opt("objects"))); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - int size = source.readInt(); - List list = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - list.set(i, decoder.decode(source)); - } - return new ParseAddUniqueOperation(list); - } - }); - - registerDecoder(ParseRemoveOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - return new ParseRemoveOperation((Collection) decoder.decode(object.opt("objects"))); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - int size = source.readInt(); - List list = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - list.set(i, decoder.decode(source)); - } - return new ParseRemoveOperation(list); - } - }); - - registerDecoder(ParseRelationOperation.OP_NAME_ADD, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - JSONArray objectsArray = object.optJSONArray("objects"); - List objectsList = (List) decoder.decode(objectsArray); - return new ParseRelationOperation<>(new HashSet<>(objectsList), null); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - int size = source.readInt(); - Set set = new HashSet<>(size); - for (int i = 0; i < size; i++) { - set.add((ParseObject) decoder.decode(source)); - } - return new ParseRelationOperation<>(set, null); - } - }); - - registerDecoder(ParseRelationOperation.OP_NAME_REMOVE, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) - throws JSONException { - JSONArray objectsArray = object.optJSONArray("objects"); - List objectsList = (List) decoder.decode(objectsArray); - return new ParseRelationOperation<>(null, new HashSet<>(objectsList)); - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - int size = source.readInt(); - Set set = new HashSet<>(size); - for (int i = 0; i < size; i++) { - set.add((ParseObject) decoder.decode(source)); - } - return new ParseRelationOperation<>(null, set); - } - }); - - registerDecoder(ParseSetOperation.OP_NAME, new ParseFieldOperationFactory() { - @Override - public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) throws JSONException { - return null; // Not called. - } - - @Override - public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - return new ParseSetOperation(decoder.decode(source)); - } - }); - } - - /** - * Converts a parsed JSON object into a ParseFieldOperation. - * - * @param encoded - * A JSONObject containing an __op field. - * @return A ParseFieldOperation. - */ - static ParseFieldOperation decode(JSONObject encoded, ParseDecoder decoder) throws JSONException { - String op = encoded.optString("__op"); - ParseFieldOperationFactory factory = opDecoderMap.get(op); - if (factory == null) { - throw new RuntimeException("Unable to decode operation of type " + op); - } - return factory.decode(encoded, decoder); - } - - /** - * Reads a ParseFieldOperation out of the given Parcel. - * - * @param source - * The source Parcel. - * @param decoder - * The given ParseParcelableDecoder. - * - * @return A ParseFieldOperation. - */ - static ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { - String op = source.readString(); - ParseFieldOperationFactory factory = opDecoderMap.get(op); - if (factory == null) { - throw new RuntimeException("Unable to decode operation of type " + op); - } - return factory.decode(source, decoder); - } - - /** - * Converts a JSONArray into an ArrayList. - */ - static ArrayList jsonArrayAsArrayList(JSONArray array) { - ArrayList result = new ArrayList<>(array.length()); - for (int i = 0; i < array.length(); ++i) { - try { - result.add(array.get(i)); - } catch (JSONException e) { - // This can't actually happen. - throw new RuntimeException(e); - } - } - return result; - } -} diff --git a/Parse/src/main/java/com/parse/ParseFieldOperations.java b/Parse/src/main/java/com/parse/ParseFieldOperations.java new file mode 100644 index 000000000..6bf042472 --- /dev/null +++ b/Parse/src/main/java/com/parse/ParseFieldOperations.java @@ -0,0 +1,253 @@ +package com.parse; + +import android.os.Parcel; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Utility methods to deal with {@link ParseFieldOperation} decoding, both from JSON objects and + * from {@link Parcel}s. + */ +/* package */ final class ParseFieldOperations { + private ParseFieldOperations() { + } + + /** + * A function that creates a ParseFieldOperation from a JSONObject or a Parcel. + */ + private interface ParseFieldOperationFactory { + ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) throws JSONException; + ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder); + } + + // A map of all known decoders. + private static Map opDecoderMap = new HashMap<>(); + + /** + * Registers a single factory for a given __op field value. + */ + private static void registerDecoder(String opName, ParseFieldOperationFactory factory) { + opDecoderMap.put(opName, factory); + } + + /** + * Registers a list of default decoder functions that convert a JSONObject with an __op field, + * or a Parcel with a op name string, into a ParseFieldOperation. + */ + static void registerDefaultDecoders() { + registerDecoder(ParseRelationOperation.OP_NAME_BATCH, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + ParseFieldOperation op = null; + JSONArray ops = object.getJSONArray("ops"); + for (int i = 0; i < ops.length(); ++i) { + ParseFieldOperation nextOp = ParseFieldOperations.decode(ops.getJSONObject(i), decoder); + op = nextOp.mergeWithPrevious(op); + } + return op; + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + // Decode AddRelation and then RemoveRelation + ParseFieldOperation add = ParseFieldOperations.decode(source, decoder); + ParseFieldOperation remove = ParseFieldOperations.decode(source, decoder); + return remove.mergeWithPrevious(add); + } + }); + + registerDecoder(ParseDeleteOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + return ParseDeleteOperation.getInstance(); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + return ParseDeleteOperation.getInstance(); + } + }); + + registerDecoder(ParseIncrementOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + return new ParseIncrementOperation((Number) decoder.decode(object.opt("amount"))); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + return new ParseIncrementOperation((Number) decoder.decode(source)); + } + }); + + registerDecoder(ParseAddOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + return new ParseAddOperation((Collection) decoder.decode(object.opt("objects"))); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + int size = source.readInt(); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.set(i, decoder.decode(source)); + } + return new ParseAddOperation(list); + } + }); + + registerDecoder(ParseAddUniqueOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + return new ParseAddUniqueOperation((Collection) decoder.decode(object.opt("objects"))); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + int size = source.readInt(); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.set(i, decoder.decode(source)); + } + return new ParseAddUniqueOperation(list); + } + }); + + registerDecoder(ParseRemoveOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + return new ParseRemoveOperation((Collection) decoder.decode(object.opt("objects"))); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + int size = source.readInt(); + List list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.set(i, decoder.decode(source)); + } + return new ParseRemoveOperation(list); + } + }); + + registerDecoder(ParseRelationOperation.OP_NAME_ADD, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + JSONArray objectsArray = object.optJSONArray("objects"); + List objectsList = (List) decoder.decode(objectsArray); + return new ParseRelationOperation<>(new HashSet<>(objectsList), null); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + int size = source.readInt(); + Set set = new HashSet<>(size); + for (int i = 0; i < size; i++) { + set.add((ParseObject) decoder.decode(source)); + } + return new ParseRelationOperation<>(set, null); + } + }); + + registerDecoder(ParseRelationOperation.OP_NAME_REMOVE, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) + throws JSONException { + JSONArray objectsArray = object.optJSONArray("objects"); + List objectsList = (List) decoder.decode(objectsArray); + return new ParseRelationOperation<>(null, new HashSet<>(objectsList)); + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + int size = source.readInt(); + Set set = new HashSet<>(size); + for (int i = 0; i < size; i++) { + set.add((ParseObject) decoder.decode(source)); + } + return new ParseRelationOperation<>(null, set); + } + }); + + registerDecoder(ParseSetOperation.OP_NAME, new ParseFieldOperationFactory() { + @Override + public ParseFieldOperation decode(JSONObject object, ParseDecoder decoder) throws JSONException { + return null; // Not called. + } + + @Override + public ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + return new ParseSetOperation(decoder.decode(source)); + } + }); + } + + /** + * Converts a parsed JSON object into a ParseFieldOperation. + * + * @param encoded + * A JSONObject containing an __op field. + * @return A ParseFieldOperation. + */ + static ParseFieldOperation decode(JSONObject encoded, ParseDecoder decoder) throws JSONException { + String op = encoded.optString("__op"); + ParseFieldOperationFactory factory = opDecoderMap.get(op); + if (factory == null) { + throw new RuntimeException("Unable to decode operation of type " + op); + } + return factory.decode(encoded, decoder); + } + + /** + * Reads a ParseFieldOperation out of the given Parcel. + * + * @param source + * The source Parcel. + * @param decoder + * The given ParseParcelableDecoder. + * + * @return A ParseFieldOperation. + */ + static ParseFieldOperation decode(Parcel source, ParseParcelDecoder decoder) { + String op = source.readString(); + ParseFieldOperationFactory factory = opDecoderMap.get(op); + if (factory == null) { + throw new RuntimeException("Unable to decode operation of type " + op); + } + return factory.decode(source, decoder); + } + + /** + * Converts a JSONArray into an ArrayList. + */ + static ArrayList jsonArrayAsArrayList(JSONArray array) { + ArrayList result = new ArrayList<>(array.length()); + for (int i = 0; i < array.length(); ++i) { + try { + result.add(array.get(i)); + } catch (JSONException e) { + // This can't actually happen. + throw new RuntimeException(e); + } + } + return result; + } +}