Skip to content

Commit

Permalink
[55336] No longer double-un/escaping json when invoking/receiving inv…
Browse files Browse the repository at this point in the history
…oked services from RVI per changes in RVI 0.5.0. Service now using gson totally too.

(cherry picked from commit a497e3bc00fb8e9cbaed19d4b352172461754817)
  • Loading branch information
lillialexis committed Mar 21, 2016
1 parent 26bbeba commit 69cc4aa
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 85 deletions.
19 changes: 12 additions & 7 deletions src/main/java/com/jaguarlandrover/rvi/DlinkReceivePacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ class DlinkReceivePacket extends DlinkPacket
/**
* The Service used to create the request params.
*/
private transient Service mService;
@SerializedName("data")
private Service mService;
// private transient Service mService;

/**
* The service is converted to a json string, then base64 encoded to be embedded in the packet's json.
*/
@SerializedName("data")
private String mData;
// @SerializedName("data")
// private String mData;

/**
* Instantiates a new Dlink receive packet.
Expand All @@ -57,8 +59,11 @@ class DlinkReceivePacket extends DlinkPacket
super(Command.RECEIVE);

mMod = "proto_json_rpc";
mService = service; // TODO: With this paradigm, if one of the parameters of mService changes, mData string will still be the same.
mData = mService.jsonString();//Base64.encodeToString(mService.jsonString().getBytes(), Base64.DEFAULT);
mService = service;


// TODO: With this paradigm, if one of the parameters of mService changes, mData string will still be the same.
//mData = mService.jsonString();//Base64.encodeToString(mService.jsonString().getBytes(), Base64.DEFAULT);
}

// public DlinkReceivePacket(HashMap jsonHash) {
Expand All @@ -75,8 +80,8 @@ class DlinkReceivePacket extends DlinkPacket
* @return the service that is being invoked
*/
Service getService() {
if (mService == null && mData != null)
mService = new Service(mData);//new String(Base64.decode(mData, Base64.DEFAULT)));
// if (mService == null && mData != null)
// mService = new Service(mData);//new String(Base64.decode(mData, Base64.DEFAULT)));

return mService;
}
Expand Down
160 changes: 82 additions & 78 deletions src/main/java/com/jaguarlandrover/rvi/Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.google.gson.internal.LinkedTreeMap;

