ParseApplication/ExternalLibs/Parse-SDK-Android/Parse/src/main/java/com/parse/ParseUserCurrentCoder.java

129 lines
4.3 KiB
Java

/*
* 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 org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import static com.parse.ParseUser.State;
/**
* Handles encoding/decoding ParseUser to/from /2 format JSON. /2 format json is only used for
* persisting current ParseUser and ParseInstallation to disk when LDS is not enabled.
*/
/** package */ class ParseUserCurrentCoder extends ParseObjectCurrentCoder {
private static final String KEY_AUTH_DATA = "auth_data";
private static final String KEY_SESSION_TOKEN = "session_token";
private static final ParseUserCurrentCoder INSTANCE = new ParseUserCurrentCoder();
public static ParseUserCurrentCoder get() {
return INSTANCE;
}
/* package */ ParseUserCurrentCoder() {
// do nothing
}
/**
* Converts a ParseUser state to /2/ JSON representation suitable for saving to disk.
*
* <pre>
* {
* data: {
* // data fields, including objectId, createdAt, updatedAt
* },
* classname: class name for the object,
* operations: { } // operations per field
* }
* </pre>
*
* All keys are included, regardless of whether they are dirty.
* We also add sessionToken and authData to the json.
*
* @see #decode(ParseObject.State.Init, JSONObject, ParseDecoder)
*/
@Override
public <T extends ParseObject.State> JSONObject encode(
T state, ParseOperationSet operations, ParseEncoder encoder) {
// FYI we'll be double writing sessionToken and authData for now...
// This is important. super.encode() has no notion of sessionToken and authData, so it treats them
// like objects (simply passed to the encoder). This means that a null sessionToken will become
// JSONObject.NULL. This must be accounted in #decode().
JSONObject objectJSON = super.encode(state, operations, encoder);
String sessionToken = ((State) state).sessionToken();
if (sessionToken != null) {
try {
objectJSON.put(KEY_SESSION_TOKEN, sessionToken);
} catch (JSONException e) {
throw new RuntimeException("could not encode value for key: session_token");
}
}
Map<String, Map<String, String>> authData = ((State) state).authData();
if (authData.size() > 0) {
try {
objectJSON.put(KEY_AUTH_DATA, encoder.encode(authData));
} catch (JSONException e) {
throw new RuntimeException("could not attach key: auth_data");
}
}
return objectJSON;
}
/**
* Merges from JSON in /2/ format.
*
* This is only used to read ParseUser state stored on disk in JSON.
* Since in encode we add sessionToken and authData to the json, we need remove them from json
* to generate state.
*
* @see #encode(ParseObject.State, ParseOperationSet, ParseEncoder)
*/
@Override
public <T extends ParseObject.State.Init<?>> T decode(
T builder, JSONObject json, ParseDecoder decoder) {
ParseUser.State.Builder userBuilder = (State.Builder) super.decode(builder, json, decoder);
// super.decode will read its own values and add them to the builder using put().
// This means the state for session token and auth data might be illegal, returning
// unexpected types. For instance if sessionToken was null, now it's JSONObject.NULL.
// We must overwrite these possibly wrong values.
String newSessionToken = json.optString(KEY_SESSION_TOKEN, null);
userBuilder.sessionToken(newSessionToken);
JSONObject newAuthData = json.optJSONObject(KEY_AUTH_DATA);
if (newAuthData == null) {
userBuilder.authData(null);
} else {
try {
@SuppressWarnings("rawtypes")
Iterator i = newAuthData.keys();
while (i.hasNext()) {
String key = (String) i.next();
if (!newAuthData.isNull(key)) {
userBuilder.putAuthData(key,
(Map<String, String>) ParseDecoder.get().decode(newAuthData.getJSONObject(key)));
}
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
return (T) userBuilder;
}
}