updating built-in GSON to 1.7.1 release

This commit is contained in:
Brettflan 2011-06-22 18:40:56 -05:00
parent ef2de46dd6
commit 6035b204dc
67 changed files with 2044 additions and 1625 deletions

View File

@ -16,7 +16,6 @@
package org.mcteam.factions.gson;
/**
* Strategy for excluding anonymous and local classes.
*

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2011 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.mcteam.factions.gson;
import java.lang.reflect.Type;
import java.util.Map;
/**
* Captures all the common/shared logic between the old, ({@link MapTypeAdapter}, and
* the new, {@link MapAsArrayTypeAdapter}, map type adapters.
*
* @author Joel Leitch
*/
abstract class BaseMapTypeAdapter
implements JsonSerializer<Map<?, ?>>, JsonDeserializer<Map<?, ?>> {
protected static final JsonElement serialize(JsonSerializationContext context,
Object src, Type srcType) {
JsonSerializationContextDefault contextImpl = (JsonSerializationContextDefault) context;
return contextImpl.serialize(src, srcType, false);
}
@SuppressWarnings("unchecked")
protected static final Map<Object, Object> constructMapType(
Type mapType, JsonDeserializationContext context) {
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
return (Map<Object, Object>) objectConstructor.construct(mapType);
}
}

View File

