mirror of https://github.com/apache/jclouds.git
Issue 797: gson 2+ addresses gson issue 325
This commit is contained in:
parent
92a926d655
commit
82c1d11191
|
@ -1,92 +0,0 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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 com.google.gson;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.json.internal.ParseObjectFromElement;
|
||||
|
||||
import com.google.gson.internal.$Gson$Types;
|
||||
|
||||
/**
|
||||
* Default serialization and deserialization of a map type. This implementation really only works
|
||||
* well with simple primitive types as the map key. If the key is not a simple primitive then the
|
||||
* object is {@code toString}ed and that value is used as its key.
|
||||
* <p/>
|
||||
* Patched depending on <a href="http://code.google.com/p/google-gson/issues/detail?id=325">this</a>
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class ObjectMapTypeAdapter extends BaseMapTypeAdapter {
|
||||
|
||||
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject map = new JsonObject();
|
||||
Type childGenericType = null;
|
||||
if (typeOfSrc instanceof ParameterizedType) {
|
||||
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc);
|
||||
childGenericType = $Gson$Types.getMapKeyAndValueTypes(typeOfSrc, rawTypeOfSrc)[1];
|
||||
}
|
||||
|
||||
for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
|
||||
JsonElement valueElement;
|
||||
if (value == null) {
|
||||
valueElement = JsonNull.createJsonNull();
|
||||
} else {
|
||||
Type childType = (childGenericType == null)
|
||||
? value.getClass() : childGenericType;
|
||||
valueElement = serialize(context, value, childType);
|
||||
}
|
||||
map.add(String.valueOf(entry.getKey()), valueElement);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
||||
// This handles cases where users are using their own subclass of Map.
|
||||
Map<Object, Object> map = constructMapType(typeOfT, context);
|
||||
Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(typeOfT, $Gson$Types.getRawType(typeOfT));
|
||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueTypes[0]);
|
||||
// START JCLOUDS PATCH
|
||||
// http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
Object value = null;
|
||||
if (keyAndValueTypes[1] == Object.class) {
|
||||
value = ParseObjectFromElement.SINGLETON.apply(entry.getValue());
|
||||
}
|
||||
if (value == null) {
|
||||
value = context.deserialize(entry.getValue(), keyAndValueTypes[1]);
|
||||
}
|
||||
// END JCLOUDS PATCH
|
||||
map.put(key, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MapTypeAdapter.class.getSimpleName();
|
||||
}
|
||||
}
|
|
@ -51,7 +51,6 @@ import com.google.gson.JsonParseException;
|
|||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.ObjectMapTypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
@ -74,7 +73,6 @@ public class GsonModule extends AbstractModule {
|
|||
GsonBuilder builder = new GsonBuilder();
|
||||
Logger.getLogger("com.google.gson.ParameterizedTypeHandlerMap").setLevel(Level.OFF);
|
||||
builder.registerTypeHierarchyAdapter(Enum.class, new EnumTypeAdapterThatReturnsFromValue());
|
||||
builder.registerTypeHierarchyAdapter(Map.class, new ObjectMapTypeAdapter());
|
||||
builder.registerTypeAdapter(JsonBall.class, jsonAdapter);
|
||||
builder.registerTypeAdapter(Date.class, adapter);
|
||||
builder.registerTypeAdapter(Properties.class, propertiesAdapter);
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.json.internal;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* Exposes the JsonObject as a map so that we can use gauva apis on it.
|
||||
* http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum JsonObjectAsMap implements Function<JsonObject, Map<String, JsonElement>> {
|
||||
INSTANCE;
|
||||
|
||||
private final Field members;
|
||||
|
||||
JsonObjectAsMap() {
|
||||
try {
|
||||
members = JsonObject.class.getDeclaredField("members");
|
||||
members.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new UnsupportedOperationException("cannot access gson internals", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Map<String, JsonElement> apply(JsonObject in) {
|
||||
try {
|
||||
return (Map<String, JsonElement>) members.get(in);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new UnsupportedOperationException("cannot access gson internals", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new UnsupportedOperationException("cannot access gson internals", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.json.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
/**
|
||||
* This is a class that helps the default {@link MapTypeAdapter} make a sane object graph when the
|
||||
* value is set to {@code Object}
|
||||
* http://code.google.com/p/google-gson/issues/detail?id=325
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ParseObjectFromElement implements Function<JsonElement, Object> {
|
||||
SINGLETON;
|
||||
public Object apply(JsonElement input) {
|
||||
Object value = null;
|
||||
if (input == null || input.isJsonNull()) {
|
||||
value = null;
|
||||
} else if (input.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = input.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
value = primitive.getAsNumber();
|
||||
} else if (primitive.isBoolean()) {
|
||||
value = primitive.getAsBoolean();
|
||||
} else {
|
||||
value = primitive.getAsString();
|
||||
}
|
||||
} else if (input.isJsonArray()) {
|
||||
value = Lists.newArrayList(Iterables.transform(input.getAsJsonArray(), this));
|
||||
} else if (input.isJsonObject()) {
|
||||
value = Maps.<String,Object>newLinkedHashMap(Maps.transformValues(JsonObjectAsMap.INSTANCE.apply(input.getAsJsonObject()),
|
||||
this));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue