All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.parse.ParseDecoder Maven / Gradle / Ivy

Go to download

A library that gives you access to the powerful Parse cloud platform from your Android app.

There is a newer version: 1.17.3
Show newest version
/*
 * Copyright (c) 2015-present, Parse, LLC.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
package com.parse;

import android.util.Base64;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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

/**
 * A {@code ParseDecoder} can be used to transform JSON data structures into actual objects, such as
 * {@link ParseObjects}.
 *
 * @see com.parse.ParseEncoder
 */
/** package */ class ParseDecoder {

  // This class isn't really a Singleton, but since it has no state, it's more efficient to get the
  // default instance.
  private static final ParseDecoder INSTANCE = new ParseDecoder();
  public static ParseDecoder get() {
    return INSTANCE;
  }

  protected ParseDecoder() {
    // do nothing
  }

  /* package */ List convertJSONArrayToList(JSONArray array) {
    List list = new ArrayList<>();
    for (int i = 0; i < array.length(); ++i) {
      list.add(decode(array.opt(i)));
    }
    return list;
  }

  /* package */ Map convertJSONObjectToMap(JSONObject object) {
    Map outputMap = new HashMap<>();
    Iterator it = object.keys();
    while (it.hasNext()) {
      String key = it.next();
      Object value = object.opt(key);
      outputMap.put(key, decode(value));
    }
    return outputMap;
  }
  
  /**
   * Gets the ParseObject another object points to. By default a new
   * object will be created.
   */
  protected ParseObject decodePointer(String className, String objectId) {
    return ParseObject.createWithoutData(className, objectId); 
  }

  public Object decode(Object object) {
    if (object instanceof JSONArray) {
      return convertJSONArrayToList((JSONArray) object);
    }
    
    if (!(object instanceof JSONObject)) {
      return object;
    }
    
    JSONObject jsonObject = (JSONObject) object;

    String opString = jsonObject.optString("__op", null);
    if (opString != null) {
      try {
        return ParseFieldOperations.decode(jsonObject, this);
      } catch (JSONException e) {
        throw new RuntimeException(e);
      }
    }

    String typeString = jsonObject.optString("__type", null);
    if (typeString == null) {
      return convertJSONObjectToMap(jsonObject);
    }

    if (typeString.equals("Date")) {
      String iso = jsonObject.optString("iso");
      return ParseDateFormat.getInstance().parse(iso);
    }

    if (typeString.equals("Bytes")) {
      String base64 = jsonObject.optString("base64");
      return Base64.decode(base64, Base64.NO_WRAP);
    }

    if (typeString.equals("Pointer")) {
      return decodePointer(jsonObject.optString("className"),
          jsonObject.optString("objectId"));
    }

    if (typeString.equals("File")) {
      return new ParseFile(jsonObject, this);
    }

    if (typeString.equals("GeoPoint")) {
      double latitude, longitude;
      try {
        latitude = jsonObject.getDouble("latitude");
        longitude = jsonObject.getDouble("longitude");
      } catch (JSONException e) {
        throw new RuntimeException(e);
      }
      return new ParseGeoPoint(latitude, longitude);
    }

    if (typeString.equals("Object")) {
      return ParseObject.fromJSON(jsonObject, null, true, this);
    }

    if (typeString.equals("Relation")) {
      return new ParseRelation<>(jsonObject, this);
    }

    if (typeString.equals("OfflineObject")) {
      throw new RuntimeException("An unexpected offline pointer was encountered.");
    }
    
    return null;
  }
}