@ -48,14 +48,4 @@ interface Cache<K, V> {
* @return the value for the given {@code key}
*/
V removeElement(K key);
/**
* Removes everything from this cache.
*/
void clear();
/**
* @return the number of objects in this cache
*/
int size();
}

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;
@ -51,8 +53,8 @@ final class CamelCaseSeparatorNamingPolicy extends RecursiveFieldNamingPolicy {
* is null or empty.
*/
public CamelCaseSeparatorNamingPolicy(String separatorString) {
Preconditions.checkNotNull(separatorString);
Preconditions.checkArgument(!"".equals(separatorString));
$Gson$Preconditions.checkNotNull(separatorString);
$Gson$Preconditions.checkArgument(!"".equals(separatorString));
this.separatorString = separatorString;
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (C) 2011 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.mcteam.factions.gson;
import java.lang.reflect.Constructor;
/**
* Use the default constructor on the class to instantiate an object.
*
* @author Joel Leitch
*/
final class DefaultConstructorAllocator {
private static final Constructor<Null> NULL_CONSTRUCTOR = createNullConstructor();
private final Cache<Class<?>, Constructor<?>> constructorCache;
public DefaultConstructorAllocator() {
this(200);
}
public DefaultConstructorAllocator(int cacheSize) {
constructorCache = new LruCache<Class<?>, Constructor<?>>(cacheSize);
}
// for testing purpose
final boolean isInCache(Class<?> cacheKey) {
return constructorCache.getElement(cacheKey) != null;
}
private static final Constructor<Null> createNullConstructor() {
try {
return getNoArgsConstructor(Null.class);
} catch (Exception e) {
return null;
}
}
public <T> T newInstance(Class<T> c) throws Exception {
Constructor<T> constructor = findConstructor(c);
return (constructor != null) ? constructor.newInstance() : null;
}
@SuppressWarnings("unchecked")
private <T> Constructor<T> findConstructor(Class<T> c) {
Constructor<T> cachedElement = (Constructor<T>) constructorCache.getElement(c);
if (cachedElement != null) {
if (cachedElement == NULL_CONSTRUCTOR) {
return null;
} else {
return cachedElement;
}
}
Constructor<T> noArgsConstructor = getNoArgsConstructor(c);
if (noArgsConstructor != null) {
constructorCache.addElement(c, noArgsConstructor);
} else {
constructorCache.addElement(c, NULL_CONSTRUCTOR);
}
return noArgsConstructor;
}
private static <T> Constructor<T> getNoArgsConstructor(Class<T> c) {
try {
Constructor<T> declaredConstructor = c.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
return declaredConstructor;
} catch (Exception e) {
return null;
}
}
// placeholder class for Null constructor
private static final class Null {
}
}

View File

@ -16,19 +16,23 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@ -36,12 +40,14 @@ import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeSet;
import java.util.UUID;
@ -62,12 +68,14 @@ final class DefaultTypeAdapters {
private static final DefaultTimestampDeserializer TIMESTAMP_DESERIALIZER =
new DefaultTimestampDeserializer();
@SuppressWarnings("rawtypes")
@SuppressWarnings("unchecked")
private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter();
private static final UrlTypeAdapter URL_TYPE_ADAPTER = new UrlTypeAdapter();
private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter();
private static final UuidTypeAdapter UUUID_TYPE_ADAPTER = new UuidTypeAdapter();
private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter();
private static final DefaultInetAddressAdapter INET_ADDRESS_ADAPTER =
new DefaultInetAddressAdapter();
private static final CollectionTypeAdapter COLLECTION_TYPE_ADAPTER = new CollectionTypeAdapter();
private static final MapTypeAdapter MAP_TYPE_ADAPTER = new MapTypeAdapter();
private static final BigDecimalTypeAdapter BIG_DECIMAL_TYPE_ADAPTER = new BigDecimalTypeAdapter();
@ -83,10 +91,11 @@ final class DefaultTypeAdapters {
private static final NumberTypeAdapter NUMBER_TYPE_ADAPTER = new NumberTypeAdapter();
private static final ShortTypeAdapter SHORT_TYPE_ADAPTER = new ShortTypeAdapter();
private static final StringTypeAdapter STRING_TYPE_ADAPTER = new StringTypeAdapter();
private static final StringBuilderTypeAdapter STRING_BUILDER_TYPE_ADAPTER =
new StringBuilderTypeAdapter();
private static final StringBufferTypeAdapter STRING_BUFFER_TYPE_ADAPTER =
new StringBufferTypeAdapter();
private static final PropertiesCreator PROPERTIES_CREATOR = new PropertiesCreator();
private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator();
private static final HashSetCreator HASH_SET_CREATOR = new HashSetCreator();
private static final GregorianCalendarTypeAdapter GREGORIAN_CALENDAR_TYPE_ADAPTER =
new GregorianCalendarTypeAdapter();
@ -95,8 +104,12 @@ final class DefaultTypeAdapters {
// constants will appear as nulls.
private static final ParameterizedTypeHandlerMap<JsonSerializer<?>> DEFAULT_SERIALIZERS =
createDefaultSerializers();
static final ParameterizedTypeHandlerMap<JsonSerializer<?>> DEFAULT_HIERARCHY_SERIALIZERS =
createDefaultHierarchySerializers();
private static final ParameterizedTypeHandlerMap<JsonDeserializer<?>> DEFAULT_DESERIALIZERS =
createDefaultDeserializers();
static final ParameterizedTypeHandlerMap<JsonDeserializer<?>> DEFAULT_HIERARCHY_DESERIALIZERS =
createDefaultHierarchyDeserializers();
private static final ParameterizedTypeHandlerMap<InstanceCreator<?>> DEFAULT_INSTANCE_CREATORS =
createDefaultInstanceCreators();
@ -104,13 +117,10 @@ final class DefaultTypeAdapters {
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
map.registerForTypeHierarchy(Enum.class, ENUM_TYPE_ADAPTER);
map.register(URL.class, URL_TYPE_ADAPTER);
map.register(URI.class, URI_TYPE_ADAPTER);
map.register(UUID.class, UUUID_TYPE_ADAPTER);
map.register(Locale.class, LOCALE_TYPE_ADAPTER);
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
map.register(Date.class, DATE_TYPE_ADAPTER);
map.register(java.sql.Date.class, JAVA_SQL_DATE_TYPE_ADAPTER);
map.register(Timestamp.class, DATE_TYPE_ADAPTER);
@ -133,70 +143,106 @@ final class DefaultTypeAdapters {
map.register(Short.class, SHORT_TYPE_ADAPTER);
map.register(short.class, SHORT_TYPE_ADAPTER);
map.register(String.class, STRING_TYPE_ADAPTER);
map.register(StringBuilder.class, STRING_BUILDER_TYPE_ADAPTER);
map.register(StringBuffer.class, STRING_BUFFER_TYPE_ADAPTER);
map.makeUnmodifiable();
return map;
}
private static ParameterizedTypeHandlerMap<JsonSerializer<?>> createDefaultHierarchySerializers() {
ParameterizedTypeHandlerMap<JsonSerializer<?>> map =
new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
map.registerForTypeHierarchy(Enum.class, ENUM_TYPE_ADAPTER);
map.registerForTypeHierarchy(InetAddress.class, INET_ADDRESS_ADAPTER);
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
map.makeUnmodifiable();
return map;
}
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultDeserializers() {
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
map.registerForTypeHierarchy(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER));
map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER));
map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER));
map.register(UUID.class, wrapDeserializer(UUUID_TYPE_ADAPTER));
map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER));
map.registerForTypeHierarchy(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER));
map.registerForTypeHierarchy(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
map.register(java.sql.Date.class, wrapDeserializer(JAVA_SQL_DATE_TYPE_ADAPTER));
map.register(Timestamp.class, wrapDeserializer(TIMESTAMP_DESERIALIZER));
map.register(Time.class, wrapDeserializer(TIME_TYPE_ADAPTER));
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER));
map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER));
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
// Add primitive deserializers
map.register(Boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
map.register(boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
map.register(Byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
map.register(byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
map.register(Byte.class, BYTE_TYPE_ADAPTER);
map.register(byte.class, BYTE_TYPE_ADAPTER);
map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
map.register(char.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
map.register(Double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
map.register(double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
map.register(Float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
map.register(float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
map.register(Integer.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
map.register(int.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
map.register(Long.class, wrapDeserializer(LONG_DESERIALIZER));
map.register(long.class, wrapDeserializer(LONG_DESERIALIZER));
map.register(Number.class, wrapDeserializer(NUMBER_TYPE_ADAPTER));
map.register(Short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
map.register(short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
map.register(Double.class, DOUBLE_TYPE_ADAPTER);
map.register(double.class, DOUBLE_TYPE_ADAPTER);
map.register(Float.class, FLOAT_TYPE_ADAPTER);
map.register(float.class, FLOAT_TYPE_ADAPTER);
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
map.register(int.class, INTEGER_TYPE_ADAPTER);
map.register(Long.class, LONG_DESERIALIZER);
map.register(long.class, LONG_DESERIALIZER);
map.register(Number.class, NUMBER_TYPE_ADAPTER);
map.register(Short.class, SHORT_TYPE_ADAPTER);
map.register(short.class, SHORT_TYPE_ADAPTER);
map.register(String.class, wrapDeserializer(STRING_TYPE_ADAPTER));
map.register(StringBuilder.class, wrapDeserializer(STRING_BUILDER_TYPE_ADAPTER));
map.register(StringBuffer.class, wrapDeserializer(STRING_BUFFER_TYPE_ADAPTER));
map.makeUnmodifiable();
return map;
}
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultHierarchyDeserializers() {
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map =
new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
map.registerForTypeHierarchy(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER));
map.registerForTypeHierarchy(InetAddress.class, wrapDeserializer(INET_ADDRESS_ADAPTER));
map.registerForTypeHierarchy(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER));
map.registerForTypeHierarchy(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
map.makeUnmodifiable();
return map;
}
@SuppressWarnings("unchecked")
private static ParameterizedTypeHandlerMap<InstanceCreator<?>> createDefaultInstanceCreators() {
ParameterizedTypeHandlerMap<InstanceCreator<?>> map =
new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
DefaultConstructorAllocator allocator = new DefaultConstructorAllocator(50);
// Map Instance Creators
map.registerForTypeHierarchy(Map.class,
new DefaultConstructorCreator<Map>(LinkedHashMap.class, allocator));
// Add Collection type instance creators
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
DefaultConstructorCreator<List> listCreator =
new DefaultConstructorCreator<List>(ArrayList.class, allocator);
DefaultConstructorCreator<Queue> queueCreator =
new DefaultConstructorCreator<Queue>(LinkedList.class, allocator);
DefaultConstructorCreator<Set> setCreator =
new DefaultConstructorCreator<Set>(HashSet.class, allocator);
DefaultConstructorCreator<SortedSet> sortedSetCreator =
new DefaultConstructorCreator<SortedSet>(TreeSet.class, allocator);
map.registerForTypeHierarchy(Collection.class, listCreator);
map.registerForTypeHierarchy(Queue.class, queueCreator);
map.registerForTypeHierarchy(Set.class, setCreator);
map.registerForTypeHierarchy(SortedSet.class, sortedSetCreator);
map.registerForTypeHierarchy(Set.class, HASH_SET_CREATOR);
map.registerForTypeHierarchy(SortedSet.class, TREE_SET_CREATOR);
map.register(Properties.class, PROPERTIES_CREATOR);
map.makeUnmodifiable();
return map;
}
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings("unchecked")
private static JsonDeserializer<?> wrapDeserializer(JsonDeserializer<?> deserializer) {
return new JsonDeserializerExceptionWrapper(deserializer);
}
@ -205,6 +251,20 @@ final class DefaultTypeAdapters {
return getDefaultSerializers(false, LongSerializationPolicy.DEFAULT);
}
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getAllDefaultSerializers() {
ParameterizedTypeHandlerMap<JsonSerializer<?>> defaultSerializers =
getDefaultSerializers(false, LongSerializationPolicy.DEFAULT);
defaultSerializers.register(DEFAULT_HIERARCHY_SERIALIZERS);
return defaultSerializers;
}
static ParameterizedTypeHandlerMap<JsonDeserializer<?>> getAllDefaultDeserializers() {
ParameterizedTypeHandlerMap<JsonDeserializer<?>> defaultDeserializers =
getDefaultDeserializers().copyOf();
defaultDeserializers.register(DEFAULT_HIERARCHY_DESERIALIZERS);
return defaultDeserializers;
}
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers(
boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy) {
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers =
@ -240,30 +300,45 @@ final class DefaultTypeAdapters {
return DEFAULT_INSTANCE_CREATORS;
}
static class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat format;
/**
* This type adapter supports three subclasses of date: Date, Timestamp, and
* java.sql.Date.
*/
static final class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat enUsFormat;
private final DateFormat localFormat;
private final DateFormat iso8601Format;
DefaultDateTypeAdapter() {
this.format = DateFormat.getDateTimeInstance();
this(DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US),
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT));
}
DefaultDateTypeAdapter(final String datePattern) {
this.format = new SimpleDateFormat(datePattern);
DefaultDateTypeAdapter(String datePattern) {
this(new SimpleDateFormat(datePattern, Locale.US), new SimpleDateFormat(datePattern));
}
DefaultDateTypeAdapter(final int style) {
this.format = DateFormat.getDateInstance(style);
DefaultDateTypeAdapter(int style) {
this(DateFormat.getDateInstance(style, Locale.US), DateFormat.getDateInstance(style));
}
public DefaultDateTypeAdapter(final int dateStyle, final int timeStyle) {
this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
this(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US),
DateFormat.getDateTimeInstance(dateStyle, timeStyle));
}
DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) {
this.enUsFormat = enUsFormat;
this.localFormat = localFormat;
this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
}
// These methods need to be synchronized since JDK DateFormat classes are not thread-safe
// See issue 162
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
synchronized (format) {
String dateFormatAsString = format.format(src);
synchronized (localFormat) {
String dateFormatAsString = enUsFormat.format(src);
return new JsonPrimitive(dateFormatAsString);
}
}
@ -273,12 +348,33 @@ final class DefaultTypeAdapters {
if (!(json instanceof JsonPrimitive)) {
throw new JsonParseException("The date should be a string value");
}
try {
synchronized (format) {
return format.parse(json.getAsString());
Date date = deserializeToDate(json);
if (typeOfT == Date.class) {
return date;
} else if (typeOfT == Timestamp.class) {
return new Timestamp(date.getTime());
} else if (typeOfT == java.sql.Date.class) {
return new java.sql.Date(date.getTime());
} else {
throw new IllegalArgumentException(getClass() + " cannot deserialize to " + typeOfT);
}
}
private Date deserializeToDate(JsonElement json) {
synchronized (localFormat) {
try {
return localFormat.parse(json.getAsString());
} catch (ParseException ignored) {
}
try {
return enUsFormat.parse(json.getAsString());
} catch (ParseException ignored) {
}
try {
return iso8601Format.parse(json.getAsString());
} catch (ParseException e) {
throw new JsonSyntaxException(e);
throw new JsonSyntaxException(json.getAsString(), e);
}
}
}
@ -286,12 +382,12 @@ final class DefaultTypeAdapters {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(DefaultDateTypeAdapter.class.getSimpleName());
sb.append('(').append(format.getClass().getSimpleName()).append(')');
sb.append('(').append(localFormat.getClass().getSimpleName()).append(')');
return sb.toString();
}
}
static class DefaultJavaSqlDateTypeAdapter implements JsonSerializer<java.sql.Date>,
static final class DefaultJavaSqlDateTypeAdapter implements JsonSerializer<java.sql.Date>,
JsonDeserializer<java.sql.Date> {
private final DateFormat format;
DefaultJavaSqlDateTypeAdapter() {
@ -322,7 +418,7 @@ final class DefaultTypeAdapters {
}
}
static class DefaultTimestampDeserializer implements JsonDeserializer<Timestamp> {
static final class DefaultTimestampDeserializer implements JsonDeserializer<Timestamp> {
public Timestamp deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
Date date = context.deserialize(json, Date.class);
@ -330,7 +426,7 @@ final class DefaultTypeAdapters {
}
}
static class DefaultTimeTypeAdapter implements JsonSerializer<Time>, JsonDeserializer<Time> {
static final class DefaultTimeTypeAdapter implements JsonSerializer<Time>, JsonDeserializer<Time> {
private final DateFormat format;
DefaultTimeTypeAdapter() {
this.format = new SimpleDateFormat("hh:mm:ss a");
@ -357,7 +453,7 @@ final class DefaultTypeAdapters {
}
}
private static class GregorianCalendarTypeAdapter
private static final class GregorianCalendarTypeAdapter
implements JsonSerializer<GregorianCalendar>, JsonDeserializer<GregorianCalendar> {
private static final String YEAR = "year";
@ -397,8 +493,26 @@ final class DefaultTypeAdapters {
}
}
static final class DefaultInetAddressAdapter
implements JsonDeserializer<InetAddress>, JsonSerializer<InetAddress> {
public InetAddress deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
try {
return InetAddress.getByName(json.getAsString());
} catch (UnknownHostException e) {
throw new JsonParseException(e);
}
}
public JsonElement serialize(InetAddress src, Type typeOfSrc,
JsonSerializationContext context) {
return new JsonPrimitive(src.getHostAddress());
}
}
@SuppressWarnings("unchecked")
private static class EnumTypeAdapter<T extends Enum<T>>
private static final class EnumTypeAdapter<T extends Enum<T>>
implements JsonSerializer<T>, JsonDeserializer<T> {
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.name());
@ -416,7 +530,7 @@ final class DefaultTypeAdapters {
}
}
private static class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> {
private static final class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> {
public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toExternalForm());
}
@ -436,7 +550,7 @@ final class DefaultTypeAdapters {
}
}
private static class UriTypeAdapter implements JsonSerializer<URI>, JsonDeserializer<URI> {
private static final class UriTypeAdapter implements JsonSerializer<URI>, JsonDeserializer<URI> {
public JsonElement serialize(URI src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toASCIIString());
}
@ -454,7 +568,7 @@ final class DefaultTypeAdapters {
}
}
private static class UuidTypeAdapter implements JsonSerializer<UUID>, JsonDeserializer<UUID> {
private static final class UuidTypeAdapter implements JsonSerializer<UUID>, JsonDeserializer<UUID> {
public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
@ -470,7 +584,7 @@ final class DefaultTypeAdapters {
}
}
private static class LocaleTypeAdapter
private static final class LocaleTypeAdapter
implements JsonSerializer<Locale>, JsonDeserializer<Locale> {
public JsonElement serialize(Locale src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
@ -507,9 +621,9 @@ final class DefaultTypeAdapters {
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static class CollectionTypeAdapter implements JsonSerializer<Collection>,
JsonDeserializer<Collection>, InstanceCreator<Collection> {
@SuppressWarnings("unchecked")
private static final class CollectionTypeAdapter implements JsonSerializer<Collection>,
JsonDeserializer<Collection> {
public JsonElement serialize(Collection src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null) {
return JsonNull.createJsonNull();
@ -517,7 +631,8 @@ final class DefaultTypeAdapters {
JsonArray array = new JsonArray();
Type childGenericType = null;
if (typeOfSrc instanceof ParameterizedType) {
childGenericType = new TypeInfoCollection(typeOfSrc).getElementType();
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc);
childGenericType = $Gson$Types.getCollectionElementType(typeOfSrc, rawTypeOfSrc);
}
for (Object child : src) {
if (child == null) {
@ -540,7 +655,7 @@ final class DefaultTypeAdapters {
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
// This handles cases where users are using their own subclass of Collection.
Collection collection = constructCollectionType(typeOfT, context);
Type childType = new TypeInfoCollection(typeOfT).getElementType();
Type childType = $Gson$Types.getCollectionElementType(typeOfT, $Gson$Types.getRawType(typeOfT));
for (JsonElement childElement : json.getAsJsonArray()) {
if (childElement == null || childElement.isJsonNull()) {
collection.add(null);
@ -558,76 +673,9 @@ final class DefaultTypeAdapters {
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
return (Collection) objectConstructor.construct(collectionType);
}
public Collection createInstance(Type type) {
return new LinkedList();
}
}
private static class PropertiesCreator implements InstanceCreator<Properties> {
public Properties createInstance(Type type) {
return new Properties();
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
static class MapTypeAdapter implements JsonSerializer<Map>, JsonDeserializer<Map>,
InstanceCreator<Map> {
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject map = new JsonObject();
Type childGenericType = null;
if (typeOfSrc instanceof ParameterizedType) {
childGenericType = new TypeInfoMap(typeOfSrc).getValueType();
}
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 = context.serialize(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);
TypeInfoMap mapTypeInfo = new TypeInfoMap(typeOfT);
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), mapTypeInfo.getKeyType());
Object value = context.deserialize(entry.getValue(), mapTypeInfo.getValueType());
map.put(key, value);
}
return map;
}
private Map constructMapType(Type mapType, JsonDeserializationContext context) {
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
return (Map) objectConstructor.construct(mapType);
}
public Map createInstance(Type type) {
return new LinkedHashMap();
}
@Override
public String toString() {
return MapTypeAdapter.class.getSimpleName();
}
}
private static class BigDecimalTypeAdapter
private static final class BigDecimalTypeAdapter
implements JsonSerializer<BigDecimal>, JsonDeserializer<BigDecimal> {
public JsonElement serialize(BigDecimal src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -635,7 +683,15 @@ final class DefaultTypeAdapters {
public BigDecimal deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
try {
return json.getAsBigDecimal();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -644,7 +700,7 @@ final class DefaultTypeAdapters {
}
}
private static class BigIntegerTypeAdapter
private static final class BigIntegerTypeAdapter
implements JsonSerializer<BigInteger>, JsonDeserializer<BigInteger> {
public JsonElement serialize(BigInteger src, Type typeOfSrc, JsonSerializationContext context) {
@ -653,7 +709,15 @@ final class DefaultTypeAdapters {
public BigInteger deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
try {
return json.getAsBigInteger();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -662,7 +726,7 @@ final class DefaultTypeAdapters {
}
}
private static class NumberTypeAdapter
private static final class NumberTypeAdapter
implements JsonSerializer<Number>, JsonDeserializer<Number> {
public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -670,7 +734,15 @@ final class DefaultTypeAdapters {
public Number deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsNumber();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -679,7 +751,7 @@ final class DefaultTypeAdapters {
}
}
private static class LongSerializer implements JsonSerializer<Long> {
private static final class LongSerializer implements JsonSerializer<Long> {
private final LongSerializationPolicy longSerializationPolicy;
private LongSerializer(LongSerializationPolicy longSerializationPolicy) {
@ -696,10 +768,18 @@ final class DefaultTypeAdapters {
}
}
private static class LongDeserializer implements JsonDeserializer<Long> {
private static final class LongDeserializer implements JsonDeserializer<Long> {
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsLong();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -708,7 +788,7 @@ final class DefaultTypeAdapters {
}
}
private static class IntegerTypeAdapter
private static final class IntegerTypeAdapter
implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -716,7 +796,15 @@ final class DefaultTypeAdapters {
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -725,7 +813,7 @@ final class DefaultTypeAdapters {
}
}
private static class ShortTypeAdapter
private static final class ShortTypeAdapter
implements JsonSerializer<Short>, JsonDeserializer<Short> {
public JsonElement serialize(Short src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -733,7 +821,15 @@ final class DefaultTypeAdapters {
public Short deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsShort();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -742,14 +838,22 @@ final class DefaultTypeAdapters {
}
}
private static class ByteTypeAdapter implements JsonSerializer<Byte>, JsonDeserializer<Byte> {
private static final class ByteTypeAdapter implements JsonSerializer<Byte>, JsonDeserializer<Byte> {
public JsonElement serialize(Byte src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
public Byte deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsByte();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -758,7 +862,7 @@ final class DefaultTypeAdapters {
}
}
static class FloatSerializer implements JsonSerializer<Float> {
static final class FloatSerializer implements JsonSerializer<Float> {
private final boolean serializeSpecialFloatingPointValues;
FloatSerializer(boolean serializeSpecialDoubleValues) {
@ -777,10 +881,18 @@ final class DefaultTypeAdapters {
}
}
private static class FloatDeserializer implements JsonDeserializer<Float> {
private static final class FloatDeserializer implements JsonDeserializer<Float> {
public Float deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsFloat();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -789,7 +901,7 @@ final class DefaultTypeAdapters {
}
}
static class DoubleSerializer implements JsonSerializer<Double> {
static final class DoubleSerializer implements JsonSerializer<Double> {
private final boolean serializeSpecialFloatingPointValues;
DoubleSerializer(boolean serializeSpecialDoubleValues) {
@ -808,10 +920,18 @@ final class DefaultTypeAdapters {
}
}
private static class DoubleDeserializer implements JsonDeserializer<Double> {
private static final class DoubleDeserializer implements JsonDeserializer<Double> {
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsDouble();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -820,7 +940,7 @@ final class DefaultTypeAdapters {
}
}
private static class CharacterTypeAdapter
private static final class CharacterTypeAdapter
implements JsonSerializer<Character>, JsonDeserializer<Character> {
public JsonElement serialize(Character src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -837,7 +957,7 @@ final class DefaultTypeAdapters {
}
}
private static class StringTypeAdapter
private static final class StringTypeAdapter
implements JsonSerializer<String>, JsonDeserializer<String> {
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -854,7 +974,41 @@ final class DefaultTypeAdapters {
}
}
private static class BooleanTypeAdapter
private static final class StringBuilderTypeAdapter
implements JsonSerializer<StringBuilder>, JsonDeserializer<StringBuilder> {
public JsonElement serialize(StringBuilder src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
public StringBuilder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new StringBuilder(json.getAsString());
}
@Override
public String toString() {
return StringBuilderTypeAdapter.class.getSimpleName();
}
}
private static final class StringBufferTypeAdapter
implements JsonSerializer<StringBuffer>, JsonDeserializer<StringBuffer> {
public JsonElement serialize(StringBuffer src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.toString());
}
public StringBuffer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new StringBuffer(json.getAsString());
}
@Override
public String toString() {
return StringBufferTypeAdapter.class.getSimpleName();
}
}
private static final class BooleanTypeAdapter
implements JsonSerializer<Boolean>, JsonDeserializer<Boolean> {
public JsonElement serialize(Boolean src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
@ -862,7 +1016,13 @@ final class DefaultTypeAdapters {
public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return json.getAsBoolean();
} catch (UnsupportedOperationException e) {
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
}
}
@Override
@ -871,23 +1031,32 @@ final class DefaultTypeAdapters {
}
}
private static class TreeSetCreator implements InstanceCreator<TreeSet<?>> {
public TreeSet<?> createInstance(Type type) {
return new TreeSet<Object>();
@SuppressWarnings("unchecked")
private static final class DefaultConstructorCreator<T> implements InstanceCreator<T> {
private final Class<? extends T> defaultInstance;
private final DefaultConstructorAllocator allocator;
public DefaultConstructorCreator(Class<? extends T> defaultInstance,
DefaultConstructorAllocator allocator) {
this.defaultInstance = defaultInstance;
this.allocator = allocator;
}
@Override
public String toString() {
return TreeSetCreator.class.getSimpleName();
public T createInstance(Type type) {
Class<?> rawType = $Gson$Types.getRawType(type);
try {
T specificInstance = (T) allocator.newInstance(rawType);
return (specificInstance == null)
? allocator.newInstance(defaultInstance)
: specificInstance;
} catch (Exception e) {
throw new JsonIOException(e);
}
}
private static class HashSetCreator implements InstanceCreator<HashSet<?>> {
public HashSet<?> createInstance(Type type) {
return new HashSet<Object>();
}
@Override
public String toString() {
return HashSetCreator.class.getSimpleName();
return DefaultConstructorCreator.class.getSimpleName();
}
}
}

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.io.IOException;
/**
@ -44,12 +46,11 @@ import java.io.IOException;
*
* @author Joel Leitch
*/
class DelegatingJsonElementVisitor implements JsonElementVisitor {
final class DelegatingJsonElementVisitor implements JsonElementVisitor {
private final JsonElementVisitor delegate;
protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) {
Preconditions.checkNotNull(delegate);
this.delegate = delegate;
this.delegate = $Gson$Preconditions.checkNotNull(delegate);
}
public void endArray(JsonArray array) throws IOException {

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.util.Collection;
/**
@ -27,9 +29,8 @@ import java.util.Collection;
final class DisjunctionExclusionStrategy implements ExclusionStrategy {
private final Collection<ExclusionStrategy> strategies;
public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
Preconditions.checkNotNull(strategies);
this.strategies = strategies;
DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
this.strategies = $Gson$Preconditions.checkNotNull(strategies);
}
public boolean shouldSkipField(FieldAttributes f) {

View File

@ -66,7 +66,7 @@ final class Escaper {
}
public String escapeJsonString(CharSequence plainText) {
StringBuffer escapedString = new StringBuffer(plainText.length() + 20);
StringBuilder escapedString = new StringBuilder(plainText.length() + 20);
try {
escapeJsonString(plainText, escapedString);
} catch (IOException e) {
@ -75,7 +75,7 @@ final class Escaper {
return escapedString.toString();
}
private void escapeJsonString(CharSequence plainText, StringBuffer out) throws IOException {
private void escapeJsonString(CharSequence plainText, StringBuilder out) throws IOException {
int pos = 0; // Index just past the last char in plainText written to out.
int len = plainText.length();

View File

@ -72,10 +72,24 @@ package org.mcteam.factions.gson;
* .create();
* </pre>
*
* <p>For certain model classes, you may only want to serialize a field, but exclude it for
* deserialization. To do that, you can write an {@code ExclusionStrategy} as per normal;
* however, you would register it with the
* {@link GsonBuilder#addDeserializationExclusionStrategy(ExclusionStrategy)} method.
* For example:
* <pre class="code">
* ExclusionStrategy excludeStrings = new UserDefinedExclusionStrategy(String.class);
* Gson gson = new GsonBuilder()
* .addDeserializationExclusionStrategy(excludeStrings)
* .create();
* </pre>
*
* @author Inderjeet Singh
* @author Joel Leitch
*
* @see GsonBuilder#setExclusionStrategies(ExclusionStrategy...)
* @see GsonBuilder#addDeserializationExclusionStrategy(ExclusionStrategy)
* @see GsonBuilder#addSerializationExclusionStrategy(ExclusionStrategy)
*
* @since 1.4
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009 Google Inc.
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.annotations.Expose;
@ -20,11 +21,9 @@ import org.mcteam.factions.gson.annotations.Expose;
/**
* Excludes fields that do not have the {@link Expose} annotation
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class ExposeAnnotationDeserializationExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 Google Inc.
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,11 +21,9 @@ import org.mcteam.factions.gson.annotations.Expose;
/**
* Excludes fields that do not have the {@link Expose} annotation
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class ExposeAnnotationSerializationExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}

View File

@ -16,6 +16,9 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
@ -35,7 +38,7 @@ import java.util.Collections;
*/
public final class FieldAttributes {
private static final String MAX_CACHE_PROPERTY_NAME =
"com.bukkit.mcteam.gson.annotation_cache_size_hint";
"org.mcteam.factions.gson.annotation_cache_size_hint";
private static final Cache<Pair<Class<?>, String>, Collection<Annotation>> ANNOTATION_CACHE =
new LruCache<Pair<Class<?>,String>, Collection<Annotation>>(getMaxCacheSize());
@ -46,6 +49,7 @@ public final class FieldAttributes {
private final boolean isSynthetic;
private final int modifiers;
private final String name;
private final Type resolvedType;
// Fields used for lazy initialization
private Type genericType;
@ -55,15 +59,16 @@ public final class FieldAttributes {
* Constructs a Field Attributes object from the {@code f}.
*
* @param f the field to pull attributes from
* @param declaringType The type in which the field is declared
*/
FieldAttributes(final Class<?> declaringClazz, final Field f) {
Preconditions.checkNotNull(declaringClazz);
this.declaringClazz = declaringClazz;
name = f.getName();
declaredType = f.getType();
isSynthetic = f.isSynthetic();
modifiers = f.getModifiers();
field = f;
FieldAttributes(Class<?> declaringClazz, Field f, Type declaringType) {
this.declaringClazz = $Gson$Preconditions.checkNotNull(declaringClazz);
this.name = f.getName();
this.declaredType = f.getType();
this.isSynthetic = f.isSynthetic();
this.modifiers = f.getModifiers();
this.field = f;
this.resolvedType = getTypeInfoForField(f, declaringType);
}
private static int getMaxCacheSize() {
@ -216,6 +221,10 @@ public final class FieldAttributes {
return field;
}
Type getResolvedType() {
return resolvedType;
}
@SuppressWarnings("unchecked")
private static <T extends Annotation> T getAnnotationFromArray(
Collection<Annotation> annotations, Class<T> annotation) {
@ -226,4 +235,21 @@ public final class FieldAttributes {
}
return null;
}
/**
* Evaluates the "actual" type for the field. If the field is a "TypeVariable" or has a
* "TypeVariable" in a parameterized type then it evaluates the real type.
*
* @param f the actual field object to retrieve the type from
* @param typeDefiningF the type that contains the field {@code f}
* @return the type information for the field
*/
static Type getTypeInfoForField(Field f, Type typeDefiningF) {
Class<?> rawType = $Gson$Types.getRawType(typeDefiningF);
if (!f.getDeclaringClass().isAssignableFrom(rawType)) {
// this field is unrelated to the type; the user probably omitted type information
return f.getGenericType();
}
return $Gson$Types.resolve(typeDefiningF, rawType, f.getGenericType());
}
}

View File

@ -32,7 +32,6 @@ interface FieldNamingStrategy2 {
*
* @param f the field that is being translated
* @return the translated field name.
* @since 1.3
*/
public String translateName(FieldAttributes f);
}

View File

@ -16,8 +16,10 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
/**
* Adapts the old "deprecated" {@link FieldNamingStrategy} to the new {@link FieldNamingStrategy2}
* Adapts the old FieldNamingStrategy to the new {@link FieldNamingStrategy2}
* type.
*
* @author Inderjeet Singh
@ -26,12 +28,10 @@ package org.mcteam.factions.gson;
final class FieldNamingStrategy2Adapter implements FieldNamingStrategy2 {
private final FieldNamingStrategy adaptee;
public FieldNamingStrategy2Adapter(FieldNamingStrategy adaptee) {
Preconditions.checkNotNull(adaptee);
this.adaptee = adaptee;
FieldNamingStrategy2Adapter(FieldNamingStrategy adaptee) {
this.adaptee = $Gson$Preconditions.checkNotNull(adaptee);
}
@SuppressWarnings("deprecation")
public String translateName(FieldAttributes f) {
return adaptee.translateName(f.getFieldObject());
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;
/**
* An simple pojo-like immutable instance of the {@link GenericArrayType}. This object provides
* us the ability to create reflective types on demand. This object is required for support
* object similar to the one defined below:
* <pre>
* class Foo<T> {
* private final List<T>[] arrayOfListT;
*
* Foo(List<T>[] arrayList) {
* this.arrayOfListT = arrayList;
* }
* }
* </pre>
*
* <p>During parsing or serialization, we know the real variable type parameter {@code T},
* so we can build a new {@code GenericTypeArray} with the "real" type parameters and
* pass that object along instead.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class GenericArrayTypeImpl implements GenericArrayType {
private final Type genericComponentType;
public GenericArrayTypeImpl(Type genericComponentType) {
this.genericComponentType = genericComponentType;
}
public Type getGenericComponentType() {
return genericComponentType;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof GenericArrayType)) {
return false;
}
GenericArrayType that = (GenericArrayType) o;
Type thatComponentType = that.getGenericComponentType();
return genericComponentType == null ?
thatComponentType == null : genericComponentType.equals(thatComponentType);
}
@Override
public int hashCode() {
return (genericComponentType == null) ? 0 : genericComponentType.hashCode();
}
}

View File

@ -16,6 +16,10 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonToken;
import org.mcteam.factions.gson.stream.JsonWriter;
import org.mcteam.factions.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
@ -27,12 +31,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.mcteam.factions.gson.JsonSerializationContextDefault;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonToken;
import org.mcteam.factions.gson.stream.JsonWriter;
import org.mcteam.factions.gson.stream.MalformedJsonException;
/**
* This is the main class for using Gson. Gson is typically used by first constructing a
* Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
@ -80,8 +78,6 @@ public final class Gson {
//TODO(inder): get rid of all the registerXXX methods and take all such parameters in the
// constructor instead. At the minimum, mark those methods private.
private static final String NULL_STRING = "null";
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
// Default instances of plug-ins
@ -94,15 +90,12 @@ public final class Gson {
static final FieldNamingStrategy2 DEFAULT_NAMING_POLICY =
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY =
createExclusionStrategy(VersionConstants.IGNORE_VERSIONS);
private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY = createExclusionStrategy();
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
private final ExclusionStrategy serializationStrategy;
private final ExclusionStrategy deserializationStrategy;
private final ExclusionStrategy deserializationExclusionStrategy;
private final ExclusionStrategy serializationExclusionStrategy;
private final FieldNamingStrategy2 fieldNamingPolicy;
private final MappedObjectConstructor objectConstructor;
@ -154,17 +147,18 @@ public final class Gson {
public Gson() {
this(DEFAULT_EXCLUSION_STRATEGY, DEFAULT_EXCLUSION_STRATEGY, DEFAULT_NAMING_POLICY,
new MappedObjectConstructor(DefaultTypeAdapters.getDefaultInstanceCreators()),
false, DefaultTypeAdapters.getDefaultSerializers(),
DefaultTypeAdapters.getDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE, true, false);
false, DefaultTypeAdapters.getAllDefaultSerializers(),
DefaultTypeAdapters.getAllDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE, true, false);
}
Gson(ExclusionStrategy serializationStrategy, ExclusionStrategy deserializationStrategy,
FieldNamingStrategy2 fieldNamingPolicy, MappedObjectConstructor objectConstructor,
boolean serializeNulls, ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
Gson(ExclusionStrategy deserializationExclusionStrategy,
ExclusionStrategy serializationExclusionStrategy, FieldNamingStrategy2 fieldNamingPolicy,
MappedObjectConstructor objectConstructor, boolean serializeNulls,
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting) {
this.serializationStrategy = serializationStrategy;
this.deserializationStrategy = deserializationStrategy;
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
this.serializationExclusionStrategy = serializationExclusionStrategy;
this.fieldNamingPolicy = fieldNamingPolicy;
this.objectConstructor = objectConstructor;
this.serializeNulls = serializeNulls;
@ -175,18 +169,11 @@ public final class Gson {
this.prettyPrinting = prettyPrinting;
}
private ObjectNavigatorFactory createDefaultObjectNavigatorFactory(ExclusionStrategy strategy) {
return new ObjectNavigatorFactory(strategy, fieldNamingPolicy);
}
private static ExclusionStrategy createExclusionStrategy(double version) {
private static ExclusionStrategy createExclusionStrategy() {
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
strategies.add(DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
strategies.add(DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
if (version != VersionConstants.IGNORE_VERSIONS) {
strategies.add(new VersionExclusionStrategy(version));
}
return new DisjunctionExclusionStrategy(strategies);
}
@ -227,12 +214,10 @@ public final class Gson {
* @since 1.4
*/
public JsonElement toJsonTree(Object src, Type typeOfSrc) {
if (src == null) {
return JsonNull.createJsonNull();
}
JsonSerializationContextDefault context = new JsonSerializationContextDefault(
createDefaultObjectNavigatorFactory(serializationStrategy), serializeNulls, serializers);
return context.serialize(src, typeOfSrc, true);
new ObjectNavigator(serializationExclusionStrategy), fieldNamingPolicy,
serializeNulls, serializers);
return context.serialize(src, typeOfSrc);
}
/**
@ -250,7 +235,7 @@ public final class Gson {
*/
public String toJson(Object src) {
if (src == null) {
return serializeNulls ? NULL_STRING : "";
return toJson(JsonNull.createJsonNull());
}
return toJson(src, src.getClass());
}
@ -291,14 +276,10 @@ public final class Gson {
* @since 1.2
*/
public void toJson(Object src, Appendable writer) throws JsonIOException {
try {
if (src != null) {
toJson(src, src.getClass(), writer);
} else if (serializeNulls) {
writeOutNullString(writer);
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
} else {
toJson(JsonNull.createJsonNull(), writer);
}
}
@ -565,21 +546,12 @@ public final class Gson {
return null;
}
JsonDeserializationContext context = new JsonDeserializationContextDefault(
createDefaultObjectNavigatorFactory(deserializationStrategy), deserializers,
objectConstructor);
new ObjectNavigator(deserializationExclusionStrategy), fieldNamingPolicy,
deserializers, objectConstructor);
T target = (T) context.deserialize(json, typeOfT);
return target;
}
/**
* Appends the {@link #NULL_STRING} to the {@code writer} object.
*
* @param writer the object to append the null value to
*/
private void writeOutNullString(Appendable writer) throws IOException {
writer.append(NULL_STRING);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{")

View File

@ -16,16 +16,19 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.mcteam.factions.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
import java.util.Map;
import java.util.Set;
/**
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
@ -39,6 +42,7 @@ import org.mcteam.factions.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
* <pre>
* Gson gson = new GsonBuilder()
* .registerTypeAdapter(Id.class, new IdTypeAdapter())
* .enableComplexMapKeySerialization()
* .serializeNulls()
* .setDateFormat(DateFormat.LONG)
* .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
@ -47,22 +51,33 @@ import org.mcteam.factions.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
* .create();
* </pre></p>
*
* <p>NOTE: the order of invocation of configuration methods does not matter.</p>
* <p>NOTES:
* <ul>
* <li> the order of invocation of configuration methods does not matter.</li>
* <li> The default serialization of {@link Date} and its subclasses in Gson does
* not contain time-zone information. So, if you are using date/time instances,
* use {@code GsonBuilder} and its {@code setDateFormat} methods.</li>
* </ul>
* </p>
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
public final class GsonBuilder {
private static final MapAsArrayTypeAdapter COMPLEX_KEY_MAP_TYPE_ADAPTER =
new MapAsArrayTypeAdapter();
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
new InnerClassExclusionStrategy();
private static final ExposeAnnotationSerializationExclusionStrategy
exposeAnnotationSerializationExclusionStrategy =
new ExposeAnnotationSerializationExclusionStrategy();
private static final ExposeAnnotationDeserializationExclusionStrategy
exposeAnnotationDeserializationExclusionStrategy =
new ExposeAnnotationDeserializationExclusionStrategy();
private static final ExposeAnnotationSerializationExclusionStrategy
exposeAnnotationSerializationExclusionStrategy =
new ExposeAnnotationSerializationExclusionStrategy();
private final Collection<ExclusionStrategy> exclusionStrategies =
private final Set<ExclusionStrategy> serializeExclusionStrategies =
new HashSet<ExclusionStrategy>();
private final Set<ExclusionStrategy> deserializeExclusionStrategies =
new HashSet<ExclusionStrategy>();
private double ignoreVersionsAfter;
@ -91,8 +106,10 @@ public final class GsonBuilder {
*/
public GsonBuilder() {
// add default exclusion strategies
exclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
exclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
deserializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
deserializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
serializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
serializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
// setup default values
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
@ -178,6 +195,87 @@ public final class GsonBuilder {
return this;
}
/**
* Enabling this feature will only change the serialized form if the map key is
* a complex type (i.e. non-primitive) in its <strong>serialized</strong> JSON
* form. The default implementation of map serialization uses {@code toString()}
* on the key; however, when this is called then one of the following cases
* apply:
*
* <h3>Maps as JSON objects</h3>
* For this case, assume that a type adapter is registered to serialize and
* deserialize some {@code Point} class, which contains an x and y coordinate,
* to/from the JSON Primitive string value {@code "(x,y)"}. The Java map would
* then be serialized as a {@link JsonObject}.
*
* <p>Below is an example:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .register(Point.class, new MyPointTypeAdapter())
* .enableComplexMapKeySerialization()
* .create();
*
* Map<Point, String> original = new LinkedHashMap<Point, String>();
* original.put(new Point(5, 6), "a");
* original.put(new Point(8, 8), "b");
* System.out.println(gson.toJson(original, type));
* }</pre>
* The above code prints this JSON object:<pre> {@code
* {
* "(5,6)": "a",
* "(8,8)": "b"
* }
* }</pre>
*
* <h3>Maps as JSON arrays</h3>
* For this case, assume that a type adapter was NOT registered for some
* {@code Point} class, but rather the default Gson serialization is applied.
* In this case, some {@code new Point(2,3)} would serialize as {@code
* {"x":2,"y":5}}.
*
* <p>Given the assumption above, a {@code Map<Point, String>} will be
* serialize as an array of arrays (can be viewed as an entry set of pairs).
*
* <p>Below is an example of serializing complex types as JSON arrays:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .enableComplexMapKeySerialization()
* .create();
*
* Map<Point, String> original = new LinkedHashMap<Point, String>();
* original.put(new Point(5, 6), "a");
* original.put(new Point(8, 8), "b");
* System.out.println(gson.toJson(original, type));
* }
*
* The JSON output would look as follows:
* <pre> {@code
* [
* [
* {
* "x": 5,
* "y": 6
* },
* "a"
* ],
* [
* {
* "x": 8,
* "y": 8
* },
* "b"
* ]
* ]
* }</pre>
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
public GsonBuilder enableComplexMapKeySerialization() {
registerTypeHierarchyAdapter(Map.class, COMPLEX_KEY_MAP_TYPE_ADAPTER);
return this;
}
/**
* Configures Gson to exclude inner classes during serialization.
*
@ -250,12 +348,45 @@ public final class GsonBuilder {
* @since 1.4
*/
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
for (ExclusionStrategy strategy : strategies) {
exclusionStrategies.add(strategy);
}
List<ExclusionStrategy> strategyList = Arrays.asList(strategies);
serializeExclusionStrategies.addAll(strategyList);
deserializeExclusionStrategies.addAll(strategyList);
return this;
}
/**
* Configures Gson to apply the passed in exclusion strategy during serialization.
* If this method is invoked numerous times with different exclusion strategy objects
* then the exclusion strategies that were added will be applied as a disjunction rule.
* This means that if one of the added exclusion strategies suggests that a field (or
* class) should be skipped then that field (or object) is skipped during its
* serialization.
*
* @param strategy an exclusion strategy to apply during serialization.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
serializeExclusionStrategies.add(strategy);
return this;
}
/**
* Configures Gson to apply the passed in exclusion strategy during deserialization.
* If this method is invoked numerous times with different exclusion strategy objects
* then the exclusion strategies that were added will be applied as a disjunction rule.
* This means that if one of the added exclusion strategies suggests that a field (or
* class) should be skipped then that field (or object) is skipped during its
* deserialization.
*
* @param strategy an exclusion strategy to apply during deserialization.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
deserializeExclusionStrategies.add(strategy);
return this;
}
/**
* Configures Gson to output Json that fits in a page for pretty printing. This option only
* affects Json serialization.
@ -284,6 +415,9 @@ public final class GsonBuilder {
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
* will be used to decide the serialization format.
*
* <p>The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
* java.sql.Timestamp} and {@link java.sql.Date}.
*
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
* valid date and time patterns.</p>
@ -354,7 +488,7 @@ public final class GsonBuilder {
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
*/
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
if (typeAdapter instanceof InstanceCreator<?>) {
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter);
@ -432,8 +566,8 @@ public final class GsonBuilder {
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
*/
GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
if (typeAdapter instanceof InstanceCreator<?>) {
registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter);
@ -498,33 +632,34 @@ public final class GsonBuilder {
* @return an instance of Gson configured with the options currently set in this builder
*/
public Gson create() {
List<ExclusionStrategy> serializationStrategies =
new LinkedList<ExclusionStrategy>(exclusionStrategies);
List<ExclusionStrategy> deserializationStrategies =
new LinkedList<ExclusionStrategy>(exclusionStrategies);
serializationStrategies.add(modifierBasedExclusionStrategy);
new LinkedList<ExclusionStrategy>(deserializeExclusionStrategies);
List<ExclusionStrategy> serializationStrategies =
new LinkedList<ExclusionStrategy>(serializeExclusionStrategies);
deserializationStrategies.add(modifierBasedExclusionStrategy);
serializationStrategies.add(modifierBasedExclusionStrategy);
if (!serializeInnerClasses) {
serializationStrategies.add(innerClassExclusionStrategy);
deserializationStrategies.add(innerClassExclusionStrategy);
serializationStrategies.add(innerClassExclusionStrategy);
}
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
serializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
deserializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
VersionExclusionStrategy versionExclusionStrategy =
new VersionExclusionStrategy(ignoreVersionsAfter);
deserializationStrategies.add(versionExclusionStrategy);
serializationStrategies.add(versionExclusionStrategy);
}
if (excludeFieldsWithoutExposeAnnotation) {
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
}
ExclusionStrategy serializationExclusionStrategy =
new DisjunctionExclusionStrategy(serializationStrategies);
ExclusionStrategy deserializationExclusionStrategy =
new DisjunctionExclusionStrategy(deserializationStrategies);
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers = serializers.copyOf();
ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers = deserializers.copyOf();
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers =
DefaultTypeAdapters.DEFAULT_HIERARCHY_SERIALIZERS.copyOf();
customSerializers.register(serializers.copyOf());
ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers =
DefaultTypeAdapters.DEFAULT_HIERARCHY_DESERIALIZERS.copyOf();
customDeserializers.register(deserializers.copyOf());
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
customDeserializers);
@ -543,9 +678,11 @@ public final class GsonBuilder {
MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
Gson gson = new Gson(serializationExclusionStrategy, deserializationExclusionStrategy,
fieldNamingPolicy, objConstructor, serializeNulls, customSerializers,
customDeserializers, generateNonExecutableJson, escapeHtmlChars, prettyPrinting);
Gson gson = new Gson(new DisjunctionExclusionStrategy(deserializationStrategies),
new DisjunctionExclusionStrategy(serializationStrategies),
fieldNamingPolicy, objConstructor, serializeNulls,
customSerializers, customDeserializers, generateNonExecutableJson, escapeHtmlChars,
prettyPrinting);
return gson;
}
@ -560,12 +697,19 @@ public final class GsonBuilder {
}
if (dateTypeAdapter != null) {
if (!serializers.hasSpecificHandlerFor(Date.class)) {
serializers.register(Date.class, dateTypeAdapter);
}
if (!deserializers.hasSpecificHandlerFor(Date.class)) {
deserializers.register(Date.class, dateTypeAdapter);
registerIfAbsent(Date.class, serializers, dateTypeAdapter);
registerIfAbsent(Date.class, deserializers, dateTypeAdapter);
registerIfAbsent(Timestamp.class, serializers, dateTypeAdapter);
registerIfAbsent(Timestamp.class, deserializers, dateTypeAdapter);
registerIfAbsent(java.sql.Date.class, serializers, dateTypeAdapter);
registerIfAbsent(java.sql.Date.class, deserializers, dateTypeAdapter);
}
}
private static <T> void registerIfAbsent(Class<?> type,
ParameterizedTypeHandlerMap<T> adapters, T adapter) {
if (!adapters.hasSpecificHandlerFor(type)) {
adapters.register(type, adapter);
}
}
}

View File

@ -23,7 +23,7 @@ import java.lang.reflect.Modifier;
*
* @author Joel Leitch
*/
class InnerClassExclusionStrategy implements ExclusionStrategy {
final class InnerClassExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipField(FieldAttributes f) {
return isInnerClass(f.getDeclaredClass());

View File

@ -295,6 +295,16 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
throw new IllegalStateException();
}
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof JsonArray && ((JsonArray) o).elements.equals(elements));
}
@Override
public int hashCode() {
return elements.hashCode();
}
@Override
protected void toString(Appendable sb, Escaper escaper) throws IOException {
sb.append('[');

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
@ -29,31 +31,28 @@ import java.lang.reflect.Type;
final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
ObjectConstructor objectConstructor,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
super(jsonArray, arrayType, factory, objectConstructor, deserializers, context);
super(jsonArray, arrayType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
}
@Override
@SuppressWarnings("unchecked")
protected T constructTarget() {
TypeInfo typeInfo = new TypeInfo(targetType);
if (!json.isJsonArray()) {
throw new JsonParseException("Expecting array found: " + json);
}
JsonArray jsonArray = json.getAsJsonArray();
if (typeInfo.isArray()) {
TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(targetType);
if ($Gson$Types.isArray(targetType)) {
// We know that we are getting back an array of the required type, so
// this typecasting is safe.
return (T) objectConstructor.constructArray(arrayTypeInfo.getSecondLevelType(),
return (T) objectConstructor.constructArray($Gson$Types.getArrayComponentType(targetType),
jsonArray.size());
}
// is a collection
return (T) objectConstructor.construct(typeInfo.getRawClass());
return (T) objectConstructor.construct($Gson$Types.getRawType(targetType));
}
public void visitArray(Object array, Type arrayType) {
@ -61,7 +60,6 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
throw new JsonParseException("Expecting array found: " + json);
}
JsonArray jsonArray = json.getAsJsonArray();
TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
for (int i = 0; i < jsonArray.size(); i++) {
JsonElement jsonChild = jsonArray.get(i);
Object child;
@ -69,11 +67,12 @@ final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisito
if (jsonChild == null || jsonChild.isJsonNull()) {
child = null;
} else if (jsonChild instanceof JsonObject) {
child = visitChildAsObject(arrayTypeInfo.getComponentRawType(), jsonChild);
child = visitChildAsObject($Gson$Types.getArrayComponentType(arrayType), jsonChild);
} else if (jsonChild instanceof JsonArray) {
child = visitChildAsArray(arrayTypeInfo.getSecondLevelType(), jsonChild.getAsJsonArray());
child = visitChildAsArray($Gson$Types.getArrayComponentType(arrayType),
jsonChild.getAsJsonArray());
} else if (jsonChild instanceof JsonPrimitive) {
child = visitChildAsObject(arrayTypeInfo.getComponentRawType(),
child = visitChildAsObject($Gson$Types.getArrayComponentType(arrayType),
jsonChild.getAsJsonPrimitive());
} else {
throw new IllegalStateException();

View File

@ -25,14 +25,17 @@ import java.lang.reflect.Type;
*/
final class JsonDeserializationContextDefault implements JsonDeserializationContext {
private final ObjectNavigatorFactory navigatorFactory;
private final ObjectNavigator objectNavigator;
private final FieldNamingStrategy2 fieldNamingPolicy;
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
private final MappedObjectConstructor objectConstructor;
JsonDeserializationContextDefault(ObjectNavigatorFactory navigatorFactory,
JsonDeserializationContextDefault(ObjectNavigator objectNavigator,
FieldNamingStrategy2 fieldNamingPolicy,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
MappedObjectConstructor objectConstructor) {
this.navigatorFactory = navigatorFactory;
this.objectNavigator = objectNavigator;
this.fieldNamingPolicy = fieldNamingPolicy;
this.deserializers = deserializers;
this.objectConstructor = objectConstructor;
}
@ -59,18 +62,18 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private <T> T fromJsonArray(Type arrayType, JsonArray jsonArray,
JsonDeserializationContext context) throws JsonParseException {
JsonArrayDeserializationVisitor<T> visitor = new JsonArrayDeserializationVisitor<T>(
jsonArray, arrayType, navigatorFactory, objectConstructor, deserializers, context);
ObjectNavigator on = navigatorFactory.create(new ObjectTypePair(null, arrayType, true));
on.accept(visitor);
jsonArray, arrayType, objectNavigator, fieldNamingPolicy,
objectConstructor, deserializers, context);
objectNavigator.accept(new ObjectTypePair(null, arrayType, true), visitor);
return visitor.getTarget();
}
private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
JsonDeserializationContext context) throws JsonParseException {
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
jsonObject, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
ObjectNavigator on = navigatorFactory.create(new ObjectTypePair(null, typeOfT, true));
on.accept(visitor);
jsonObject, typeOfT, objectNavigator, fieldNamingPolicy,
objectConstructor, deserializers, context);
objectNavigator.accept(new ObjectTypePair(null, typeOfT, true), visitor);
return visitor.getTarget();
}
@ -78,10 +81,8 @@ final class JsonDeserializationContextDefault implements JsonDeserializationCont
private <T> T fromJsonPrimitive(Type typeOfT, JsonPrimitive json,
JsonDeserializationContext context) throws JsonParseException {
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
json, typeOfT, navigatorFactory, objectConstructor, deserializers, context);
ObjectNavigator on =
navigatorFactory.create(new ObjectTypePair(json.getAsObject(), typeOfT, true));
on.accept(visitor);
json, typeOfT, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
objectNavigator.accept(new ObjectTypePair(json.getAsObject(), typeOfT, true), visitor);
Object target = visitor.getTarget();
return (T) target;
}

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Type;
/**
@ -28,7 +30,8 @@ import java.lang.reflect.Type;
*/
abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor {
protected final ObjectNavigatorFactory factory;
protected final ObjectNavigator objectNavigator;
protected final FieldNamingStrategy2 fieldNamingPolicy;
protected final ObjectConstructor objectConstructor;
protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
protected T target;
@ -37,16 +40,17 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
protected final JsonDeserializationContext context;
protected boolean constructed;
public JsonDeserializationVisitor(JsonElement json, Type targetType,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
JsonDeserializationVisitor(JsonElement json, Type targetType,
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
ObjectConstructor objectConstructor,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
Preconditions.checkNotNull(json);
this.targetType = targetType;
this.factory = factory;
this.objectNavigator = objectNavigator;
this.fieldNamingPolicy = fieldNamingPolicy;
this.objectConstructor = objectConstructor;
this.deserializers = deserializers;
this.json = json;
this.json = $Gson$Preconditions.checkNotNull(json);
this.context = context;
this.constructed = false;
}
@ -91,20 +95,19 @@ abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor
final Object visitChildAsObject(Type childType, JsonElement jsonChild) {
JsonDeserializationVisitor<?> childVisitor =
new JsonObjectDeserializationVisitor<Object>(jsonChild, childType,
factory, objectConstructor, deserializers, context);
objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
return visitChild(childType, childVisitor);
}
final Object visitChildAsArray(Type childType, JsonArray jsonChild) {
JsonDeserializationVisitor<?> childVisitor =
new JsonArrayDeserializationVisitor<Object>(jsonChild.getAsJsonArray(), childType,
factory, objectConstructor, deserializers, context);
objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
return visitChild(childType, childVisitor);
}
private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
ObjectNavigator on = factory.create(new ObjectTypePair(null, type, false));
on.accept(childVisitor);
objectNavigator.accept(new ObjectTypePair(null, type, false), childVisitor);
// the underlying object may have changed during the construction phase
// This happens primarily because of custom deserializers
return childVisitor.getTarget();

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Type;
/**
@ -28,7 +30,7 @@ import java.lang.reflect.Type;
* @author Inderjeet Singh
* @author Joel Leitch
*/
class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
final class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
private final JsonDeserializer<T> delegate;
@ -40,8 +42,7 @@ class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
* @throws IllegalArgumentException if {@code delegate} is {@code null}.
*/
JsonDeserializerExceptionWrapper(JsonDeserializer<T> delegate) {
Preconditions.checkNotNull(delegate);
this.delegate = delegate;
this.delegate = $Gson$Preconditions.checkNotNull(delegate);
}
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
@ -56,7 +57,7 @@ class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
StringBuilder errorMsg = new StringBuilder()
.append("The JsonDeserializer ")
.append(delegate)
.append(" failed to deserialized json object ")
.append(" failed to deserialize json object ")
.append(json)
.append(" given the type ")
.append(typeOfT);

View File

@ -1,56 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class can be used to check the validity of a JSON field name.
*
* <p>The primary use of this object is to ensure that any Java fields that use the
* {@link org.mcteam.factions.gson.annotations.SerializedName} annotation is providing valid JSON
* field names. This will make the code fail-fast rather than letting the invalid
* field name propagate to the client and it fails to parse.</p>
*
* @author Joel Leitch
*/
class JsonFieldNameValidator {
private static final String COMMON_PATTERN = "[a-zA-Z][a-zA-Z0-9\\ \\$_\\-]*$";
private static final Pattern JSON_FIELD_NAME_PATTERN =
Pattern.compile("(^" + COMMON_PATTERN + ")|(^[\\$_]" + COMMON_PATTERN + ")");
/**
* Performs validation on the JSON field name to ensure it is a valid field name.
*
* @param fieldName the name of the field to validate
* @return {@code fieldName} if it is a valid JSON field name
* @throws IllegalArgumentException if the field name is an invalid JSON field name
*/
public String validate(String fieldName) {
Preconditions.checkNotNull(fieldName);
Preconditions.checkArgument(!"".equals(fieldName.trim()));
Matcher matcher = JSON_FIELD_NAME_PATTERN.matcher(fieldName);
if (!matcher.matches()) {
throw new IllegalArgumentException(fieldName + " is not a valid JSON field name.");
}
return fieldName;
}
}

View File

@ -53,7 +53,7 @@ public final class JsonNull extends JsonElement {
*/
@Override
public boolean equals(Object other) {
return other instanceof JsonNull;
return this == other || other instanceof JsonNull;
}
/**

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
@ -52,11 +54,10 @@ public final class JsonObject extends JsonElement {
* @param value the member object.
*/
public void add(String property, JsonElement value) {
Preconditions.checkNotNull(property);
if (value == null) {
value = JsonNull.createJsonNull();
}
members.put(property, value);
members.put($Gson$Preconditions.checkNotNull(property), value);
}
/**
@ -188,6 +189,17 @@ public final class JsonObject extends JsonElement {
return (JsonObject) members.get(memberName);
}
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof JsonObject
&& ((JsonObject) o).members.equals(members));
}
@Override
public int hashCode() {
return members.hashCode();
}
@Override
protected void toString(Appendable sb, Escaper escaper) throws IOException {
sb.append('{');

View File

@ -16,6 +16,7 @@
package org.mcteam.factions.gson;
import java.lang.reflect.Type;
/**
@ -28,10 +29,11 @@ import java.lang.reflect.Type;
final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
JsonObjectDeserializationVisitor(JsonElement json, Type type,
ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
ObjectConstructor objectConstructor,
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
JsonDeserializationContext context) {
super(json, type, factory, objectConstructor, deserializers, context);
super(json, type, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
}
@Override
@ -88,8 +90,7 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
}
private String getFieldName(FieldAttributes f) {
FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
return namingPolicy.translateName(f);
return fieldNamingPolicy.translateName(f);
}
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
@ -99,11 +100,11 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
throw new JsonParseException("Expecting object found: " + json);
}
JsonElement child = json.getAsJsonObject().get(fName);
TypeInfo typeInfo = new TypeInfo(declaredTypeOfField);
boolean isPrimitive = Primitives.isPrimitive(declaredTypeOfField);
if (child == null) { // Child will be null if the field wasn't present in Json
return true;
} else if (child.isJsonNull()) {
if (!typeInfo.isPrimitive()) {
if (!isPrimitive) {
f.set(parent, null);
}
return true;
@ -114,7 +115,7 @@ final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisit
return false;
}
Object value = invokeCustomDeserializer(child, pair);
if (value != null || !typeInfo.isPrimitive()) {
if (value != null || !isPrimitive) {
f.set(parent, value);
}
return true;

View File

@ -15,15 +15,14 @@
*/
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonToken;
import org.mcteam.factions.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonToken;
import org.mcteam.factions.gson.stream.MalformedJsonException;
/**
* A parser to parse Json into a parse tree of {@link JsonElement}s
*

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
@ -92,7 +94,7 @@ public final class JsonPrimitive extends JsonElement {
char c = ((Character) primitive).charValue();
this.value = String.valueOf(c);
} else {
Preconditions.checkArgument(primitive instanceof Number
$Gson$Preconditions.checkArgument(primitive instanceof Number
|| isPrimitiveOrString(primitive));
this.value = primitive;
}
@ -111,7 +113,6 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a {@link Boolean}.
*
* @return get this element as a {@link Boolean}.
* @throws ClassCastException if the value contained is not a valid boolean value.
*/
@Override
Boolean getAsBooleanWrapper() {
@ -122,7 +123,6 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a boolean value.
*
* @return get this element as a primitive boolean value.
* @throws ClassCastException if the value contained is not a valid boolean value.
*/
@Override
public boolean getAsBoolean() {
@ -142,7 +142,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a Number.
*
* @return get this element as a Number.
* @throws ClassCastException if the value contained is not a valid Number.
* @throws NumberFormatException if the value contained is not a valid Number.
*/
@Override
public Number getAsNumber() {
@ -179,7 +179,6 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a String.
*
* @return get this element as a String.
* @throws ClassCastException if the value contained is not a valid String.
*/
@Override
public String getAsString() {
@ -196,7 +195,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a primitive double.
*
* @return get this element as a primitive double.
* @throws ClassCastException if the value contained is not a valid double.
* @throws NumberFormatException if the value contained is not a valid double.
*/
@Override
public double getAsDouble() {
@ -229,7 +228,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a float.
*
* @return get this element as a float.
* @throws ClassCastException if the value contained is not a valid float.
* @throws NumberFormatException if the value contained is not a valid float.
*/
@Override
public float getAsFloat() {
@ -240,7 +239,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a primitive long.
*
* @return get this element as a primitive long.
* @throws ClassCastException if the value contained is not a valid long.
* @throws NumberFormatException if the value contained is not a valid long.
*/
@Override
public long getAsLong() {
@ -251,7 +250,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a primitive short.
*
* @return get this element as a primitive short.
* @throws ClassCastException if the value contained is not a valid short value.
* @throws NumberFormatException if the value contained is not a valid short value.
*/
@Override
public short getAsShort() {
@ -262,7 +261,7 @@ public final class JsonPrimitive extends JsonElement {
* convenience method to get this element as a primitive integer.
*
* @return get this element as a primitive integer.
* @throws ClassCastException if the value contained is not a valid integer.
* @throws NumberFormatException if the value contained is not a valid integer.
*/
@Override
public int getAsInt() {
@ -356,7 +355,11 @@ public final class JsonPrimitive extends JsonElement {
return getAsNumber().longValue() == other.getAsNumber().longValue();
}
if (isFloatingPoint(this) && isFloatingPoint(other)) {
return getAsNumber().doubleValue() == other.getAsNumber().doubleValue();
double a = getAsNumber().doubleValue();
// Java standard types other than double return true for two NaN. So, need
// special handling for double.
double b = other.getAsNumber().doubleValue();
return a == b || (Double.isNaN(a) && Double.isNaN(b));
}
return value.equals(other.value);
}

View File

@ -16,6 +16,7 @@
package org.mcteam.factions.gson;
import java.lang.reflect.Type;
/**
@ -25,14 +26,17 @@ import java.lang.reflect.Type;
*/
final class JsonSerializationContextDefault implements JsonSerializationContext {
private final ObjectNavigatorFactory factory;
private final ObjectNavigator objectNavigator;
private final FieldNamingStrategy2 fieldNamingPolicy;
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
private final boolean serializeNulls;
private final MemoryRefStack ancestors;
JsonSerializationContextDefault(ObjectNavigatorFactory factory, boolean serializeNulls,
JsonSerializationContextDefault(ObjectNavigator objectNavigator,
FieldNamingStrategy2 fieldNamingPolicy, boolean serializeNulls,
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers) {
this.factory = factory;
this.objectNavigator = objectNavigator;
this.fieldNamingPolicy = fieldNamingPolicy;
this.serializeNulls = serializeNulls;
this.serializers = serializers;
this.ancestors = new MemoryRefStack();
@ -42,18 +46,20 @@ final class JsonSerializationContextDefault implements JsonSerializationContext
if (src == null) {
return JsonNull.createJsonNull();
}
return serialize(src, src.getClass(), true);
return serialize(src, src.getClass(), false);
}
public JsonElement serialize(Object src, Type typeOfSrc) {
return serialize(src, typeOfSrc, true);
}
public JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType) {
ObjectNavigator on = factory.create(new ObjectTypePair(src, typeOfSrc, preserveType));
JsonSerializationVisitor visitor =
new JsonSerializationVisitor(factory, serializeNulls, serializers, this, ancestors);
on.accept(visitor);
JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType) {
if (src == null) {
return JsonNull.createJsonNull();
}
JsonSerializationVisitor visitor = new JsonSerializationVisitor(
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors);
objectNavigator.accept(new ObjectTypePair(src, typeOfSrc, preserveType), visitor);
return visitor.getJsonElement();
}
}

View File

@ -16,6 +16,9 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Types;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
@ -27,17 +30,19 @@ import java.lang.reflect.Type;
*/
final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
private final ObjectNavigatorFactory factory;
private final ObjectNavigator objectNavigator;
private final FieldNamingStrategy2 fieldNamingPolicy;
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
private final boolean serializeNulls;
private final JsonSerializationContext context;
private final MemoryRefStack ancestors;
private JsonElement root;
JsonSerializationVisitor(ObjectNavigatorFactory factory, boolean serializeNulls,
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers, JsonSerializationContext context,
MemoryRefStack ancestors) {
this.factory = factory;
JsonSerializationVisitor(ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
boolean serializeNulls, ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
JsonSerializationContext context, MemoryRefStack ancestors) {
this.objectNavigator = objectNavigator;
this.fieldNamingPolicy = fieldNamingPolicy;
this.serializeNulls = serializeNulls;
this.serializers = serializers;
this.context = context;
@ -71,15 +76,12 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
public void visitArray(Object array, Type arrayType) {
assignToRoot(new JsonArray());
int length = Array.getLength(array);
TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
Type componentType = fieldTypeInfo.getSecondLevelType();
Type componentType = $Gson$Types.getArrayComponentType(arrayType);
for (int i = 0; i < length; ++i) {
Object child = Array.get(array, i);
Type childType = componentType;
// we should not get more specific component type yet since it is possible
// that a custom
// serializer is registered for the componentType
addAsArrayElement(new ObjectTypePair(child, childType, false));
// that a custom serializer is registered for the componentType
addAsArrayElement(new ObjectTypePair(child, componentType, false));
}
}
@ -127,8 +129,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
}
private void addChildAsElement(FieldAttributes f, JsonElement childElement) {
FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
root.getAsJsonObject().add(fieldNamingPolicy.translateName(f), childElement);
}
private void addAsArrayElement(ObjectTypePair elementTypePair) {
@ -141,10 +142,9 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
}
private JsonElement getJsonElementForChild(ObjectTypePair fieldValueTypePair) {
ObjectNavigator on = factory.create(fieldValueTypePair);
JsonSerializationVisitor childVisitor =
new JsonSerializationVisitor(factory, serializeNulls, serializers, context, ancestors);
on.accept(childVisitor);
JsonSerializationVisitor childVisitor = new JsonSerializationVisitor(
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, context, ancestors);
objectNavigator.accept(fieldValueTypePair, childVisitor);
return childVisitor.getJsonElement();
}
@ -171,7 +171,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
/**
* objTypePair.getObject() must not be null
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings("unchecked")
private JsonElement findAndInvokeCustomSerializer(ObjectTypePair objTypePair) {
Pair<JsonSerializer<?>,ObjectTypePair> pair = objTypePair.getMatchingHandler(serializers);
if (pair == null) {
@ -189,9 +189,10 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
}
}
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
public boolean visitFieldUsingCustomHandler(
FieldAttributes f, Type declaredTypeOfField, Object parent) {
try {
Preconditions.checkState(root.isJsonObject());
$Gson$Preconditions.checkState(root.isJsonObject());
Object obj = f.get(parent);
if (obj == null) {
if (serializeNulls) {
@ -214,8 +215,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
}
private void assignToRoot(JsonElement newRoot) {
Preconditions.checkNotNull(newRoot);
root = newRoot;
root = $Gson$Preconditions.checkNotNull(newRoot);
}
private boolean isFieldNull(FieldAttributes f, Object obj) {

View File

@ -26,7 +26,6 @@ import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonToken;
import org.mcteam.factions.gson.stream.MalformedJsonException;
/**
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously.

View File

@ -16,6 +16,7 @@
package org.mcteam.factions.gson;
import java.util.LinkedHashMap;
import java.util.Map;
@ -32,33 +33,23 @@ final class LruCache<K, V> extends LinkedHashMap<K, V> implements Cache<K, V> {
private final int maxCapacity;
LruCache(int maxCapacity) {
public LruCache(int maxCapacity) {
super(maxCapacity, 0.7F, true);
this.maxCapacity = maxCapacity;
}
public void addElement(K key, V value) {
public synchronized void addElement(K key, V value) {
put(key, value);
}
@Override
public void clear() {
super.clear();
}
public V getElement(K key) {
public synchronized V getElement(K key) {
return get(key);
}
public V removeElement(K key) {
public synchronized V removeElement(K key) {
return remove(key);
}
@Override
public int size() {
return super.size();
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> entry) {
return size() > maxCapacity;

View File

@ -19,7 +19,6 @@ package org.mcteam.factions.gson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -45,9 +44,9 @@ import java.util.Map;
* But GSON is unable to deserialize this value because the JSON string name is
* just the {@link Object#toString() toString()} of the map key. Attempting to
* convert the above JSON to an object fails with a parse exception:
* <pre>com.bukkit.mcteam.gson.JsonParseException: Expecting object found: "(5,6)"
* at com.bukkit.mcteam.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler
* at com.bukkit.mcteam.gson.ObjectNavigator.navigateClassFields
* <pre>org.mcteam.factions.gson.JsonParseException: Expecting object found: "(5,6)"
* at org.mcteam.factions.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler
* at org.mcteam.factions.gson.ObjectNavigator.navigateClassFields
* ...</pre>
*
* <h3>Maps as JSON arrays</h3>
@ -90,12 +89,13 @@ import java.util.Map;
* complex. A key is complex if its JSON-serialized form is an array or an
* object.
*/
public final class MapAsArrayTypeAdapter
final class MapAsArrayTypeAdapter
extends BaseMapTypeAdapter
implements JsonSerializer<Map<?, ?>>, JsonDeserializer<Map<?, ?>> {
public Map<?, ?> deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
Map<Object, Object> result = new LinkedHashMap<Object, Object>();
Map<Object, Object> result = constructMapType(typeOfT, context);
Type[] keyAndValueType = typeToTypeArguments(typeOfT);
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
@ -123,10 +123,10 @@ public final class MapAsArrayTypeAdapter
boolean serializeAsArray = false;
List<JsonElement> keysAndValues = new ArrayList<JsonElement>();
for (Map.Entry<?, ?> entry : src.entrySet()) {
JsonElement key = context.serialize(entry.getKey(), keyAndValueType[0]);
JsonElement key = serialize(context, entry.getKey(), keyAndValueType[0]);
serializeAsArray |= key.isJsonObject() || key.isJsonArray();
keysAndValues.add(key);
keysAndValues.add(context.serialize(entry.getValue(), keyAndValueType[1]));
keysAndValues.add(serialize(context, entry.getValue(), keyAndValueType[1]));
}
if (serializeAsArray) {

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2011 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.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
/**
* 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.
*
* @author Joel Leitch
*/
@SuppressWarnings("unchecked")
final class MapTypeAdapter 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]);
Object value = context.deserialize(entry.getValue(), keyAndValueTypes[1]);
map.put(key, value);
}
return map;
}
@Override
public String toString() {
return MapTypeAdapter.class.getSimpleName();
}
}

View File

@ -16,13 +16,10 @@
package org.mcteam.factions.gson;
import java.lang.reflect.AccessibleObject;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This class contains a mapping of all the application specific
@ -35,7 +32,9 @@ import java.util.logging.Logger;
* @author Joel Leitch
*/
final class MappedObjectConstructor implements ObjectConstructor {
private static final Logger log = Logger.getLogger(MappedObjectConstructor.class.getName());
private static final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create();
private static final DefaultConstructorAllocator defaultConstructorAllocator =
new DefaultConstructorAllocator(500);
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap;
@ -50,60 +49,26 @@ final class MappedObjectConstructor implements ObjectConstructor {
if (creator != null) {
return creator.createInstance(typeOfT);
}
return (T) constructWithNoArgConstructor(typeOfT);
return (T) constructWithAllocators(typeOfT);
}
public Object constructArray(Type type, int length) {
return Array.newInstance(TypeUtils.toRawClass(type), length);
}
private <T> T constructWithNoArgConstructor(Type typeOfT) {
try {
Constructor<T> constructor = getNoArgsConstructor(typeOfT);
if (constructor == null) {
throw new RuntimeException(("No-args constructor for " + typeOfT + " does not exist. "
+ "Register an InstanceCreator with Gson for this type to fix this problem."));
}
return constructor.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
} catch (IllegalAccessException e) {
throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
} catch (InvocationTargetException e) {
throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
}
return Array.newInstance($Gson$Types.getRawType(type), length);
}
@SuppressWarnings({"unchecked", "cast"})
private <T> Constructor<T> getNoArgsConstructor(Type typeOfT) {
TypeInfo typeInfo = new TypeInfo(typeOfT);
Class<T> clazz = (Class<T>) typeInfo.getRawClass();
Constructor<T>[] declaredConstructors = (Constructor<T>[]) clazz.getDeclaredConstructors();
AccessibleObject.setAccessible(declaredConstructors, true);
for (Constructor<T> constructor : declaredConstructors) {
if (constructor.getParameterTypes().length == 0) {
return constructor;
private <T> T constructWithAllocators(Type typeOfT) {
try {
Class<T> clazz = (Class<T>) $Gson$Types.getRawType(typeOfT);
T obj = defaultConstructorAllocator.newInstance(clazz);
return (obj == null)
? unsafeAllocator.newInstance(clazz)
: obj;
} catch (Exception e) {
throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
}
}
return null;
}
/**
* Use this methods to register an {@link InstanceCreator} for a new type.
*
* @param <T> the type of class to be mapped with its "creator"
* @param typeOfT the instance type that will be created
* @param creator the {@link InstanceCreator} instance to register
*/
<T> void register(Type typeOfT, InstanceCreator<? extends T> creator) {
if (instanceCreatorMap.hasSpecificHandlerFor(typeOfT)) {
log.log(Level.WARNING, "Overriding the existing InstanceCreator for {0}", typeOfT);
}
instanceCreatorMap.register(typeOfT, creator);
}
@Override
public String toString() {

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.util.Stack;
/**
@ -35,8 +37,7 @@ final class MemoryRefStack {
* @return the object that was added
*/
public ObjectTypePair push(ObjectTypePair obj) {
Preconditions.checkNotNull(obj);
$Gson$Preconditions.checkNotNull(obj);
return stack.push(obj);
}

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;
@ -62,9 +64,8 @@ final class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy {
* @param modifier the type of modification that should be performed
* @throws IllegalArgumentException if {@code modifier} is null
*/
public ModifyFirstLetterNamingPolicy(LetterModifier modifier) {
Preconditions.checkNotNull(modifier);
this.letterModifier = modifier;
ModifyFirstLetterNamingPolicy(LetterModifier modifier) {
this.letterModifier = $Gson$Preconditions.checkNotNull(modifier);
}
@Override
@ -100,8 +101,8 @@ final class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy {
}
private String modifyString(char firstCharacter, String srcString, int indexOfSubstring) {
return indexOfSubstring < srcString.length() ?
firstCharacter + srcString.substring(indexOfSubstring)
return (indexOfSubstring < srcString.length())
? firstCharacter + srcString.substring(indexOfSubstring)
: String.valueOf(firstCharacter);
}
}

View File

@ -16,7 +16,6 @@
package org.mcteam.factions.gson;
/**
* This acts as a "Null Object" pattern for the {@link ExclusionStrategy}.
* Passing an instance of this class into the {@link ObjectNavigator} will

View File

@ -16,8 +16,8 @@
package org.mcteam.factions.gson;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.Type;
/**
@ -69,38 +69,33 @@ final class ObjectNavigator {
public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField,
Object parent);
void visitPrimitive(Object primitive);
/**
* Retrieve the current target
*/
Object getTarget();
void visitPrimitive(Object primitive);
}
private final ExclusionStrategy exclusionStrategy;
private final ObjectTypePair objTypePair;
private final ReflectingFieldNavigator reflectingFieldNavigator;
/**
* @param objTypePair
* The object,type (fully genericized) being navigated
* @param exclusionStrategy
* the concrete strategy object to be used to filter out fields of an
* @param strategy the concrete exclusion strategy object to be used to filter out fields of an
* object.
*/
ObjectNavigator(ObjectTypePair objTypePair, ExclusionStrategy exclusionStrategy) {
Preconditions.checkNotNull(exclusionStrategy);
this.objTypePair = objTypePair;
this.exclusionStrategy = exclusionStrategy;
ObjectNavigator(ExclusionStrategy strategy) {
this.exclusionStrategy = strategy == null ? new NullExclusionStrategy() : strategy;
this.reflectingFieldNavigator = new ReflectingFieldNavigator(exclusionStrategy);
}
/**
* Navigate all the fields of the specified object. If a field is null, it
* does not get visited.
* @param objTypePair The object,type (fully genericized) being navigated
*/
public void accept(Visitor visitor) {
TypeInfo objTypeInfo = new TypeInfo(objTypePair.type);
if (exclusionStrategy.shouldSkipClass(objTypeInfo.getRawClass())) {
public void accept(ObjectTypePair objTypePair, Visitor visitor) {
if (exclusionStrategy.shouldSkipClass($Gson$Types.getRawType(objTypePair.type))) {
return;
}
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
@ -113,24 +108,16 @@ final class ObjectNavigator {
objTypePair.setObject(objectToVisit);
visitor.start(objTypePair);
try {
if (objTypeInfo.isArray()) {
if ($Gson$Types.isArray(objTypePair.type)) {
visitor.visitArray(objectToVisit, objTypePair.type);
} else if (objTypeInfo.getActualType() == Object.class
&& isPrimitiveOrString(objectToVisit)) {
} else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) {
// TODO(Joel): this is only used for deserialization of "primitives"
// we should rethink this!!!
visitor.visitPrimitive(objectToVisit);
objectToVisit = visitor.getTarget();
visitor.getTarget();
} else {
visitor.startVisitingObject(objectToVisit);
ObjectTypePair currObjTypePair = objTypePair.toMoreSpecificType();
Class<?> topLevelClass = new TypeInfo(currObjTypePair.type).getRawClass();
for (Class<?> curr = topLevelClass; curr != null && !curr.equals(Object.class); curr =
curr.getSuperclass()) {
if (!curr.isSynthetic()) {
navigateClassFields(objectToVisit, curr, visitor);
}
}
reflectingFieldNavigator.visitFieldsReflectively(objTypePair, visitor);
}
} finally {
visitor.end(objTypePair);
@ -138,32 +125,9 @@ final class ObjectNavigator {
}
}
private boolean isPrimitiveOrString(Object objectToVisit) {
private static boolean isPrimitiveOrString(Object objectToVisit) {
Class<?> realClazz = objectToVisit.getClass();
return realClazz == Object.class || realClazz == String.class
|| Primitives.unwrap(realClazz).isPrimitive();
}
private void navigateClassFields(Object obj, Class<?> clazz, Visitor visitor) {
Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
for (Field f : fields) {
FieldAttributes fieldAttributes = new FieldAttributes(clazz, f);
if (exclusionStrategy.shouldSkipField(fieldAttributes)
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) {
continue; // skip
}
TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objTypePair.type);
Type declaredTypeOfField = fieldTypeInfo.getActualType();
boolean visitedWithCustomHandler =
visitor.visitFieldUsingCustomHandler(fieldAttributes, declaredTypeOfField, obj);
if (!visitedWithCustomHandler) {
if (fieldTypeInfo.isArray()) {
visitor.visitArrayField(fieldAttributes, declaredTypeOfField, obj);
} else {
visitor.visitObjectField(fieldAttributes, declaredTypeOfField, obj);
}
}
}
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
/**
* A factory class used to simplify {@link ObjectNavigator} creation.
* This object holds on to a reference of the {@link ExclusionStrategy}
* that you'd like to use with the {@link ObjectNavigator}.
*
* @author Joel Leitch
*/
final class ObjectNavigatorFactory {
private final ExclusionStrategy strategy;
private final FieldNamingStrategy2 fieldNamingPolicy;
/**
* Creates a factory object that will be able to create new
* {@link ObjectNavigator}s with the provided {@code strategy}
*
* @param strategy the exclusion strategy to use with every instance that
* is created by this factory instance.
* @param fieldNamingPolicy the naming policy that should be applied to field
* names
*/
public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy2 fieldNamingPolicy) {
Preconditions.checkNotNull(fieldNamingPolicy);
this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy);
this.fieldNamingPolicy = fieldNamingPolicy;
}
/**
* Creates a new {@link ObjectNavigator} for this {@code srcObject},
* {@code type} pair.
*
* @param objTypePair The object,type (fully genericized) being navigated
* @return a new instance of a {@link ObjectNavigator} ready to navigate the
* {@code srcObject} while taking into consideration the
* {@code type}.
*/
public ObjectNavigator create(ObjectTypePair objTypePair) {
return new ObjectNavigator(objTypePair, strategy);
}
FieldNamingStrategy2 getFieldNamingPolicy() {
return fieldNamingPolicy;
}
}

View File

@ -15,6 +15,7 @@
*/
package org.mcteam.factions.gson;
import java.lang.reflect.Type;
/**
@ -77,6 +78,13 @@ final class ObjectTypePair {
return new ObjectTypePair(obj, actualType, preserveType);
}
Type getMoreSpecificType() {
if (preserveType || obj == null) {
return type;
}
return getActualTypeIfMoreSpecific(type, obj.getClass());
}
// This takes care of situations where the field was declared as an Object, but the
// actual value contains something more specific. See Issue 54.
// TODO (inder): This solution will not work if the field is of a generic type, but

View File

@ -26,11 +26,10 @@ package org.mcteam.factions.gson;
* @param <SECOND>
*/
final class Pair<FIRST, SECOND> {
public final FIRST first;
public final SECOND second;
final FIRST first;
final SECOND second;
Pair(FIRST first, SECOND second) {
public Pair(FIRST first, SECOND second) {
this.first = first;
this.second = second;
}

View File

@ -16,6 +16,8 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.internal.$Gson$Types;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
@ -105,6 +107,21 @@ final class ParameterizedTypeHandlerMap<T> {
}
}
public synchronized void register(ParameterizedTypeHandlerMap<T> other) {
if (!modifiable) {
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
}
for (Map.Entry<Type, T> entry : other.map.entrySet()) {
register(entry.getKey(), entry.getValue());
}
// Quite important to traverse the typeHierarchyList from stack bottom first since
// we want to register the handlers in the same order to preserve priority order
for (int i = other.typeHierarchyList.size()-1; i >= 0; --i) {
Pair<Class<?>, T> entry = other.typeHierarchyList.get(i);
registerForTypeHierarchy(entry);
}
}
public synchronized void registerIfAbsent(Type typeOfT, T value) {
if (!modifiable) {
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
@ -121,7 +138,7 @@ final class ParameterizedTypeHandlerMap<T> {
public synchronized T getHandlerFor(Type type) {
T handler = map.get(type);
if (handler == null) {
Class<?> rawClass = TypeUtils.toRawClass(type);
Class<?> rawClass = $Gson$Types.getRawType(type);
if (rawClass != type) {
handler = getHandlerFor(rawClass);
}
@ -157,12 +174,10 @@ final class ParameterizedTypeHandlerMap<T> {
public synchronized ParameterizedTypeHandlerMap<T> copyOf() {
ParameterizedTypeHandlerMap<T> copy = new ParameterizedTypeHandlerMap<T>();
for (Map.Entry<Type, T> entry : map.entrySet()) {
copy.register(entry.getKey(), entry.getValue());
}
for (Pair<Class<?>, T> entry : typeHierarchyList) {
copy.registerForTypeHierarchy(entry);
}
// Instead of individually registering entries in the map, make an efficient copy
// of the list and map
copy.map.putAll(map);
copy.typeHierarchyList.addAll(typeHierarchyList);
return copy;
}
@ -195,6 +210,6 @@ final class ParameterizedTypeHandlerMap<T> {
}
private String typeToString(Type type) {
return TypeUtils.toRawClass(type).getSimpleName();
return $Gson$Types.getRawType(type).getSimpleName();
}
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
/**
* An immutable implementation of the {@link ParameterizedType} interface. This object allows
* us to build a reflective {@link Type} objects on demand. This object is used to support
* serialization and deserialization of classes with an {@code ParameterizedType} field where
* as least one of the actual type parameters is a {@code TypeVariable}.
*
* <p>Here's an example class:
* <pre>
* class Foo<T> {
* private List<T> someList;
*
* Foo(List<T> list) {
* this.someList = list;
* }
* }
* </pre>
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class ParameterizedTypeImpl implements ParameterizedType {
private final Type rawType;
private final Type[] actualTypeArguments;
private final Type owner;
public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type owner) {
this.rawType = rawType;
this.actualTypeArguments = actualTypeArguments;
this.owner = owner;
}
public Type getRawType() {
return rawType;
}
public Type[] getActualTypeArguments() {
return actualTypeArguments;
}
public Type getOwnerType() {
return owner;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ParameterizedType)) {
return false;
}
// Check that information is equivalent
ParameterizedType that = (ParameterizedType) o;
if (this == that) {
return true;
}
Type thatOwner = that.getOwnerType();
Type thatRawType = that.getRawType();
return (owner == null ? thatOwner == null : owner.equals(thatOwner))
&& (rawType == null ? thatRawType == null : rawType.equals(thatRawType))
&& Arrays.equals(actualTypeArguments, that.getActualTypeArguments());
}
@Override
public int hashCode() {
return Arrays.hashCode(actualTypeArguments)
^ (owner == null ? 0 : owner.hashCode())
^ (rawType == null ? 0 : rawType.hashCode());
}
}

View File

@ -16,10 +16,14 @@
package org.mcteam.factions.gson;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
/**
* Contains static utility methods pertaining to primitive types and their
* corresponding wrapper types.
@ -30,10 +34,10 @@ final class Primitives {
private Primitives() {}
/** A map from primitive types to their corresponding wrapper types. */
public static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
/** A map from wrapper types to their corresponding primitive types. */
public static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
// Sad that we can't use a BiMap. :(
@ -61,6 +65,13 @@ final class Primitives {
backward.put(value, key);
}
/**
* Returns true if this type is a primitive.
*/
public static boolean isPrimitive(Type type) {
return PRIMITIVE_TO_WRAPPER_TYPE.containsKey(type);
}
/**
* Returns {@code true} if {@code type} is one of the nine
* primitive-wrapper types, such as {@link Integer}.
@ -68,12 +79,8 @@ final class Primitives {
* @see Class#isPrimitive
*/
public static boolean isWrapperType(Class<?> type) {
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type));
}
private static Class<?> checkNotNull(Class<?> type) {
Preconditions.checkNotNull(type);
return type;
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(
$Gson$Preconditions.checkNotNull(type));
}
/**
@ -86,11 +93,10 @@ final class Primitives {
* </pre>
*/
public static <T> Class<T> wrap(Class<T> type) {
checkNotNull(type);
// cast is safe: long.class and Long.class are both of type Class<Long>
@SuppressWarnings("unchecked")
Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(type);
Class<T> wrapped = (Class<T>) PRIMITIVE_TO_WRAPPER_TYPE.get(
$Gson$Preconditions.checkNotNull(type));
return (wrapped == null) ? type : wrapped;
}
@ -104,11 +110,10 @@ final class Primitives {
* </pre>
*/
public static <T> Class<T> unwrap(Class<T> type) {
checkNotNull(type);
// cast is safe: long.class and Long.class are both of type Class<Long>
@SuppressWarnings("unchecked")
Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(type);
Class<T> unwrapped = (Class<T>) WRAPPER_TO_PRIMITIVE_TYPE.get(
$Gson$Preconditions.checkNotNull(type));
return (unwrapped == null) ? type : unwrapped;
}
}

View File

@ -30,7 +30,6 @@ import java.util.Collection;
abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy2 {
public final String translateName(FieldAttributes f) {
Preconditions.checkNotNull(f);
return translateName(f.getName(), f.getDeclaredType(), f.getAnnotations());
}

View File

@ -0,0 +1,106 @@
/*
* Copyright (C) 2011 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.mcteam.factions.gson;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.mcteam.factions.gson.ObjectNavigator.Visitor;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import org.mcteam.factions.gson.internal.$Gson$Types;
/**
* Visits each of the fields of the specified class using reflection
*
* @author Inderjeet Singh
* @author Joel Leitch
* @author Jesse Wilson
*/
final class ReflectingFieldNavigator {
private static final Cache<Type, List<FieldAttributes>> fieldsCache =
new LruCache<Type, List<FieldAttributes>>(500);
private final ExclusionStrategy exclusionStrategy;
/**
* @param exclusionStrategy the concrete strategy object to be used to filter out fields of an
* object.
*/
ReflectingFieldNavigator(ExclusionStrategy exclusionStrategy) {
this.exclusionStrategy = $Gson$Preconditions.checkNotNull(exclusionStrategy);
}
/**
* @param objTypePair The object,type (fully genericized) being navigated
* @param visitor the visitor to visit each field with
*/
void visitFieldsReflectively(ObjectTypePair objTypePair, Visitor visitor) {
Type moreSpecificType = objTypePair.getMoreSpecificType();
Object obj = objTypePair.getObject();
for (FieldAttributes fieldAttributes : getAllFields(moreSpecificType, objTypePair.getType())) {
if (exclusionStrategy.shouldSkipField(fieldAttributes)
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) {
continue; // skip
}
Type resolvedTypeOfField = fieldAttributes.getResolvedType();
boolean visitedWithCustomHandler =
visitor.visitFieldUsingCustomHandler(fieldAttributes, resolvedTypeOfField, obj);
if (!visitedWithCustomHandler) {
if ($Gson$Types.isArray(resolvedTypeOfField)) {
visitor.visitArrayField(fieldAttributes, resolvedTypeOfField, obj);
} else {
visitor.visitObjectField(fieldAttributes, resolvedTypeOfField, obj);
}
}
}
}
private List<FieldAttributes> getAllFields(Type type, Type declaredType) {
List<FieldAttributes> fields = fieldsCache.getElement(type);
if (fields == null) {
fields = new ArrayList<FieldAttributes>();
for (Class<?> curr : getInheritanceHierarchy(type)) {
Field[] currentClazzFields = curr.getDeclaredFields();
AccessibleObject.setAccessible(currentClazzFields, true);
Field[] classFields = currentClazzFields;
for (Field f : classFields) {
fields.add(new FieldAttributes(curr, f, declaredType));
}
}
fieldsCache.addElement(type, fields);
}
return fields;
}
/**
* Returns a list of classes corresponding to the inheritance of specified type
*/
private List<Class<?>> getInheritanceHierarchy(Type type) {
List<Class<?>> classes = new ArrayList<Class<?>>();
Class<?> topLevelClass = $Gson$Types.getRawType(type);
for (Class<?> curr = topLevelClass; curr != null && !curr.equals(Object.class); curr =
curr.getSuperclass()) {
if (!curr.isSynthetic()) {
classes.add(curr);
}
}
return classes;
}
}

View File

@ -20,29 +20,29 @@ import org.mcteam.factions.gson.annotations.SerializedName;
/**
* A {@link FieldNamingStrategy2} that acts as a chain of responsibility. If the
* {@link org.mcteam.factions.gson.annotations.SerializedName} annotation is applied to a field then this
* strategy will translate the name to the {@code serializedName.value()}; otherwise it delegates
* to the wrapped {@link FieldNamingStrategy2}.
* {@link org.mcteam.factions.gson.annotations.SerializedName} annotation is applied to a
* field then this strategy will translate the name to the {@code
* serializedName.value()}; otherwise it delegates to the wrapped
* {@link FieldNamingStrategy2}.
*
* <p>NOTE: this class performs JSON field name validation for any of the fields marked with
* an {@code @SerializedName} annotation.</p>
* <p>
* NOTE: this class performs JSON field name validation for any of the fields
* marked with an {@code @SerializedName} annotation.
* </p>
*
* @see SerializedName
*
* @author Joel Leitch
*/
final class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy2 {
private static final JsonFieldNameValidator fieldNameValidator = new JsonFieldNameValidator();
private final FieldNamingStrategy2 delegate;
public SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy2 delegate) {
SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy2 delegate) {
this.delegate = delegate;
}
public String translateName(FieldAttributes f) {
Preconditions.checkNotNull(f);
SerializedName serializedName = f.getAnnotation(SerializedName.class);
return serializedName == null ? delegate.translateName(f)
: fieldNameValidator.validate(serializedName.value());
return serializedName == null ? delegate.translateName(f) : serializedName.value();
}
}

View File

@ -16,15 +16,14 @@
package org.mcteam.factions.gson;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonWriter;
import org.mcteam.factions.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import org.mcteam.factions.gson.stream.JsonReader;
import org.mcteam.factions.gson.stream.JsonWriter;
import org.mcteam.factions.gson.stream.MalformedJsonException;
/**
* Reads and writes GSON parse trees over streams.
*/

View File

@ -26,7 +26,7 @@ package org.mcteam.factions.gson;
*
* @since 1.4
*/
class SyntheticFieldExclusionStrategy implements ExclusionStrategy {
final class SyntheticFieldExclusionStrategy implements ExclusionStrategy {
private final boolean skipSyntheticFields;
SyntheticFieldExclusionStrategy(boolean skipSyntheticFields) {

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
/**
* This class is responsible for adapting/converting an particular "from"
* instance to an instance of type "to".
*
* @author Joel Leitch
*/
interface TypeAdapter {
/**
* Adapts an object instance "from" to and instance of type "to".
*
* @param from the object to adapt
* @param to the Type/Class which this will convert to
* @return the converted "from" instance to type "to"
*/
public <T> T adaptType(Object from, Class<T> to);
}

View File

@ -1,76 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.Type;
import java.util.Collection;
/**
* Class that provides information relevant to different parts of a type.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
class TypeInfo {
protected final Type actualType;
protected final Class<?> rawClass;
TypeInfo(Type actualType) {
this.actualType = actualType;
rawClass = TypeUtils.toRawClass(actualType);
}
public final Type getActualType() {
return actualType;
}
/**
* Returns the corresponding wrapper type of {@code type} if it is a primitive
* type; otherwise returns {@code type} itself. Idempotent.
* <pre>
* wrap(int.class) == Integer.class
* wrap(Integer.class) == Integer.class
* wrap(String.class) == String.class
* </pre>
*/
public final Class<?> getWrappedClass() {
return Primitives.wrap(rawClass);
}
/**
* @return the raw class associated with this type
*/
public final Class<?> getRawClass() {
return rawClass;
}
public final boolean isCollectionOrArray() {
return Collection.class.isAssignableFrom(rawClass) || isArray();
}
public final boolean isArray() {
return TypeUtils.isArray(rawClass);
}
public final boolean isEnum() {
return rawClass.isEnum();
}
public final boolean isPrimitive() {
return Primitives.isWrapperType(Primitives.wrap(rawClass));
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;
/**
* Class to extract information about types used to define a generic array.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeInfoArray extends TypeInfo {
private final Class<?> componentRawType;
private final Type secondLevel;
TypeInfoArray(Type type) {
super(type);
Class<?> rootComponentType = rawClass;
while (rootComponentType.isArray()) {
rootComponentType = rootComponentType.getComponentType();
}
this.componentRawType = rootComponentType;
this.secondLevel = extractSecondLevelType(actualType, rawClass);
}
private static Type extractSecondLevelType(Type actualType, Class<?> rawClass) {
return actualType instanceof GenericArrayType ?
((GenericArrayType) actualType).getGenericComponentType() : rawClass.getComponentType();
}
/**
* @return the raw type unwrapped of the second level of array.
* If the object is (single-dimensional or multi-dimensional) array, it is the class of the
* elements of the array. For example, this method returns Foo.class for Foo[].
* It will return Foo[].class for Foo[][]. For Foo&lt;String&gt;[][] types, it will return the
* type representing Foo&lt;String&gt;[]
* (i.e. <code>new TypeToken<Foo<String>[]>() {}.getType()</code>).
*/
public Type getSecondLevelType() {
return secondLevel;
}
/**
* @return the raw type of the root component.
* If the object is a single-dimensional array then the component type is the class of an
* element of the array.
* If the object is a multi-dimensional array then the component type is the class of the
* inner-most array element. For example, the This method will return Foo.class for Foo[][][].
*/
public Class<?> getComponentRawType() {
return componentRawType;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
/**
* A convenience object for retrieving the map type information.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeInfoCollection {
private final ParameterizedType collectionType;
public TypeInfoCollection(Type collectionType) {
if (!(collectionType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Collection objects need to be parameterized unless you use a custom serializer. "
+ "Use the com.bukkit.mcteam.gson.reflect.TypeToken to extract the ParameterizedType.");
}
TypeInfo rawType = new TypeInfo(collectionType);
Preconditions.checkArgument(Collection.class.isAssignableFrom(rawType.getRawClass()));
this.collectionType = (ParameterizedType) collectionType;
}
public Type getElementType() {
return collectionType.getActualTypeArguments()[0];
}
}

View File

@ -1,175 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
/**
* A static factory class used to construct the "TypeInfo" objects.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeInfoFactory {
private TypeInfoFactory() {
// Not instantiable since it provides factory methods only.
}
public static TypeInfoArray getTypeInfoForArray(Type type) {
Preconditions.checkArgument(TypeUtils.isArray(type));
return new TypeInfoArray(type);
}
/**
* Evaluates the "actual" type for the field. If the field is a "TypeVariable" or has a
* "TypeVariable" in a parameterized type then it evaluates the real type.
*
* @param f the actual field object to retrieve the type from
* @param typeDefiningF the type that contains the field {@code f}
* @return the type information for the field
*/
public static TypeInfo getTypeInfoForField(Field f, Type typeDefiningF) {
Class<?> classDefiningF = TypeUtils.toRawClass(typeDefiningF);
Type type = f.getGenericType();
Type actualType = getActualType(type, typeDefiningF, classDefiningF);
return new TypeInfo(actualType);
}
private static Type getActualType(
Type typeToEvaluate, Type parentType, Class<?> rawParentClass) {
if (typeToEvaluate instanceof Class<?>) {
return typeToEvaluate;
} else if (typeToEvaluate instanceof ParameterizedType) {
ParameterizedType castedType = (ParameterizedType) typeToEvaluate;
Type owner = castedType.getOwnerType();
Type[] actualTypeParameters =
extractRealTypes(castedType.getActualTypeArguments(), parentType, rawParentClass);
Type rawType = castedType.getRawType();
return new ParameterizedTypeImpl(rawType, actualTypeParameters, owner);
} else if (typeToEvaluate instanceof GenericArrayType) {
GenericArrayType castedType = (GenericArrayType) typeToEvaluate;
Type componentType = castedType.getGenericComponentType();
Type actualType = getActualType(componentType, parentType, rawParentClass);
if (componentType.equals(actualType)) {
return castedType;
}
return actualType instanceof Class<?> ?
TypeUtils.wrapWithArray(TypeUtils.toRawClass(actualType))
: new GenericArrayTypeImpl(actualType);
} else if (typeToEvaluate instanceof TypeVariable<?>) {
if (parentType instanceof ParameterizedType) {
// The class definition has the actual types used for the type variables.
// Find the matching actual type for the Type Variable used for the field.
// For example, class Foo<A> { A a; }
// new Foo<Integer>(); defines the actual type of A to be Integer.
// So, to find the type of the field a, we will have to look at the class'
// actual type arguments.
TypeVariable<?> fieldTypeVariable = (TypeVariable<?>) typeToEvaluate;
TypeVariable<?>[] classTypeVariables = rawParentClass.getTypeParameters();
ParameterizedType objParameterizedType = (ParameterizedType) parentType;
int indexOfActualTypeArgument = getIndex(classTypeVariables, fieldTypeVariable);
Type[] actualTypeArguments = objParameterizedType.getActualTypeArguments();
return actualTypeArguments[indexOfActualTypeArgument];
} else if (typeToEvaluate instanceof TypeVariable<?>) {
Type theSearchedType = null;
do {
theSearchedType = extractTypeForHierarchy(parentType, (TypeVariable<?>) typeToEvaluate);
} while ((theSearchedType != null) && (theSearchedType instanceof TypeVariable<?>));
if (theSearchedType != null) {
return theSearchedType;
}
}
throw new UnsupportedOperationException("Expecting parameterized type, got " + parentType
+ ".\n Are you missing the use of TypeToken idiom?\n See "
+ "http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener");
} else if (typeToEvaluate instanceof WildcardType) {
WildcardType castedType = (WildcardType) typeToEvaluate;
return getActualType(castedType.getUpperBounds()[0], parentType, rawParentClass);
} else {
throw new IllegalArgumentException("Type \'" + typeToEvaluate + "\' is not a Class, "
+ "ParameterizedType, GenericArrayType or TypeVariable. Can't extract type.");
}
}
private static Type extractTypeForHierarchy(Type parentType, TypeVariable<?> typeToEvaluate) {
Class<?> rawParentType = null;
if (parentType instanceof Class<?>) {
rawParentType = (Class<?>) parentType;
} else if (parentType instanceof ParameterizedType) {
ParameterizedType parentTypeAsPT = (ParameterizedType) parentType;
rawParentType = (Class<?>) parentTypeAsPT.getRawType();
} else {
return null;
}
Type superClass = rawParentType.getGenericSuperclass();
if (superClass instanceof ParameterizedType
&& ((ParameterizedType) superClass).getRawType() == typeToEvaluate.getGenericDeclaration()) {
// Evaluate type on this type
TypeVariable<?>[] classTypeVariables =
((Class<?>) ((ParameterizedType) superClass).getRawType()).getTypeParameters();
int indexOfActualTypeArgument = getIndex(classTypeVariables, typeToEvaluate);
Type[] actualTypeArguments = null;
if (parentType instanceof Class<?>) {
actualTypeArguments = ((ParameterizedType) superClass).getActualTypeArguments();
} else if (parentType instanceof ParameterizedType) {
actualTypeArguments = ((ParameterizedType) parentType).getActualTypeArguments();
} else {
return null;
}
return actualTypeArguments[indexOfActualTypeArgument];
}
Type searchedType = null;
if (superClass != null) {
searchedType = extractTypeForHierarchy(superClass, typeToEvaluate);
}
return searchedType;
}
private static Type[] extractRealTypes(
Type[] actualTypeArguments, Type parentType, Class<?> rawParentClass) {
Preconditions.checkNotNull(actualTypeArguments);
Type[] retTypes = new Type[actualTypeArguments.length];
for (int i = 0; i < actualTypeArguments.length; ++i) {
retTypes[i] = getActualType(actualTypeArguments[i], parentType, rawParentClass);
}
return retTypes;
}
private static int getIndex(TypeVariable<?>[] types, TypeVariable<?> type) {
for (int i = 0; i < types.length; ++i) {
if (type.equals(types[i])) {
return i;
}
}
throw new IllegalStateException(
"How can the type variable not be present in the class declaration!");
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Properties;
/**
* A convenience object for retrieving the map type information.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeInfoMap {
private final Type keyType;
private final Type valueType;
public TypeInfoMap(Type mapType) {
if (mapType instanceof Class<?> && Properties.class.isAssignableFrom((Class<?>) mapType)) {
keyType = String.class;
valueType = String.class;
} else if (mapType instanceof ParameterizedType) {
TypeInfo rawType = new TypeInfo(mapType);
Preconditions.checkArgument(Map.class.isAssignableFrom(rawType.getRawClass()));
ParameterizedType paramType = (ParameterizedType) mapType;
keyType = paramType.getActualTypeArguments()[0];
valueType = paramType.getActualTypeArguments()[1];
} else {
throw new IllegalArgumentException(
"Map objects need to be parameterized unless you use a custom serializer. "
+ "Use the com.bukkit.mcteam.gson.reflect.TypeToken to extract the ParameterizedType.");
}
}
public Type getKeyType() {
return keyType;
}
public Type getValueType() {
return valueType;
}
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2008 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.mcteam.factions.gson;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
/**
* Utility class containing some methods for obtaining information on types.
*
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class TypeUtils {
/**
* Returns the actual type matching up with the first type variable.
* So, for a {@code typeInfo} instance defined as:
* <pre>
* class Foo<A, B> {
* }
* Type fooType = new TypeToken<Foo<Integer, String>>() {}.getType();
* </pre>
* <code>TypeUtils.getActualTypeForFirstTypeVariable(fooType)</code> will return Integer.class.
*/
static Type getActualTypeForFirstTypeVariable(Type type) {
if (type instanceof Class<?>) {
return Object.class;
} else if (type instanceof ParameterizedType) {
return ((ParameterizedType)type).getActualTypeArguments()[0];
} else if (type instanceof GenericArrayType) {
return getActualTypeForFirstTypeVariable(((GenericArrayType)type).getGenericComponentType());
} else {
throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+ "ParameterizedType, or GenericArrayType. Can't extract class.");
}
}
static boolean isArray(Type type) {
if (type instanceof Class<?>) {
return ((Class<?>)type).isArray();
} else if (type instanceof GenericArrayType) {
return true;
} else {
return false;
}
}
/**
* This method returns the actual raw class associated with the specified type.
*/
static Class<?> toRawClass(Type type) {
if (type instanceof Class<?>) {
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType actualType = (ParameterizedType)type;
return toRawClass(actualType.getRawType());
} else if (type instanceof GenericArrayType) {
GenericArrayType actualType = (GenericArrayType) type;
Class<?> rawClass = toRawClass(actualType.getGenericComponentType());
return wrapWithArray(rawClass);
} else if (type instanceof WildcardType) {
WildcardType castedType = (WildcardType) type;
return toRawClass(castedType.getUpperBounds()[0]);
} else {
throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, "
+ "ParameterizedType, or GenericArrayType. Can't extract class.");
}
}
static Class<?> wrapWithArray(Class<?> rawClass) {
return Array.newInstance(rawClass, 0).getClass();
}
private TypeUtils() {
// Class with just some static utility methods, should not be instantiated
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2011 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.mcteam.factions.gson;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Do sneaky things to allocate objects without invoking their constructors.
*
* @author Joel Leitch
* @author Jesse Wilson
*/
abstract class UnsafeAllocator {
public abstract <T> T newInstance(Class<T> c) throws Exception;
public static UnsafeAllocator create() {
// try JVM
// public class Unsafe {
// public Object allocateInstance(Class<?> type);
// }
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
Field f = unsafeClass.getDeclaredField("theUnsafe");
f.setAccessible(true);
final Object unsafe = f.get(null);
final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);
return new UnsafeAllocator() {
@Override
@SuppressWarnings("unchecked")
public <T> T newInstance(Class<T> c) throws Exception {
return (T) allocateInstance.invoke(unsafe, c);
}
};
} catch (Exception ignored) {
}
// try dalvikvm, pre-gingerbread
// public class ObjectInputStream {
// private static native Object newInstance(
// Class<?> instantiationClass, Class<?> constructorClass);
// }
try {
final Method newInstance = ObjectInputStream.class
.getDeclaredMethod("newInstance", Class.class, Class.class);
newInstance.setAccessible(true);
return new UnsafeAllocator() {
@Override
@SuppressWarnings("unchecked")
public <T> T newInstance(Class<T> c) throws Exception {
return (T) newInstance.invoke(null, c, Object.class);
}
};
} catch (Exception ignored) {
}
// try dalvivkm, post-gingerbread
// public class ObjectStreamClass {
// private static native int getConstructorId(Class<?> c);
// private static native Object newInstance(Class<?> instantiationClass, int methodId);
// }
try {
Method getConstructorId = ObjectStreamClass.class
.getDeclaredMethod("getConstructorId", Class.class);
getConstructorId.setAccessible(true);
final int constructorId = (Integer) getConstructorId.invoke(null, Object.class);
final Method newInstance = ObjectStreamClass.class
.getDeclaredMethod("newInstance", Class.class, int.class);
newInstance.setAccessible(true);
return new UnsafeAllocator() {
@Override
@SuppressWarnings("unchecked")
public <T> T newInstance(Class<T> c) throws Exception {
return (T) newInstance.invoke(null, c, constructorId);
}
};
} catch (Exception ignored) {
}
// give up
return new UnsafeAllocator() {
@Override
public <T> T newInstance(Class<T> c) {
throw new UnsupportedOperationException("Cannot allocate " + c);
}
};
}
}

View File

@ -18,6 +18,7 @@ package org.mcteam.factions.gson;
import org.mcteam.factions.gson.annotations.Since;
import org.mcteam.factions.gson.annotations.Until;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
/**
* This strategy will exclude any files and/or class that are passed the
@ -28,8 +29,8 @@ import org.mcteam.factions.gson.annotations.Until;
final class VersionExclusionStrategy implements ExclusionStrategy {
private final double version;
public VersionExclusionStrategy(double version) {
Preconditions.checkArgument(version >= 0.0D);
VersionExclusionStrategy(double version) {
$Gson$Preconditions.checkArgument(version >= 0.0D);
this.version = version;
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.mcteam.factions.gson;
package org.mcteam.factions.gson.internal;
/**
* A simple utility class used to check method Preconditions.
@ -29,20 +29,23 @@ package org.mcteam.factions.gson;
* @author Inderjeet Singh
* @author Joel Leitch
*/
final class Preconditions {
public static void checkNotNull(Object obj) {
checkArgument(obj != null);
public final class $Gson$Preconditions {
public static <T> T checkNotNull(T obj) {
if (obj == null) {
throw new NullPointerException();
}
return obj;
}
public static void checkArgument(boolean condition) {
if (!condition) {
throw new IllegalArgumentException("condition failed: " + condition);
throw new IllegalArgumentException();
}
}
public static void checkState(boolean condition) {
if (!condition) {
throw new IllegalArgumentException("condition failed: " + condition);
throw new IllegalStateException();
}
}
}

View File

@ -0,0 +1,589 @@
/**
* Copyright (C) 2008 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.mcteam.factions.gson.internal;
import static org.mcteam.factions.gson.internal.$Gson$Preconditions.checkArgument;
import static org.mcteam.factions.gson.internal.$Gson$Preconditions.checkNotNull;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
/**
* Static methods for working with types.
*
* @author Bob Lee
* @author Jesse Wilson
*/
public final class $Gson$Types {
static final Type[] EMPTY_TYPE_ARRAY = new Type[] {};
private $Gson$Types() {}
/**
* Returns a new parameterized type, applying {@code typeArguments} to
* {@code rawType} and enclosed by {@code ownerType}.
*
* @return a {@link java.io.Serializable serializable} parameterized type.
*/
public static ParameterizedType newParameterizedTypeWithOwner(
Type ownerType, Type rawType, Type... typeArguments) {
return new ParameterizedTypeImpl(ownerType, rawType, typeArguments);
}
/**
* Returns an array type whose elements are all instances of
* {@code componentType}.
*
* @return a {@link java.io.Serializable serializable} generic array type.
*/
public static GenericArrayType arrayOf(Type componentType) {
return new GenericArrayTypeImpl(componentType);
}
/**
* Returns a type that represents an unknown type that extends {@code bound}.
* For example, if {@code bound} is {@code CharSequence.class}, this returns
* {@code ? extends CharSequence}. If {@code bound} is {@code Object.class},
* this returns {@code ?}, which is shorthand for {@code ? extends Object}.
*/
public static WildcardType subtypeOf(Type bound) {
return new WildcardTypeImpl(new Type[] { bound }, EMPTY_TYPE_ARRAY);
}
/**
* Returns a type that represents an unknown supertype of {@code bound}. For
* example, if {@code bound} is {@code String.class}, this returns {@code ?
* super String}.
*/
public static WildcardType supertypeOf(Type bound) {
return new WildcardTypeImpl(new Type[] { Object.class }, new Type[] { bound });
}
/**
* Returns a type that is functionally equal but not necessarily equal
* according to {@link Object#equals(Object) Object.equals()}. The returned
* type is {@link java.io.Serializable}.
*/
@SuppressWarnings("unchecked")
public static Type canonicalize(Type type) {
if (type instanceof Class) {
Class<?> c = (Class<?>) type;
return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;
} else if (type instanceof ParameterizedType) {
ParameterizedType p = (ParameterizedType) type;
return new ParameterizedTypeImpl(p.getOwnerType(),
p.getRawType(), p.getActualTypeArguments());
} else if (type instanceof GenericArrayType) {
GenericArrayType g = (GenericArrayType) type;
return new GenericArrayTypeImpl(g.getGenericComponentType());
} else if (type instanceof WildcardType) {
WildcardType w = (WildcardType) type;
return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
} else {
// type is either serializable as-is or unsupported
return type;
}
}
@SuppressWarnings("unchecked")
public static Class<?> getRawType(Type type) {
if (type instanceof Class<?>) {
// type is a normal class.
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class.
// Neal isn't either but suspects some pathological case related
// to nested classes exists.
Type rawType = parameterizedType.getRawType();
checkArgument(rawType instanceof Class);
return (Class<?>) rawType;
} else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType)type).getGenericComponentType();
return Array.newInstance(getRawType(componentType), 0).getClass();
} else if (type instanceof TypeVariable) {
// we could use the variable's bounds, but that won't work if there are multiple.
// having a raw type that's more general than necessary is okay
return Object.class;
} else if (type instanceof WildcardType) {
return getRawType(((WildcardType) type).getUpperBounds()[0]);
} else {
String className = type == null ? "null" : type.getClass().getName();
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + className);
}
}
static boolean equal(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
/**
* Returns true if {@code a} and {@code b} are equal.
*/
@SuppressWarnings("unchecked")
public static boolean equals(Type a, Type b) {
if (a == b) {
// also handles (a == null && b == null)
return true;
} else if (a instanceof Class) {
// Class already specifies equals().
return a.equals(b);
} else if (a instanceof ParameterizedType) {
if (!(b instanceof ParameterizedType)) {
return false;
}
// TODO: save a .clone() call
ParameterizedType pa = (ParameterizedType) a;
ParameterizedType pb = (ParameterizedType) b;
return equal(pa.getOwnerType(), pb.getOwnerType())
&& pa.getRawType().equals(pb.getRawType())
&& Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments());
} else if (a instanceof GenericArrayType) {
if (!(b instanceof GenericArrayType)) {
return false;
}
GenericArrayType ga = (GenericArrayType) a;
GenericArrayType gb = (GenericArrayType) b;
return equals(ga.getGenericComponentType(), gb.getGenericComponentType());
} else if (a instanceof WildcardType) {
if (!(b instanceof WildcardType)) {
return false;
}
WildcardType wa = (WildcardType) a;
WildcardType wb = (WildcardType) b;
return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds())
&& Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds());
} else if (a instanceof TypeVariable) {
if (!(b instanceof TypeVariable)) {
return false;
}
TypeVariable<?> va = (TypeVariable<?>) a;
TypeVariable<?> vb = (TypeVariable<?>) b;
return va.getGenericDeclaration() == vb.getGenericDeclaration()
&& va.getName().equals(vb.getName());
} else {
// This isn't a type we support. Could be a generic array type, wildcard type, etc.
return false;
}
}
private static int hashCodeOrZero(Object o) {
return o != null ? o.hashCode() : 0;
}
@SuppressWarnings("unchecked")
public static String typeToString(Type type) {
return type instanceof Class ? ((Class<?>) type).getName() : type.toString();
}
/**
* Returns the generic supertype for {@code supertype}. For example, given a class {@code
* IntegerSet}, the result for when supertype is {@code Set.class} is {@code Set<Integer>} and the
* result when the supertype is {@code Collection.class} is {@code Collection<Integer>}.
*/
static Type getGenericSupertype(Type context, Class<?> rawType, Class<?> toResolve) {
if (toResolve == rawType) {
return context;
}
// we skip searching through interfaces if unknown is an interface
if (toResolve.isInterface()) {
Class<?>[] interfaces = rawType.getInterfaces();
for (int i = 0, length = interfaces.length; i < length; i++) {
if (interfaces[i] == toResolve) {
return rawType.getGenericInterfaces()[i];
} else if (toResolve.isAssignableFrom(interfaces[i])) {
return getGenericSupertype(rawType.getGenericInterfaces()[i], interfaces[i], toResolve);
}
}
}
// check our supertypes
if (!rawType.isInterface()) {
while (rawType != Object.class) {
Class<?> rawSupertype = rawType.getSuperclass();
if (rawSupertype == toResolve) {
return rawType.getGenericSuperclass();
} else if (toResolve.isAssignableFrom(rawSupertype)) {
return getGenericSupertype(rawType.getGenericSuperclass(), rawSupertype, toResolve);
}
rawType = rawSupertype;
}
}
// we can't resolve this further
return toResolve;
}
/**
* Returns the generic form of {@code supertype}. For example, if this is {@code
* ArrayList<String>}, this returns {@code Iterable<String>} given the input {@code
* Iterable.class}.
*
* @param supertype a superclass of, or interface implemented by, this.
*/
static Type getSupertype(Type context, Class<?> contextRawType, Class<?> supertype) {
checkArgument(supertype.isAssignableFrom(contextRawType));
return resolve(context, contextRawType,
$Gson$Types.getGenericSupertype(context, contextRawType, supertype));
}
/**
* Returns true if this type is an array.
*/
@SuppressWarnings("unchecked")
public static boolean isArray(Type type) {
return type instanceof GenericArrayType
|| (type instanceof Class && ((Class<?>) type).isArray());
}
/**
* Returns the component type of this array type.
* @throws ClassCastException if this type is not an array.
*/
public static Type getArrayComponentType(Type array) {
return array instanceof GenericArrayType
? ((GenericArrayType) array).getGenericComponentType()
: ((Class<?>) array).getComponentType();
}
/**
* Returns the element type of this collection type.
* @throws IllegalArgumentException if this type is not a collection.
*/
public static Type getCollectionElementType(Type context, Class<?> contextRawType) {
Type collectionType = getSupertype(context, contextRawType, Collection.class);
return ((ParameterizedType) collectionType).getActualTypeArguments()[0];
}
/**
* Returns a two element array containing this map's key and value types in
* positions 0 and 1 respectively.
*/
public static Type[] getMapKeyAndValueTypes(Type context, Class<?> contextRawType) {
/*
* Work around a problem with the declaration of java.util.Properties. That
* class should extend Hashtable<String, String>, but it's declared to
* extend Hashtable<Object, Object>.
*/
if (context == Properties.class) {
return new Type[] { String.class, String.class }; // TODO: test subclasses of Properties!
}
Type mapType = getSupertype(context, contextRawType, Map.class);
ParameterizedType mapParameterizedType = (ParameterizedType) mapType;
return mapParameterizedType.getActualTypeArguments();
}
@SuppressWarnings("unchecked")
public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
// this implementation is made a little more complicated in an attempt to avoid object-creation
while (true) {
if (toResolve instanceof TypeVariable) {
TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
if (toResolve == typeVariable) {
return toResolve;
}
} else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
Class<?> original = (Class<?>) toResolve;
Type componentType = original.getComponentType();
Type newComponentType = resolve(context, contextRawType, componentType);
return componentType == newComponentType
? original
: arrayOf(newComponentType);
} else if (toResolve instanceof GenericArrayType) {
GenericArrayType original = (GenericArrayType) toResolve;
Type componentType = original.getGenericComponentType();
Type newComponentType = resolve(context, contextRawType, componentType);
return componentType == newComponentType
? original
: arrayOf(newComponentType);
} else if (toResolve instanceof ParameterizedType) {
ParameterizedType original = (ParameterizedType) toResolve;
Type ownerType = original.getOwnerType();
Type newOwnerType = resolve(context, contextRawType, ownerType);
boolean changed = newOwnerType != ownerType;
Type[] args = original.getActualTypeArguments();
for (int t = 0, length = args.length; t < length; t++) {
Type resolvedTypeArgument = resolve(context, contextRawType, args[t]);
if (resolvedTypeArgument != args[t]) {
if (!changed) {
args = args.clone();
changed = true;
}
args[t] = resolvedTypeArgument;
}
}
return changed
? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
: original;
} else if (toResolve instanceof WildcardType) {
WildcardType original = (WildcardType) toResolve;
Type[] originalLowerBound = original.getLowerBounds();
Type[] originalUpperBound = original.getUpperBounds();
if (originalLowerBound.length == 1) {
Type lowerBound = resolve(context, contextRawType, originalLowerBound[0]);
if (lowerBound != originalLowerBound[0]) {
return supertypeOf(lowerBound);
}
} else if (originalUpperBound.length == 1) {
Type upperBound = resolve(context, contextRawType, originalUpperBound[0]);
if (upperBound != originalUpperBound[0]) {
return subtypeOf(upperBound);
}
}
return original;
} else {
return toResolve;
}
}
}
@SuppressWarnings("unchecked")
static Type resolveTypeVariable(Type context, Class<?> contextRawType, TypeVariable unknown) {
Class<?> declaredByRaw = declaringClassOf(unknown);
// we can't reduce this further
if (declaredByRaw == null) {
return unknown;
}
Type declaredBy = getGenericSupertype(context, contextRawType, declaredByRaw);
if (declaredBy instanceof ParameterizedType) {
int index = indexOf(declaredByRaw.getTypeParameters(), unknown);
return ((ParameterizedType) declaredBy).getActualTypeArguments()[index];
}
return unknown;
}
private static int indexOf(Object[] array, Object toFind) {
for (int i = 0; i < array.length; i++) {
if (toFind.equals(array[i])) {
return i;
}
}
throw new NoSuchElementException();
}
/**
* Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by
* a class.
*/
@SuppressWarnings("unchecked")
private static Class<?> declaringClassOf(TypeVariable typeVariable) {
GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
return genericDeclaration instanceof Class
? (Class<?>) genericDeclaration
: null;
}
private static void checkNotPrimitive(Type type) {
checkArgument(!(type instanceof Class<?>) || !((Class<?>) type).isPrimitive());
}
private static final class ParameterizedTypeImpl implements ParameterizedType, Serializable {
private final Type ownerType;
private final Type rawType;
private final Type[] typeArguments;
@SuppressWarnings("unchecked")
public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) {
// require an owner type if the raw type needs it
if (rawType instanceof Class<?>) {
Class rawTypeAsClass = (Class) rawType;
checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null);
checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null);
}
this.ownerType = ownerType == null ? null : canonicalize(ownerType);
this.rawType = canonicalize(rawType);
this.typeArguments = typeArguments.clone();
for (int t = 0; t < this.typeArguments.length; t++) {
checkNotNull(this.typeArguments[t]);
checkNotPrimitive(this.typeArguments[t]);
this.typeArguments[t] = canonicalize(this.typeArguments[t]);
}
}
public Type[] getActualTypeArguments() {
return typeArguments.clone();
}
public Type getRawType() {
return rawType;
}
public Type getOwnerType() {
return ownerType;
}
@Override public boolean equals(Object other) {
return other instanceof ParameterizedType
&& $Gson$Types.equals(this, (ParameterizedType) other);
}
@Override public int hashCode() {
return Arrays.hashCode(typeArguments)
^ rawType.hashCode()
^ hashCodeOrZero(ownerType);
}
@Override public String toString() {
StringBuilder stringBuilder = new StringBuilder(30 * (typeArguments.length + 1));
stringBuilder.append(typeToString(rawType));
if (typeArguments.length == 0) {
return stringBuilder.toString();
}
stringBuilder.append("<").append(typeToString(typeArguments[0]));
for (int i = 1; i < typeArguments.length; i++) {
stringBuilder.append(", ").append(typeToString(typeArguments[i]));
}
return stringBuilder.append(">").toString();
}
private static final long serialVersionUID = 0;
}
private static final class GenericArrayTypeImpl implements GenericArrayType, Serializable {
private final Type componentType;
public GenericArrayTypeImpl(Type componentType) {
this.componentType = canonicalize(componentType);
}
public Type getGenericComponentType() {
return componentType;
}
@Override public boolean equals(Object o) {
return o instanceof GenericArrayType
&& $Gson$Types.equals(this, (GenericArrayType) o);
}
@Override public int hashCode() {
return componentType.hashCode();
}
@Override public String toString() {
return typeToString(componentType) + "[]";
}
private static final long serialVersionUID = 0;
}
/**
* The WildcardType interface supports multiple upper bounds and multiple
* lower bounds. We only support what the Java 6 language needs - at most one
* bound. If a lower bound is set, the upper bound must be Object.class.
*/
private static final class WildcardTypeImpl implements WildcardType, Serializable {
private final Type upperBound;
private final Type lowerBound;
public WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) {
checkArgument(lowerBounds.length <= 1);
checkArgument(upperBounds.length == 1);
if (lowerBounds.length == 1) {
checkNotNull(lowerBounds[0]);
checkNotPrimitive(lowerBounds[0]);
checkArgument(upperBounds[0] == Object.class);
this.lowerBound = canonicalize(lowerBounds[0]);
this.upperBound = Object.class;
} else {
checkNotNull(upperBounds[0]);
checkNotPrimitive(upperBounds[0]);
this.lowerBound = null;
this.upperBound = canonicalize(upperBounds[0]);
}
}
public Type[] getUpperBounds() {
return new Type[] { upperBound };
}
public Type[] getLowerBounds() {
return lowerBound != null ? new Type[] { lowerBound } : EMPTY_TYPE_ARRAY;
}
@Override public boolean equals(Object other) {
return other instanceof WildcardType
&& $Gson$Types.equals(this, (WildcardType) other);
}
@Override public int hashCode() {
// this equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds());
return (lowerBound != null ? 31 + lowerBound.hashCode() : 1)
^ (31 + upperBound.hashCode());
}
@Override public String toString() {
if (lowerBound != null) {
return "? super " + typeToString(lowerBound);
} else if (upperBound == Object.class) {
return "?";
} else {
return "? extends " + typeToString(upperBound);
}
}
private static final long serialVersionUID = 0;
}
}

View File

@ -0,0 +1,7 @@
/**
* Do NOT use any class in this package as they are meant for internal use in Gson.
* These classes will very likely change incompatibly in future versions. You have been warned.
*
* @author Inderjeet Singh, Joel Leitch, Jesse Wilson
*/
package org.mcteam.factions.gson.internal;

View File

@ -1,9 +1,9 @@
/**
* This package provides the {@link com.bukkit.mcteam.gson.Gson} class to convert Json to Java and
* This package provides the {@link org.mcteam.factions.gson.Gson} class to convert Json to Java and
* vice-versa.
*
* <p>The primary class to use is {@link com.bukkit.mcteam.gson.Gson} which can be constructed with
* {@code new Gson()} (using default settings) or by using {@link com.bukkit.mcteam.gson.GsonBuilder}
* <p>The primary class to use is {@link org.mcteam.factions.gson.Gson} which can be constructed with
* {@code new Gson()} (using default settings) or by using {@link org.mcteam.factions.gson.GsonBuilder}
* (to configure various options such as using versioning and so on).</p>
*
* @author Inderjeet Singh, Joel Leitch

View File

@ -16,7 +16,8 @@
package org.mcteam.factions.gson.reflect;
import java.lang.reflect.Array;
import org.mcteam.factions.gson.internal.$Gson$Types;
import org.mcteam.factions.gson.internal.$Gson$Preconditions;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@ -25,135 +26,101 @@ import java.util.HashMap;
import java.util.Map;
/**
* Represents a generic type {@code T}.
* Represents a generic type {@code T}. Java doesn't yet provide a way to
* represent generic types, so this class does. Forces clients to create a
* subclass of this class which enables retrieval the type information even at
* runtime.
*
* <p>For example, to create a type literal for {@code List<String>}, you can
* create an empty anonymous inner class:
*
* You can use this class to get the generic type for a class. For example,
* to get the generic type for <code>Collection&lt;Foo&gt;</code>, you can use:
* <p>
* <code>Type typeOfCollectionOfFoo = new TypeToken&lt;Collection&lt;Foo&gt;&gt;(){}.getType()
* </code>
* {@code TypeToken<List<String>> list = new TypeToken<List<String>>() {};}
*
* <p>Assumes {@code Type} implements {@code equals()} and {@code hashCode()}
* as a value (as opposed to identity) comparison.
*
* Also implements {@link #isAssignableFrom(Type)} to check type-safe
* assignability.
* <p>This syntax cannot be used to create type literals that have wildcard
* parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
*
* @author Bob Lee
* @author Sven Mawson
* @author Jesse Wilson
*/
public abstract class TypeToken<T> {
public class TypeToken<T> {
final Class<? super T> rawType;
final Type type;
final int hashCode;
/**
* Constructs a new type token. Derives represented class from type
* Constructs a new type literal. Derives represented class from type
* parameter.
*
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
* parameter in the anonymous class's type hierarchy so we can reconstitute
* it at runtime despite erasure.
*
* <p>For example:
* <code>
* {@literal TypeToken<List<String>> t = new TypeToken<List<String>>}(){}
* </code>
* parameter in the anonymous class's type hierarchy so we can reconstitute it
* at runtime despite erasure.
*/
@SuppressWarnings("unchecked")
protected TypeToken() {
this.type = getSuperclassTypeParameter(getClass());
this.rawType = (Class<? super T>) getRawType(type);
this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
this.hashCode = type.hashCode();
}
/**
* Unsafe. Constructs a type token manually.
* Unsafe. Constructs a type literal manually.
*/
@SuppressWarnings({"unchecked"})
private TypeToken(Type type) {
this.rawType = (Class<? super T>) getRawType(nonNull(type, "type"));
this.type = type;
}
private static <T> T nonNull(T o, String message) {
if (o == null) {
throw new NullPointerException(message);
}
return o;
@SuppressWarnings("unchecked")
TypeToken(Type type) {
this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
this.hashCode = this.type.hashCode();
}
/**
* Gets type from super class's type parameter.
* Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
* canonical form}.
*/
@SuppressWarnings("unchecked")
static Type getSuperclassTypeParameter(Class<?> subclass) {
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class<?>) {
if (superclass instanceof Class) {
throw new RuntimeException("Missing type parameter.");
}
return ((ParameterizedType) superclass).getActualTypeArguments()[0];
ParameterizedType parameterized = (ParameterizedType) superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
/**
* Gets type token from super class's type parameter.
* Returns the raw (non-generic) type for this type.
*/
static TypeToken<?> fromSuperclassTypeParameter(Class<?> subclass) {
return new SimpleTypeToken<Object>(subclass);
}
private static Class<?> getRawType(Type type) {
if (type instanceof Class<?>) {
// type is a normal class.
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class.
// Neal isn't either but suspects some pathological case related
// to nested classes exists.
Type rawType = parameterizedType.getRawType();
if (rawType instanceof Class<?>) {
return (Class<?>) rawType;
}
throw buildUnexpectedTypeError(rawType, Class.class);
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType) type;
// TODO(jleitch): This is not the most efficient way to handle generic
// arrays, but is there another way to extract the array class in a
// non-hacky way (i.e. using String value class names- "[L...")?
Object rawArrayType = Array.newInstance(
getRawType(genericArrayType.getGenericComponentType()), 0);
return rawArrayType.getClass();
} else {
throw buildUnexpectedTypeError(
type, ParameterizedType.class, GenericArrayType.class);
}
}
/**
* Gets the raw type.
*/
public Class<? super T> getRawType() {
public final Class<? super T> getRawType() {
return rawType;
}
/**
* Gets underlying {@code Type} instance.
*/
public Type getType() {
public final Type getType() {
return type;
}
/**
* Check if this type is assignable from the given class object.
*
* @deprecated this implementation may be inconsistent with javac for types
* with wildcards.
*/
@Deprecated
public boolean isAssignableFrom(Class<?> cls) {
return isAssignableFrom((Type) cls);
}
/**
* Check if this type is assignable from the given Type.
*
* @deprecated this implementation may be inconsistent with javac for types
* with wildcards.
*/
@Deprecated
public boolean isAssignableFrom(Type from) {
if (from == null) {
return false;
@ -164,12 +131,12 @@ public abstract class TypeToken<T> {
}
if (type instanceof Class<?>) {
return rawType.isAssignableFrom(getRawType(from));
return rawType.isAssignableFrom($Gson$Types.getRawType(from));
} else if (type instanceof ParameterizedType) {
return isAssignableFrom(from, (ParameterizedType) type,
new HashMap<String, Type>());
} else if (type instanceof GenericArrayType) {
return rawType.isAssignableFrom(getRawType(from))
return rawType.isAssignableFrom($Gson$Types.getRawType(from))
&& isAssignableFrom(from, (GenericArrayType) type);
} else {
throw buildUnexpectedTypeError(
@ -179,7 +146,11 @@ public abstract class TypeToken<T> {
/**
* Check if this type is assignable from the given type token.
*
* @deprecated this implementation may be inconsistent with javac for types
* with wildcards.
*/
@Deprecated
public boolean isAssignableFrom(TypeToken<?> token) {
return isAssignableFrom(token.getType());
}
@ -225,7 +196,7 @@ public abstract class TypeToken<T> {
}
// First figure out the class and any type information.
Class<?> clazz = getRawType(from);
Class<?> clazz = $Gson$Types.getRawType(from);
ParameterizedType ptype = null;
if (from instanceof ParameterizedType) {
ptype = (ParameterizedType) from;
@ -259,11 +230,7 @@ public abstract class TypeToken<T> {
// Interfaces didn't work, try the superclass.
Type sType = clazz.getGenericSuperclass();
if (isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap))) {
return true;
}
return false;
return isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap));
}
/**
@ -285,55 +252,6 @@ public abstract class TypeToken<T> {
return false;
}
/**
* Checks if two types are the same or are equivalent under a variable mapping
* given in the type map that was provided.
*/
private static boolean matches(Type from, Type to,
Map<String, Type> typeMap) {
if (to.equals(from)) return true;
if (from instanceof TypeVariable<?>) {
return to.equals(typeMap.get(((TypeVariable<?>)from).getName()));
}
return false;
}
/**
* Hashcode for this object.
* @return hashcode for this object.
*/
@Override public int hashCode() {
return type.hashCode();
}
/**
* Method to test equality.
*
* @return true if this object is logically equal to the specified object, false otherwise.
*/
@Override public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof TypeToken<?>)) {
return false;
}
TypeToken<?> t = (TypeToken<?>) o;
return type.equals(t.type);
}
/**
* Returns a string representation of this object.
* @return a string representation of this object.
*/
@Override public String toString() {
return type instanceof Class<?>
? ((Class<?>) type).getName()
: type.toString();
}
private static AssertionError buildUnexpectedTypeError(
Type token, Class<?>... expected) {
@ -350,26 +268,41 @@ public abstract class TypeToken<T> {
}
/**
* Gets type token for the given {@code Type} instance.
* Checks if two types are the same or are equivalent under a variable mapping
* given in the type map that was provided.
*/
@SuppressWarnings("unchecked")
private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
return to.equals(from)
|| (from instanceof TypeVariable
&& to.equals(typeMap.get(((TypeVariable<?>) from).getName())));
}
@Override public final int hashCode() {
return this.hashCode;
}
@Override public final boolean equals(Object o) {
return o instanceof TypeToken<?>
&& $Gson$Types.equals(type, ((TypeToken<?>) o).type);
}
@Override public final String toString() {
return $Gson$Types.typeToString(type);
}
/**
* Gets type literal for the given {@code Type} instance.
*/
public static TypeToken<?> get(Type type) {
return new SimpleTypeToken<Object>(type);
return new TypeToken<Object>(type);
}
/**
* Gets type token for the given {@code Class} instance.
* Gets type literal for the given {@code Class} instance.
*/
public static <T> TypeToken<T> get(Class<T> type) {
return new SimpleTypeToken<T>(type);
}
/**
* Private static class to not create more anonymous classes than
* necessary.
*/
private static class SimpleTypeToken<T> extends TypeToken<T> {
public SimpleTypeToken(Type type) {
super(type);
}
return new TypeToken<T>(type);
}
}

View File

@ -1097,7 +1097,8 @@ public final class JsonReader implements Closeable {
token = JsonToken.NUMBER;
} catch (NumberFormatException ignored) {
// this must be an unquoted string
throw syntaxError("invalid number or unquoted string");
checkLenient();
token = JsonToken.STRING;
}
}
}