/** * Copyright 2010 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.waveprotocol.wave.communication.gson; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import org.waveprotocol.wave.communication.json.JsonLongHelper; import org.waveprotocol.wave.communication.json.RawStringData; /** * Utilities for working with GsonSerializable objects * */ public class GsonUtil { /** * A wrapper routine used to catch exceptions thrown while parsing and convert * them to GsonExceptions * * @param <T> A GsonSerializable object class * @param obj The object * @param json The root of a tree of JsonElements * @param gson The gson object used to parse multi-stage json * @param data The raw data object that contains the substring * @return The provided object * @throws GsonException */ public static <T extends GsonSerializable> T parseGson(T obj, JsonElement json, Gson gson, RawStringData data) throws GsonException { try { obj.fromGson(json, gson, data); return obj; } catch (IllegalArgumentException e) { throw new GsonException("Unable to parse JSON", e); } catch (IllegalStateException e) { throw new GsonException("Unable to parse JSON", e); } catch (UnsupportedOperationException e) { throw new GsonException("Unable to parse JSON", e); } } /** * A wrapper routine used to catch exceptions thrown while parsing and convert * them to GsonExceptions * * @param <T> The type to deserialize * @param gson A Gson context * @param json The json string to interpret * @throws GsonException */ public static <T extends GsonSerializable> void parseJson(T object, Gson gson, String json, RawStringData data) throws GsonException { try { JsonElement root = new JsonParser().parse(json); object.fromGson(root, gson, data); } catch (JsonParseException e) { throw new GsonException("Unable to parse Json", e); } } /** * A wrapper routine used to catch exceptions thrown while parsing and convert * them to GsonExceptions * * @param <T> The type to deserialize * @param gson A Gson context * @param json The json string to interpret * @param clazz The class object representing T * @return An instance representing the parsed json * @throws GsonException */ public static <T> T parseJson(Gson gson, String json, Class<T> clazz) throws GsonException { try { return gson.fromJson(json, clazz); } catch (JsonParseException e) { throw new GsonException("Unable to parse Json", e); } } /** * Unpack a JsonElement into the object type * * @param <T> The type to deserialize * @param object The object used to accept the pare result * @param valueObj The root of a tree of JsonElements or an indirection index * @param gson A Gson context * @param raw * @throws GsonException */ public static <T extends GsonSerializable> void extractJsonObject(T object, JsonElement valueObj, Gson gson, RawStringData raw) throws GsonException { if (valueObj.isJsonObject()) { object.fromGson(valueObj.getAsJsonObject(), gson, raw); } else if (valueObj.isJsonPrimitive()) { JsonPrimitive primitive = valueObj.getAsJsonPrimitive(); String s = null; if (raw == null || !primitive.isString()) { throw new GsonException("Decoding " + valueObj + " as object " + object.getClass() + " with no RawStringData given"); } s = raw.getString(valueObj.getAsString()); GsonUtil.parseJson(object, gson, s, raw); } else { throw new GsonException("Cannot decode valueObject " + valueObj.getClass() + " as object " + object.getClass()); } } /** * Faithfully serializes a 64-bit long value as a two-number array. */ public static JsonArray toJson(long value) { JsonArray arr = new JsonArray(); arr.add(new JsonPrimitive(JsonLongHelper.getLowWord(value))); arr.add(new JsonPrimitive(JsonLongHelper.getHighWord(value))); return arr; } /** * Deserializes a two-number array from {@link #toJson(long)} into a long. */ public static long fromJson(JsonElement e) { JsonArray arr = e.getAsJsonArray(); return JsonLongHelper.toLong(arr.get(1).getAsInt(), arr.get(0).getAsInt()); } private GsonUtil() { } }