import java.util.ArrayList;
Expand All @@ -29,18 +30,27 @@ class Service
{
private final static String TAG = "RVI:Service";

private String mServiceIdentifier;
@SerializedName("service")
private String mJsonService = null;

private String mBundleIdentifier;
@SerializedName("parameters")
private Object mJsonParameters = null;

private String mDomain;
private String mServiceIdentifier = null;

private String mNodeIdentifier;
private String mBundleIdentifier = null;

private Object mParameters;
private String mDomain = null;

private String mNodeIdentifier = null;

private Object mParameters = null;

@SerializedName("timeout")
private Long mTimeout;

Service() {}

/**
* Instantiates a new Vehicle service.
*
Expand All @@ -54,6 +64,8 @@ class Service
mBundleIdentifier = bundleIdentifier;
mDomain = domain;
mNodeIdentifier = prefix;

mJsonService = getFullyQualifiedServiceName();
}

HashMap unwrap(ArrayList<LinkedTreeMap> parameters) {
Expand All @@ -65,60 +77,40 @@ HashMap unwrap(ArrayList<LinkedTreeMap> parameters) {

return unwrapped;
}
/**
* Instantiates a new Vehicle service.
*
* @param jsonString the json string
*/
Service(String jsonString) {
Log.d(TAG, "Service data: " + jsonString);

Gson gson = new Gson();
HashMap jsonHash = gson.fromJson(jsonString, HashMap.class);

String[] serviceParts = ((String) jsonHash.get("service")).split("/");

if (serviceParts.length != 5) return;

mDomain = serviceParts[0];
mNodeIdentifier = serviceParts[1] + "/" + serviceParts[2];
mBundleIdentifier = serviceParts[3];
mServiceIdentifier = serviceParts[4];
/* If the Service object was deserialized from json, mParameters field might not yet have been unwrapped, but the mJsonParameters
field will be set. If this is the case, unwrap the mJsonParameters field into something more easily consumable and set mParameters.
We only have the intermediary value here, because RVI sends parameters as a _list_ of single-kvpair objects, instead of one
multi-kvpair object. This gives up the opportunity to unwrap the list into an object. */
private Boolean shouldParseParameters() {
return mJsonParameters != null && mParameters == null;
}

private void parseParamters() {
// TODO: Why are parameters arrays of object, not just an object? This should probably get fixed everywhere.
if (jsonHash.get("parameters").getClass().equals(ArrayList.class) && ((ArrayList<LinkedTreeMap>)jsonHash.get("parameters")).size() == 1)
mParameters = ((ArrayList<LinkedTreeMap>) jsonHash.get("parameters")).get(0);
else if (jsonHash.get("parameters").getClass().equals(ArrayList.class) && ((ArrayList<LinkedTreeMap>)jsonHash.get("parameters")).size() > 1)
mParameters = unwrap((ArrayList<LinkedTreeMap>) jsonHash.get("parameters"));
if (mJsonParameters.getClass().equals(ArrayList.class) && ((ArrayList<LinkedTreeMap>)mJsonParameters).size() == 1)
mParameters = ((ArrayList<LinkedTreeMap>) mJsonParameters).get(0);
else if (mJsonParameters.getClass().equals(ArrayList.class) && ((ArrayList<LinkedTreeMap>)mJsonParameters).size() > 1)
mParameters = unwrap((ArrayList<LinkedTreeMap>) mJsonParameters);
else
mParameters = jsonHash.get("parameters");
mParameters = mJsonParameters;
}

/**
* Gets parameters.
*
* @return the parameters
*/
Object getParameters() {
return mParameters;
/* If the Service object was deserialized from json, some of its fields might not be set, but the mJsonService field will be set.
If this is the case, parse out the mJsonService field into its parts and set the rest of the fields. */
private Boolean shouldParseServiceName() {
return mJsonService != null && (mDomain == null || mNodeIdentifier == null || mBundleIdentifier == null || mServiceIdentifier == null);
}

/**
* Sets parameters.
*
* @param parameters the parameters
*/
void setParameters(Object parameters) {
this.mParameters = parameters;
}
private void parseFullyQualifiedServiceName() {
String[] serviceParts = mJsonService.split("/");

/**
* Gets service identifier.
*
* @return the service identifier
*/
String getServiceIdentifier() {
return mServiceIdentifier;
if (serviceParts.length != 5) return;

mDomain = serviceParts[0];
mNodeIdentifier = serviceParts[1] + "/" + serviceParts[2];
mBundleIdentifier = serviceParts[3];
mServiceIdentifier = serviceParts[4];
}

/**
Expand All @@ -127,6 +119,9 @@ String getServiceIdentifier() {
* @return the fully qualified service name
*/
String getFullyQualifiedServiceName() {
if (shouldParseServiceName())
parseFullyQualifiedServiceName();

return mDomain + "/" + mNodeIdentifier + "/" + mBundleIdentifier + "/" + mServiceIdentifier;
}

Expand All @@ -141,34 +136,25 @@ boolean hasNodeIdentifier() {
}

/**
* Generate request params.
* Sets the node identifier portion of the fully-qualified service name
*
* @return the object
* @param nodeIdentifier the local or remote RVI node's identifier
*/
Object generateRequestParams() {
HashMap<String, Object> params = new HashMap<>(4);

params.put("service", getFullyQualifiedServiceName());
params.put("parameters", mParameters);//Arrays.asList(mParameters));
params.put("timeout", mTimeout);
params.put("tid", 1); // TODO: Please tell me we can not have this here
//params.put("signature", "signature");
//params.put("certificate", "certificate");

return params;
void setNodeIdentifier(String nodeIdentifier) {
mNodeIdentifier = nodeIdentifier;
mJsonService = getFullyQualifiedServiceName();
}

/**
* Json string.
* Gets the domain.
*
* @return the string
* @return the domain
*/
String jsonString() {
Gson gson = new Gson();

Log.d(TAG, "Service data: " + gson.toJson(generateRequestParams()));
String getDomain() {
if (shouldParseServiceName())
parseFullyQualifiedServiceName();

return gson.toJson(generateRequestParams());
return mDomain;
}

/**
Expand All @@ -177,25 +163,43 @@ String jsonString() {
* @return the bundle identifier
*/
String getBundleIdentifier() {
if (shouldParseServiceName())
parseFullyQualifiedServiceName();

return mBundleIdentifier;
}

/**
* Gets the domain.
* Gets service identifier.
*
* @return the domain
* @return the service identifier
*/
String getDomain() {
return mDomain;
String getServiceIdentifier() {
if (shouldParseServiceName())
parseFullyQualifiedServiceName();

return mServiceIdentifier;
}

/**
* Sets the node identifier portion of the fully-qualified service name
* Gets parameters.
*
* @param nodeIdentifier the local or remote RVI node's identifier
* @return the parameters
*/
void setNodeIdentifier(String nodeIdentifier) {
mNodeIdentifier = nodeIdentifier;
Object getParameters() {
if (shouldParseParameters())
parseParamters();

return mParameters;
}

/**
* Sets parameters.
*
* @param parameters the parameters
*/
void setParameters(Object parameters) {
this.mParameters = this.mJsonParameters = parameters;
}

/**
Expand Down

0 comments on commit 69cc4aa

Please sign in to comment.