summaryrefslogtreecommitdiff
path: root/sdl_android/src/main/java/com/smartdevicelink/marshal/JsonRPCMarshaller.java
blob: 414538a19178b50756d803002c93a50c9e9323c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.smartdevicelink.marshal;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

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

import com.smartdevicelink.proxy.RPCMessage;
import com.smartdevicelink.proxy.RPCStruct;
import com.smartdevicelink.trace.*;
import com.smartdevicelink.trace.enums.InterfaceActivityDirection;
import com.smartdevicelink.util.DebugTool;

/*
 * Responsible for marshalling and unmarshing between RPC Objects and byte streams that are sent
 * over transmission
 */

public class JsonRPCMarshaller {
	
	private static final String SDL_LIB_PRIVATE_KEY = "42baba60-eb57-11df-98cf-0800200c9a66";
	
	public static byte[] marshall(RPCMessage msg, byte version) {
		byte[] jsonBytes = null;
		try {
			JSONObject jsonObject = msg.serializeJSON(version);
			jsonBytes = jsonObject.toString().getBytes();
			
			SdlTrace.logMarshallingEvent(InterfaceActivityDirection.Transmit, jsonBytes, SDL_LIB_PRIVATE_KEY);
		} catch (JSONException e) {
			DebugTool.logError("Failed to encode messages to JSON.", e);
		}
		return jsonBytes;
	}
	
	public static Hashtable<String, Object> unmarshall(byte[] message) {
		SdlTrace.logMarshallingEvent(InterfaceActivityDirection.Receive, message, SDL_LIB_PRIVATE_KEY);
		Hashtable<String, Object> ret = null;
		try {
			String jsonString = new String(message);
			JSONObject jsonObject = new JSONObject(jsonString);
			ret = deserializeJSONObject(jsonObject);
		} catch (JSONException e) {
			DebugTool.logError("Failed to parse JSON", e);
		}
		return ret;
	}
	
	@SuppressWarnings("unchecked")
    public static Hashtable<String, Object> deserializeJSONObject(JSONObject jsonObject) 
			throws JSONException {
		Hashtable<String, Object> ret = new Hashtable<String, Object>();
		Iterator<String> it = jsonObject.keys();
		String key = null;
		while (it.hasNext()) {
			key = it.next();
			Object value = jsonObject.get(key);
			if (value instanceof JSONObject) {
				ret.put(key, deserializeJSONObject((JSONObject)value));
			} else if (value instanceof JSONArray) {
				JSONArray arrayValue = (JSONArray) value;
				List<Object> putList = new ArrayList<Object>(arrayValue.length());
				for (int i = 0; i < arrayValue.length(); i++) {
					Object anObject = arrayValue.get(i); 
					if (anObject instanceof JSONObject) {
						Hashtable<String, Object> deserializedObject = deserializeJSONObject((JSONObject)anObject);
						putList.add(deserializedObject);
					} else {
						putList.add(anObject);
					}
				}
				ret.put(key, putList);
			} else {
				ret.put(key, value);
			}
		}
		return ret;
	}

    @SuppressWarnings("unchecked")
	private static JSONArray serializeList(List<?> list) throws JSONException{
		JSONArray toPut = new JSONArray();
		Iterator<Object> valueIterator = (Iterator<Object>) list.iterator();
		while(valueIterator.hasNext()){
			Object anObject = valueIterator.next();
			if (anObject instanceof RPCStruct) {
				RPCStruct toSerialize = (RPCStruct) anObject;
				toPut.put(toSerialize.serializeJSON());
			} else if(anObject instanceof Hashtable){
				Hashtable<String, Object> toSerialize = (Hashtable<String, Object>)anObject;
				toPut.put(serializeHashtable(toSerialize));
			} else {
				toPut.put(anObject);
			}
		}
		return toPut;
	}

	@SuppressWarnings({"unchecked" })
    public static JSONObject serializeHashtable(Hashtable<String, Object> hash) throws JSONException{
		JSONObject obj = new JSONObject();
		Iterator<String> hashKeyIterator = hash.keySet().iterator();
		while (hashKeyIterator.hasNext()){
			String key = (String) hashKeyIterator.next();
			Object value = hash.get(key);
			if (value instanceof RPCStruct) {
				obj.put(key, ((RPCStruct) value).serializeJSON());
			} else if (value instanceof List<?>) {
				obj.put(key, serializeList((List<?>) value));
			} else if (value instanceof Hashtable) {
				obj.put(key, serializeHashtable((Hashtable<String, Object>)value));
			} else {
				obj.put(key, value);
			}
		}
		return obj;
	}
}