streamline rebased Gson into source; rebase was done to prevent conflict with other plugins (like upcoming WorldGuard release) which also use Gson; Bukkit doesn't yet handle such conflicts properly
This commit is contained in:
		@@ -10,7 +10,7 @@ import org.bukkit.entity.Player;
 | 
			
		||||
import com.bukkit.mcteam.factions.Factions;
 | 
			
		||||
import com.bukkit.mcteam.factions.util.*;
 | 
			
		||||
import com.bukkit.mcteam.util.DiscUtil;
 | 
			
		||||
import com.google.gson.*;
 | 
			
		||||
import com.bukkit.mcteam.gson.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is a entity manager that persists object to json.
 | 
			
		||||
@@ -125,6 +125,7 @@ public class EM {
 | 
			
		||||
		folderBoard.mkdirs();
 | 
			
		||||
				
 | 
			
		||||
		class jsonFileFilter implements FileFilter {
 | 
			
		||||
			@Override
 | 
			
		||||
			public boolean accept(File file) {
 | 
			
		||||
				return (file.getName().toLowerCase().endsWith(ext) && file.isFile());
 | 
			
		||||
			}
 | 
			
		||||
@@ -204,6 +205,7 @@ public class EM {
 | 
			
		||||
		folderFollower.mkdirs();
 | 
			
		||||
				
 | 
			
		||||
		class jsonFileFilter implements FileFilter {
 | 
			
		||||
			@Override
 | 
			
		||||
			public boolean accept(File file) {
 | 
			
		||||
				return (file.getName().toLowerCase().endsWith(ext) && file.isFile());
 | 
			
		||||
			}
 | 
			
		||||
@@ -292,6 +294,7 @@ public class EM {
 | 
			
		||||
				
 | 
			
		||||
		class jsonFileFilter implements FileFilter
 | 
			
		||||
		{
 | 
			
		||||
			@Override
 | 
			
		||||
			public boolean accept(File file) {
 | 
			
		||||
				return (file.getName().toLowerCase().endsWith(ext) && file.isFile());
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Strategy for excluding anonymous and local classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class AnonymousAndLocalClassExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    return isAnonymousOrLocal(f.getDeclaredClass());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return isAnonymousOrLocal(clazz);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isAnonymousOrLocal(Class<?> clazz) {
 | 
			
		||||
    return !Enum.class.isAssignableFrom(clazz)
 | 
			
		||||
        && (clazz.isAnonymousClass() || clazz.isLocalClass());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/com/bukkit/mcteam/gson/Cache.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/com/bukkit/mcteam/gson/Cache.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines generic cache interface.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
interface Cache<K, V> {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adds the new value object into the cache for the given key.  If the key already
 | 
			
		||||
   * exists, then this method will override the value for the key.
 | 
			
		||||
   *
 | 
			
		||||
   * @param key the key identifier for the {@code value} object
 | 
			
		||||
   * @param value the value object to store in the cache
 | 
			
		||||
   */
 | 
			
		||||
  void addElement(K key, V value);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the cached value for the given {@code key}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param key the key identifying the value
 | 
			
		||||
   * @return the cached value for the given {@code key}
 | 
			
		||||
   */
 | 
			
		||||
  V getElement(K key);
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Removes the value from the cache for the given key.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param key the key identifying the value to remove
 | 
			
		||||
   * @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();
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts the field name that uses camel-case define word separation into separate words that
 | 
			
		||||
 * are separated by the provided {@code separatorString}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IntWrapper {
 | 
			
		||||
 *   public int integerField = 0;
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * CamelCaseSeparatorNamingPolicy policy = new CamelCaseSeparatorNamingPolicy("_");
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(IntWrapper.class.getField("integerField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("integer_Field".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class CamelCaseSeparatorNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
  private final String separatorString;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a new CamelCaseSeparatorNamingPolicy object that will add the
 | 
			
		||||
   * {@code separatorString} between each of the words separated by camel case.
 | 
			
		||||
   *
 | 
			
		||||
   * @param separatorString the string value to place between words
 | 
			
		||||
   * @throws IllegalArgumentException thrown if the {@code separatorString} parameter
 | 
			
		||||
   *         is null or empty.
 | 
			
		||||
   */
 | 
			
		||||
  public CamelCaseSeparatorNamingPolicy(String separatorString) {
 | 
			
		||||
    Preconditions.checkNotNull(separatorString);
 | 
			
		||||
    Preconditions.checkArgument(!"".equals(separatorString));
 | 
			
		||||
    this.separatorString = separatorString;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType,
 | 
			
		||||
      Collection<Annotation> annnotations) {
 | 
			
		||||
    StringBuilder translation = new StringBuilder();
 | 
			
		||||
    for (int i = 0; i < target.length(); i++) {
 | 
			
		||||
      char character = target.charAt(i);
 | 
			
		||||
      if (Character.isUpperCase(character) && translation.length() != 0) {
 | 
			
		||||
        translation.append(separatorString);
 | 
			
		||||
      }
 | 
			
		||||
      translation.append(character);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return translation.toString();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/com/bukkit/mcteam/gson/CircularReferenceException.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/com/bukkit/mcteam/gson/CircularReferenceException.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exception class to indicate a circular reference error.
 | 
			
		||||
 * This class is not part of the public API and hence is not public.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class CircularReferenceException extends RuntimeException {
 | 
			
		||||
  private static final long serialVersionUID = 7444343294106513081L;
 | 
			
		||||
  private final Object offendingNode;
 | 
			
		||||
 | 
			
		||||
  CircularReferenceException(Object offendingNode) {
 | 
			
		||||
    super("circular reference error");
 | 
			
		||||
    this.offendingNode = offendingNode;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public IllegalStateException createDetailedException(FieldAttributes offendingField) {
 | 
			
		||||
    StringBuilder msg = new StringBuilder(getMessage());
 | 
			
		||||
    if (offendingField != null) {
 | 
			
		||||
      msg.append("\n  ").append("Offending field: ").append(offendingField.getName() + "\n");
 | 
			
		||||
    }
 | 
			
		||||
    if (offendingNode != null) {
 | 
			
		||||
      msg.append("\n  ").append("Offending object: ").append(offendingNode);
 | 
			
		||||
    }
 | 
			
		||||
    return new IllegalStateException(msg.toString(), this);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/com/bukkit/mcteam/gson/CompositionFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/com/bukkit/mcteam/gson/CompositionFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Performs numerous field naming translations wrapped up as one object.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
abstract class CompositionFieldNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  private final RecursiveFieldNamingPolicy[] fieldPolicies;
 | 
			
		||||
 | 
			
		||||
  public CompositionFieldNamingPolicy(RecursiveFieldNamingPolicy... fieldNamingPolicies) {
 | 
			
		||||
    if (fieldNamingPolicies == null) {
 | 
			
		||||
      throw new NullPointerException("naming policies can not be null.");
 | 
			
		||||
    }
 | 
			
		||||
    this.fieldPolicies = fieldNamingPolicies;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
 | 
			
		||||
    for (RecursiveFieldNamingPolicy policy : fieldPolicies) {
 | 
			
		||||
      target = policy.translateName(target, fieldType, annotations);
 | 
			
		||||
    }
 | 
			
		||||
    return target;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										893
									
								
								src/com/bukkit/mcteam/gson/DefaultTypeAdapters.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										893
									
								
								src/com/bukkit/mcteam/gson/DefaultTypeAdapters.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,893 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.ParameterizedType;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.net.MalformedURLException;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.URISyntaxException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.sql.Time;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.GregorianCalendar;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.SortedSet;
 | 
			
		||||
import java.util.StringTokenizer;
 | 
			
		||||
import java.util.TreeSet;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * List of all the default type adapters ({@link JsonSerializer}s, {@link JsonDeserializer}s,
 | 
			
		||||
 * and {@link InstanceCreator}s.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class DefaultTypeAdapters {
 | 
			
		||||
 | 
			
		||||
  private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER = new DefaultDateTypeAdapter();
 | 
			
		||||
  private static final DefaultJavaSqlDateTypeAdapter JAVA_SQL_DATE_TYPE_ADAPTER =
 | 
			
		||||
    new DefaultJavaSqlDateTypeAdapter();
 | 
			
		||||
  private static final DefaultTimeTypeAdapter TIME_TYPE_ADAPTER =
 | 
			
		||||
    new DefaultTimeTypeAdapter();
 | 
			
		||||
  private static final DefaultTimestampDeserializer TIMESTAMP_DESERIALIZER =
 | 
			
		||||
    new DefaultTimestampDeserializer();
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("rawtypes")
 | 
			
		||||
  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 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();
 | 
			
		||||
  private static final BigIntegerTypeAdapter BIG_INTEGER_TYPE_ADAPTER = new BigIntegerTypeAdapter();
 | 
			
		||||
 | 
			
		||||
  private static final BooleanTypeAdapter BOOLEAN_TYPE_ADAPTER = new BooleanTypeAdapter();
 | 
			
		||||
  private static final ByteTypeAdapter BYTE_TYPE_ADAPTER = new ByteTypeAdapter();
 | 
			
		||||
  private static final CharacterTypeAdapter CHARACTER_TYPE_ADAPTER = new CharacterTypeAdapter();
 | 
			
		||||
  private static final DoubleDeserializer DOUBLE_TYPE_ADAPTER = new DoubleDeserializer();
 | 
			
		||||
  private static final FloatDeserializer FLOAT_TYPE_ADAPTER = new FloatDeserializer();
 | 
			
		||||
  private static final IntegerTypeAdapter INTEGER_TYPE_ADAPTER = new IntegerTypeAdapter();
 | 
			
		||||
  private static final LongDeserializer LONG_DESERIALIZER = new LongDeserializer();
 | 
			
		||||
  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 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();
 | 
			
		||||
 | 
			
		||||
  // The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS
 | 
			
		||||
  // must be defined after the constants for the type adapters. Otherwise, the type adapter
 | 
			
		||||
  // constants will appear as nulls.
 | 
			
		||||
  private static final ParameterizedTypeHandlerMap<JsonSerializer<?>> DEFAULT_SERIALIZERS =
 | 
			
		||||
      createDefaultSerializers();
 | 
			
		||||
  private static final ParameterizedTypeHandlerMap<JsonDeserializer<?>> DEFAULT_DESERIALIZERS =
 | 
			
		||||
      createDefaultDeserializers();
 | 
			
		||||
  private static final ParameterizedTypeHandlerMap<InstanceCreator<?>> DEFAULT_INSTANCE_CREATORS =
 | 
			
		||||
      createDefaultInstanceCreators();
 | 
			
		||||
 | 
			
		||||
  private static ParameterizedTypeHandlerMap<JsonSerializer<?>> createDefaultSerializers() {
 | 
			
		||||
    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);
 | 
			
		||||
    map.register(Time.class, TIME_TYPE_ADAPTER);
 | 
			
		||||
    map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
 | 
			
		||||
    map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
 | 
			
		||||
    map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
 | 
			
		||||
    map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
 | 
			
		||||
 | 
			
		||||
    // Add primitive serializers
 | 
			
		||||
    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, CHARACTER_TYPE_ADAPTER);
 | 
			
		||||
    map.register(char.class, CHARACTER_TYPE_ADAPTER);
 | 
			
		||||
    map.register(Integer.class, INTEGER_TYPE_ADAPTER);
 | 
			
		||||
    map.register(int.class, INTEGER_TYPE_ADAPTER);
 | 
			
		||||
    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, STRING_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));
 | 
			
		||||
 | 
			
		||||
    // 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(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(String.class, wrapDeserializer(STRING_TYPE_ADAPTER));
 | 
			
		||||
 | 
			
		||||
    map.makeUnmodifiable();
 | 
			
		||||
    return map;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static ParameterizedTypeHandlerMap<InstanceCreator<?>> createDefaultInstanceCreators() {
 | 
			
		||||
    ParameterizedTypeHandlerMap<InstanceCreator<?>> map =
 | 
			
		||||
        new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
 | 
			
		||||
    map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
 | 
			
		||||
 | 
			
		||||
    // Add Collection type instance creators
 | 
			
		||||
    map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
 | 
			
		||||
 | 
			
		||||
    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"})
 | 
			
		||||
  private static JsonDeserializer<?> wrapDeserializer(JsonDeserializer<?> deserializer) {
 | 
			
		||||
    return new JsonDeserializerExceptionWrapper(deserializer);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers() {
 | 
			
		||||
    return getDefaultSerializers(false, LongSerializationPolicy.DEFAULT);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers(
 | 
			
		||||
      boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy) {
 | 
			
		||||
    ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers =
 | 
			
		||||
        new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
 | 
			
		||||
 | 
			
		||||
    // Double primitive
 | 
			
		||||
    DefaultTypeAdapters.DoubleSerializer doubleSerializer =
 | 
			
		||||
        new DefaultTypeAdapters.DoubleSerializer(serializeSpecialFloatingPointValues);
 | 
			
		||||
    serializers.registerIfAbsent(Double.class, doubleSerializer);
 | 
			
		||||
    serializers.registerIfAbsent(double.class, doubleSerializer);
 | 
			
		||||
 | 
			
		||||
    // Float primitive
 | 
			
		||||
    DefaultTypeAdapters.FloatSerializer floatSerializer =
 | 
			
		||||
        new DefaultTypeAdapters.FloatSerializer(serializeSpecialFloatingPointValues);
 | 
			
		||||
    serializers.registerIfAbsent(Float.class, floatSerializer);
 | 
			
		||||
    serializers.registerIfAbsent(float.class, floatSerializer);
 | 
			
		||||
 | 
			
		||||
    // Long primitive
 | 
			
		||||
    DefaultTypeAdapters.LongSerializer longSerializer =
 | 
			
		||||
        new DefaultTypeAdapters.LongSerializer(longSerializationPolicy);
 | 
			
		||||
    serializers.registerIfAbsent(Long.class, longSerializer);
 | 
			
		||||
    serializers.registerIfAbsent(long.class, longSerializer);
 | 
			
		||||
 | 
			
		||||
    serializers.registerIfAbsent(DEFAULT_SERIALIZERS);
 | 
			
		||||
    return serializers;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static ParameterizedTypeHandlerMap<JsonDeserializer<?>> getDefaultDeserializers() {
 | 
			
		||||
    return DEFAULT_DESERIALIZERS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static ParameterizedTypeHandlerMap<InstanceCreator<?>> getDefaultInstanceCreators() {
 | 
			
		||||
    return DEFAULT_INSTANCE_CREATORS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
 | 
			
		||||
    private final DateFormat format;
 | 
			
		||||
 | 
			
		||||
    DefaultDateTypeAdapter() {
 | 
			
		||||
      this.format = DateFormat.getDateTimeInstance();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DefaultDateTypeAdapter(final String datePattern) {
 | 
			
		||||
      this.format = new SimpleDateFormat(datePattern);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DefaultDateTypeAdapter(final int style) {
 | 
			
		||||
      this.format = DateFormat.getDateInstance(style);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public DefaultDateTypeAdapter(final int dateStyle, final int timeStyle) {
 | 
			
		||||
      this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
        return new JsonPrimitive(dateFormatAsString);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      if (!(json instanceof JsonPrimitive)) {
 | 
			
		||||
        throw new JsonParseException("The date should be a string value");
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        synchronized (format) {
 | 
			
		||||
          return format.parse(json.getAsString());
 | 
			
		||||
        }
 | 
			
		||||
      } catch (ParseException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      StringBuilder sb = new StringBuilder();
 | 
			
		||||
      sb.append(DefaultDateTypeAdapter.class.getSimpleName());
 | 
			
		||||
      sb.append('(').append(format.getClass().getSimpleName()).append(')');
 | 
			
		||||
      return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DefaultJavaSqlDateTypeAdapter implements JsonSerializer<java.sql.Date>,
 | 
			
		||||
      JsonDeserializer<java.sql.Date> {
 | 
			
		||||
    private final DateFormat format;
 | 
			
		||||
    DefaultJavaSqlDateTypeAdapter() {
 | 
			
		||||
      this.format = new SimpleDateFormat("MMM d, yyyy");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(java.sql.Date src, Type typeOfSrc,
 | 
			
		||||
        JsonSerializationContext context) {
 | 
			
		||||
      synchronized (format) {
 | 
			
		||||
        String dateFormatAsString = format.format(src);
 | 
			
		||||
        return new JsonPrimitive(dateFormatAsString);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public java.sql.Date deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      if (!(json instanceof JsonPrimitive)) {
 | 
			
		||||
        throw new JsonParseException("The date should be a string value");
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        synchronized (format) {
 | 
			
		||||
          Date date = format.parse(json.getAsString());
 | 
			
		||||
          return new java.sql.Date(date.getTime());
 | 
			
		||||
        }
 | 
			
		||||
      } catch (ParseException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DefaultTimestampDeserializer implements JsonDeserializer<Timestamp> {
 | 
			
		||||
    public Timestamp deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      Date date = context.deserialize(json, Date.class);
 | 
			
		||||
      return new Timestamp(date.getTime());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DefaultTimeTypeAdapter implements JsonSerializer<Time>, JsonDeserializer<Time> {
 | 
			
		||||
    private final DateFormat format;
 | 
			
		||||
    DefaultTimeTypeAdapter() {
 | 
			
		||||
      this.format = new SimpleDateFormat("hh:mm:ss a");
 | 
			
		||||
    }
 | 
			
		||||
    public JsonElement serialize(Time src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      synchronized (format) {
 | 
			
		||||
        String dateFormatAsString = format.format(src);
 | 
			
		||||
        return new JsonPrimitive(dateFormatAsString);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    public Time deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      if (!(json instanceof JsonPrimitive)) {
 | 
			
		||||
        throw new JsonParseException("The date should be a string value");
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        synchronized (format) {
 | 
			
		||||
          Date date = format.parse(json.getAsString());
 | 
			
		||||
          return new Time(date.getTime());
 | 
			
		||||
        }
 | 
			
		||||
      } catch (ParseException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class GregorianCalendarTypeAdapter
 | 
			
		||||
      implements JsonSerializer<GregorianCalendar>, JsonDeserializer<GregorianCalendar> {
 | 
			
		||||
 | 
			
		||||
    private static final String YEAR = "year";
 | 
			
		||||
    private static final String MONTH = "month";
 | 
			
		||||
    private static final String DAY_OF_MONTH = "dayOfMonth";
 | 
			
		||||
    private static final String HOUR_OF_DAY = "hourOfDay";
 | 
			
		||||
    private static final String MINUTE = "minute";
 | 
			
		||||
    private static final String SECOND = "second";
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(GregorianCalendar src, Type typeOfSrc,
 | 
			
		||||
        JsonSerializationContext context) {
 | 
			
		||||
      JsonObject obj = new JsonObject();
 | 
			
		||||
      obj.addProperty(YEAR, src.get(Calendar.YEAR));
 | 
			
		||||
      obj.addProperty(MONTH, src.get(Calendar.MONTH));
 | 
			
		||||
      obj.addProperty(DAY_OF_MONTH, src.get(Calendar.DAY_OF_MONTH));
 | 
			
		||||
      obj.addProperty(HOUR_OF_DAY, src.get(Calendar.HOUR_OF_DAY));
 | 
			
		||||
      obj.addProperty(MINUTE, src.get(Calendar.MINUTE));
 | 
			
		||||
      obj.addProperty(SECOND, src.get(Calendar.SECOND));
 | 
			
		||||
      return obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public GregorianCalendar deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      JsonObject obj = json.getAsJsonObject();
 | 
			
		||||
      int year = obj.get(YEAR).getAsInt();
 | 
			
		||||
      int month = obj.get(MONTH).getAsInt();
 | 
			
		||||
      int dayOfMonth = obj.get(DAY_OF_MONTH).getAsInt();
 | 
			
		||||
      int hourOfDay = obj.get(HOUR_OF_DAY).getAsInt();
 | 
			
		||||
      int minute = obj.get(MINUTE).getAsInt();
 | 
			
		||||
      int second = obj.get(SECOND).getAsInt();
 | 
			
		||||
      return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return GregorianCalendarTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  private static 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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("cast")
 | 
			
		||||
    public T deserialize(JsonElement json, Type classOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return (T) Enum.valueOf((Class<T>) classOfT, json.getAsString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return EnumTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> {
 | 
			
		||||
    public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src.toExternalForm());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public URL deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      try {
 | 
			
		||||
        return new URL(json.getAsString());
 | 
			
		||||
      } catch (MalformedURLException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return UrlTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class UriTypeAdapter implements JsonSerializer<URI>, JsonDeserializer<URI> {
 | 
			
		||||
    public JsonElement serialize(URI src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src.toASCIIString());
 | 
			
		||||
    }
 | 
			
		||||
    public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
    throws JsonParseException {
 | 
			
		||||
      try {
 | 
			
		||||
        return new URI(json.getAsString());
 | 
			
		||||
      } catch (URISyntaxException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return UriTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class UuidTypeAdapter implements JsonSerializer<UUID>, JsonDeserializer<UUID> {
 | 
			
		||||
    public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public UUID deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return UUID.fromString(json.getAsString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return UuidTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class LocaleTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Locale>, JsonDeserializer<Locale> {
 | 
			
		||||
    public JsonElement serialize(Locale src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src.toString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Locale deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      String locale = json.getAsString();
 | 
			
		||||
      StringTokenizer tokenizer = new StringTokenizer(locale, "_");
 | 
			
		||||
      String language = null;
 | 
			
		||||
      String country = null;
 | 
			
		||||
      String variant = null;
 | 
			
		||||
      if (tokenizer.hasMoreElements()) {
 | 
			
		||||
        language = tokenizer.nextToken();
 | 
			
		||||
      }
 | 
			
		||||
      if (tokenizer.hasMoreElements()) {
 | 
			
		||||
        country = tokenizer.nextToken();
 | 
			
		||||
      }
 | 
			
		||||
      if (tokenizer.hasMoreElements()) {
 | 
			
		||||
        variant = tokenizer.nextToken();
 | 
			
		||||
      }
 | 
			
		||||
      if (country == null && variant == null) {
 | 
			
		||||
        return new Locale(language);
 | 
			
		||||
      } else if (variant == null) {
 | 
			
		||||
        return new Locale(language, country);
 | 
			
		||||
      } else {
 | 
			
		||||
        return new Locale(language, country, variant);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return LocaleTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings({"unchecked", "rawtypes"})
 | 
			
		||||
  private static class CollectionTypeAdapter implements JsonSerializer<Collection>,
 | 
			
		||||
      JsonDeserializer<Collection>, InstanceCreator<Collection> {
 | 
			
		||||
    public JsonElement serialize(Collection src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      if (src == null) {
 | 
			
		||||
        return JsonNull.createJsonNull();
 | 
			
		||||
      }
 | 
			
		||||
      JsonArray array = new JsonArray();
 | 
			
		||||
      Type childGenericType = null;
 | 
			
		||||
      if (typeOfSrc instanceof ParameterizedType) {
 | 
			
		||||
        childGenericType = new TypeInfoCollection(typeOfSrc).getElementType();
 | 
			
		||||
      }
 | 
			
		||||
      for (Object child : src) {
 | 
			
		||||
        if (child == null) {
 | 
			
		||||
          array.add(JsonNull.createJsonNull());
 | 
			
		||||
        } else {
 | 
			
		||||
          Type childType = (childGenericType == null || childGenericType == Object.class)
 | 
			
		||||
              ? child.getClass() : childGenericType;
 | 
			
		||||
          JsonElement element = context.serialize(child, childType);
 | 
			
		||||
          array.add(element);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Collection deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      if (json.isJsonNull()) {
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
      // 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();
 | 
			
		||||
      for (JsonElement childElement : json.getAsJsonArray()) {
 | 
			
		||||
        if (childElement == null || childElement.isJsonNull()) {
 | 
			
		||||
          collection.add(null);
 | 
			
		||||
        } else {
 | 
			
		||||
          Object value = context.deserialize(childElement, childType);
 | 
			
		||||
          collection.add(value);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return collection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Collection constructCollectionType(Type collectionType,
 | 
			
		||||
        JsonDeserializationContext context) {
 | 
			
		||||
      JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
 | 
			
		||||
      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
 | 
			
		||||
      implements JsonSerializer<BigDecimal>, JsonDeserializer<BigDecimal> {
 | 
			
		||||
    public JsonElement serialize(BigDecimal src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BigDecimal deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      return json.getAsBigDecimal();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return BigDecimalTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class BigIntegerTypeAdapter
 | 
			
		||||
      implements JsonSerializer<BigInteger>, JsonDeserializer<BigInteger> {
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(BigInteger src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BigInteger deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
        JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
      return json.getAsBigInteger();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return BigIntegerTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class NumberTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Number>, JsonDeserializer<Number> {
 | 
			
		||||
    public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Number deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsNumber();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return NumberTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class LongSerializer implements JsonSerializer<Long> {
 | 
			
		||||
    private final LongSerializationPolicy longSerializationPolicy;
 | 
			
		||||
 | 
			
		||||
    private LongSerializer(LongSerializationPolicy longSerializationPolicy) {
 | 
			
		||||
      this.longSerializationPolicy = longSerializationPolicy;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return longSerializationPolicy.serialize(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return LongSerializer.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class LongDeserializer implements JsonDeserializer<Long> {
 | 
			
		||||
    public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsLong();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return LongDeserializer.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class IntegerTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
 | 
			
		||||
    public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsInt();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return IntegerTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class ShortTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Short>, JsonDeserializer<Short> {
 | 
			
		||||
    public JsonElement serialize(Short src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Short deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsShort();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return ShortTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static 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 {
 | 
			
		||||
      return json.getAsByte();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return ByteTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class FloatSerializer implements JsonSerializer<Float> {
 | 
			
		||||
    private final boolean serializeSpecialFloatingPointValues;
 | 
			
		||||
 | 
			
		||||
    FloatSerializer(boolean serializeSpecialDoubleValues) {
 | 
			
		||||
      this.serializeSpecialFloatingPointValues = serializeSpecialDoubleValues;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(Float src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      if (!serializeSpecialFloatingPointValues) {
 | 
			
		||||
        if (Float.isNaN(src) || Float.isInfinite(src)) {
 | 
			
		||||
          throw new IllegalArgumentException(src
 | 
			
		||||
              + " is not a valid float value as per JSON specification. To override this"
 | 
			
		||||
              + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class FloatDeserializer implements JsonDeserializer<Float> {
 | 
			
		||||
    public Float deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsFloat();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return FloatDeserializer.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static class DoubleSerializer implements JsonSerializer<Double> {
 | 
			
		||||
    private final boolean serializeSpecialFloatingPointValues;
 | 
			
		||||
 | 
			
		||||
    DoubleSerializer(boolean serializeSpecialDoubleValues) {
 | 
			
		||||
      this.serializeSpecialFloatingPointValues = serializeSpecialDoubleValues;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      if (!serializeSpecialFloatingPointValues) {
 | 
			
		||||
        if (Double.isNaN(src) || Double.isInfinite(src)) {
 | 
			
		||||
          throw new IllegalArgumentException(src
 | 
			
		||||
              + " is not a valid double value as per JSON specification. To override this"
 | 
			
		||||
              + " behavior, use GsonBuilder.serializeSpecialDoubleValues() method.");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class DoubleDeserializer implements JsonDeserializer<Double> {
 | 
			
		||||
    public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsDouble();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return DoubleDeserializer.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class CharacterTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Character>, JsonDeserializer<Character> {
 | 
			
		||||
    public JsonElement serialize(Character src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Character deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsCharacter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return CharacterTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class StringTypeAdapter
 | 
			
		||||
      implements JsonSerializer<String>, JsonDeserializer<String> {
 | 
			
		||||
    public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return StringTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class BooleanTypeAdapter
 | 
			
		||||
      implements JsonSerializer<Boolean>, JsonDeserializer<Boolean> {
 | 
			
		||||
    public JsonElement serialize(Boolean src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
      return new JsonPrimitive(src);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
        throws JsonParseException {
 | 
			
		||||
      return json.getAsBoolean();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return BooleanTypeAdapter.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class TreeSetCreator implements InstanceCreator<TreeSet<?>> {
 | 
			
		||||
    public TreeSet<?> createInstance(Type type) {
 | 
			
		||||
      return new TreeSet<Object>();
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return TreeSetCreator.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static class HashSetCreator implements InstanceCreator<HashSet<?>> {
 | 
			
		||||
    public HashSet<?> createInstance(Type type) {
 | 
			
		||||
      return new HashSet<Object>();
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
      return HashSetCreator.class.getSimpleName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								src/com/bukkit/mcteam/gson/DelegatingJsonElementVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/com/bukkit/mcteam/gson/DelegatingJsonElementVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple implementation of the {@link JsonElementVisitor} that simply delegates the method
 | 
			
		||||
 * invocation onto a {@code delegate} instance of the {@link JsonElementVisitor}.  This object
 | 
			
		||||
 * can be used to build a chain of visitors such that each Visitor instance can perform some
 | 
			
		||||
 * operation on the {@link JsonElement} and then pass on the input to the delegate.  This kind
 | 
			
		||||
 * of pattern is sometimes referred as a "Chain of Responsibility".
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example use case:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class JsonEscapingVisitor extends DelegatingJsonElementVisitor {
 | 
			
		||||
 *   public JsonEscapingVisitor(JsonElementVisitor) {
 | 
			
		||||
 *     super(visitor);
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public void visitPrimitive(JsonPrimitive primitive) {
 | 
			
		||||
 *     JsonPrimitive escapedPrimitive = escapePrimitiveObject(primitive);
 | 
			
		||||
 *     super.visitPrimitive(escapedPrimitive);
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * JsonElementVisitor visitor = new JsonEscapingVisitor(new FormattingVisitor());
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
class DelegatingJsonElementVisitor implements JsonElementVisitor {
 | 
			
		||||
  private final JsonElementVisitor delegate;
 | 
			
		||||
 | 
			
		||||
  protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) {
 | 
			
		||||
    Preconditions.checkNotNull(delegate);
 | 
			
		||||
    this.delegate = delegate;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void endArray(JsonArray array) throws IOException {
 | 
			
		||||
    delegate.endArray(array);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void endObject(JsonObject object) throws IOException {
 | 
			
		||||
    delegate.endObject(object);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void startArray(JsonArray array) throws IOException {
 | 
			
		||||
    delegate.startArray(array);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void startObject(JsonObject object) throws IOException {
 | 
			
		||||
    delegate.startObject(object);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayMember(JsonArray parent, JsonPrimitive member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitArrayMember(parent, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayMember(JsonArray parent, JsonArray member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitArrayMember(parent, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayMember(JsonArray parent, JsonObject member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitArrayMember(parent, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitObjectMember(parent, memberName, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectMember(JsonObject parent, String memberName, JsonArray member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitObjectMember(parent, memberName, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectMember(JsonObject parent, String memberName, JsonObject member, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitObjectMember(parent, memberName, member, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitNullObjectMember(JsonObject parent, String memberName, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitNullObjectMember(parent, memberName, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitPrimitive(JsonPrimitive primitive) throws IOException {
 | 
			
		||||
    delegate.visitPrimitive(primitive);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitNull() throws IOException {
 | 
			
		||||
    delegate.visitNull();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitNullArrayMember(JsonArray parent, boolean isFirst) throws IOException {
 | 
			
		||||
    delegate.visitNullArrayMember(parent, isFirst);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								src/com/bukkit/mcteam/gson/DisjunctionExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/com/bukkit/mcteam/gson/DisjunctionExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A wrapper class used to collect numerous {@link ExclusionStrategy} objects
 | 
			
		||||
 * and perform a short-circuited OR operation.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class DisjunctionExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
  private final Collection<ExclusionStrategy> strategies;
 | 
			
		||||
 | 
			
		||||
  public DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
 | 
			
		||||
    Preconditions.checkNotNull(strategies);
 | 
			
		||||
    this.strategies = strategies;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    for (ExclusionStrategy strategy : strategies) {
 | 
			
		||||
      if (strategy.shouldSkipField(f)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    for (ExclusionStrategy strategy : strategies) {
 | 
			
		||||
      if (strategy.shouldSkipClass(clazz)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										160
									
								
								src/com/bukkit/mcteam/gson/Escaper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/com/bukkit/mcteam/gson/Escaper.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A utility class that is used to perform JSON escaping so that ", <, >, etc. characters are
 | 
			
		||||
 * properly encoded in the JSON string representation before returning to the client code.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class contains a single method to escape a passed in string value:
 | 
			
		||||
 * <pre>
 | 
			
		||||
 *   String jsonStringValue = "beforeQuote\"afterQuote";
 | 
			
		||||
 *   String escapedValue = Escaper.escapeJsonString(jsonStringValue);
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class Escaper {
 | 
			
		||||
 | 
			
		||||
  private static final char[] HEX_CHARS = {
 | 
			
		||||
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  private static final Set<Character> JS_ESCAPE_CHARS;
 | 
			
		||||
  private static final Set<Character> HTML_ESCAPE_CHARS;
 | 
			
		||||
 | 
			
		||||
  static {
 | 
			
		||||
    Set<Character> mandatoryEscapeSet = new HashSet<Character>();
 | 
			
		||||
    mandatoryEscapeSet.add('"');
 | 
			
		||||
    mandatoryEscapeSet.add('\\');
 | 
			
		||||
    JS_ESCAPE_CHARS = Collections.unmodifiableSet(mandatoryEscapeSet);
 | 
			
		||||
 | 
			
		||||
    Set<Character> htmlEscapeSet = new HashSet<Character>();
 | 
			
		||||
    htmlEscapeSet.add('<');
 | 
			
		||||
    htmlEscapeSet.add('>');
 | 
			
		||||
    htmlEscapeSet.add('&');
 | 
			
		||||
    htmlEscapeSet.add('=');
 | 
			
		||||
    htmlEscapeSet.add('\''); 
 | 
			
		||||
//    htmlEscapeSet.add('/');  -- Removing slash for now since it causes some incompatibilities
 | 
			
		||||
    HTML_ESCAPE_CHARS = Collections.unmodifiableSet(htmlEscapeSet);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private final boolean escapeHtmlCharacters;
 | 
			
		||||
  
 | 
			
		||||
  Escaper(boolean escapeHtmlCharacters) {
 | 
			
		||||
    this.escapeHtmlCharacters = escapeHtmlCharacters;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public String escapeJsonString(CharSequence plainText) {
 | 
			
		||||
    StringBuffer escapedString = new StringBuffer(plainText.length() + 20);
 | 
			
		||||
    try {
 | 
			
		||||
      escapeJsonString(plainText, escapedString);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
    return escapedString.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void escapeJsonString(CharSequence plainText, StringBuffer out) throws IOException {
 | 
			
		||||
    int pos = 0;  // Index just past the last char in plainText written to out.
 | 
			
		||||
    int len = plainText.length();
 | 
			
		||||
    
 | 
			
		||||
    for (int charCount, i = 0; i < len; i += charCount) {
 | 
			
		||||
      int codePoint = Character.codePointAt(plainText, i);
 | 
			
		||||
      charCount = Character.charCount(codePoint);
 | 
			
		||||
      
 | 
			
		||||
       if (!isControlCharacter(codePoint) && !mustEscapeCharInJsString(codePoint)) {
 | 
			
		||||
          continue;
 | 
			
		||||
       }
 | 
			
		||||
 | 
			
		||||
       out.append(plainText, pos, i);
 | 
			
		||||
       pos = i + charCount;
 | 
			
		||||
       switch (codePoint) {
 | 
			
		||||
         case '\b':
 | 
			
		||||
           out.append("\\b");
 | 
			
		||||
           break;
 | 
			
		||||
         case '\t':
 | 
			
		||||
           out.append("\\t");
 | 
			
		||||
           break;
 | 
			
		||||
         case '\n':
 | 
			
		||||
           out.append("\\n");
 | 
			
		||||
           break;
 | 
			
		||||
         case '\f':
 | 
			
		||||
           out.append("\\f");
 | 
			
		||||
           break;
 | 
			
		||||
         case '\r':
 | 
			
		||||
           out.append("\\r");
 | 
			
		||||
           break;
 | 
			
		||||
         case '\\':
 | 
			
		||||
           out.append("\\\\");
 | 
			
		||||
           break;
 | 
			
		||||
         case '/':
 | 
			
		||||
           out.append("\\/");
 | 
			
		||||
           break;
 | 
			
		||||
         case '"':
 | 
			
		||||
           out.append("\\\"");
 | 
			
		||||
           break;
 | 
			
		||||
         default:
 | 
			
		||||
           appendHexJavaScriptRepresentation(codePoint, out);
 | 
			
		||||
           break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
     out.append(plainText, pos, len);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  private boolean mustEscapeCharInJsString(int codepoint) {
 | 
			
		||||
    if (!Character.isSupplementaryCodePoint(codepoint)) {
 | 
			
		||||
      char c = (char) codepoint;
 | 
			
		||||
      return JS_ESCAPE_CHARS.contains(c)
 | 
			
		||||
          || (escapeHtmlCharacters && HTML_ESCAPE_CHARS.contains(c));
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static boolean isControlCharacter(int codePoint) {
 | 
			
		||||
    // JSON spec defines these code points as control characters, so they must be escaped
 | 
			
		||||
    return codePoint < 0x20
 | 
			
		||||
        || codePoint == 0x2028  // Line separator
 | 
			
		||||
        || codePoint == 0x2029  // Paragraph separator
 | 
			
		||||
        || (codePoint >= 0x7f && codePoint <= 0x9f);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void appendHexJavaScriptRepresentation(int codePoint, Appendable out)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    if (Character.isSupplementaryCodePoint(codePoint)) {
 | 
			
		||||
      // Handle supplementary unicode values which are not representable in
 | 
			
		||||
      // javascript.  We deal with these by escaping them as two 4B sequences
 | 
			
		||||
      // so that they will round-trip properly when sent from java to javascript
 | 
			
		||||
      // and back.
 | 
			
		||||
      char[] surrogates = Character.toChars(codePoint);
 | 
			
		||||
      appendHexJavaScriptRepresentation(surrogates[0], out);
 | 
			
		||||
      appendHexJavaScriptRepresentation(surrogates[1], out);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    out.append("\\u")
 | 
			
		||||
        .append(HEX_CHARS[(codePoint >>> 12) & 0xf])
 | 
			
		||||
        .append(HEX_CHARS[(codePoint >>> 8) & 0xf])
 | 
			
		||||
        .append(HEX_CHARS[(codePoint >>> 4) & 0xf])
 | 
			
		||||
        .append(HEX_CHARS[codePoint & 0xf]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								src/com/bukkit/mcteam/gson/ExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/com/bukkit/mcteam/gson/ExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A strategy (or policy) definition that is used to decide whether or not a field or top-level
 | 
			
		||||
 * class should be serialized or deserialized as part of the JSON output/input. For serialization,
 | 
			
		||||
 * if the {@link #shouldSkipClass(Class)} method returns false then that class or field type
 | 
			
		||||
 * will not be part of the JSON output.  For deserialization, if {@link #shouldSkipClass(Class)}
 | 
			
		||||
 * returns false, then it will not be set as part of the Java object structure.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following are a few examples that shows how you can use this exclusion mechanism.
 | 
			
		||||
 *
 | 
			
		||||
 * <p><strong>Exclude fields and objects based on a particular class type:</strong>
 | 
			
		||||
 * <pre class="code">
 | 
			
		||||
 * private static class SpecificClassExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
 *   private final Class<?> excludedThisClass;
 | 
			
		||||
 *
 | 
			
		||||
 *   public SpecificClassExclusionStrategy(Class<?> excludedThisClass) {
 | 
			
		||||
 *     this.excludedThisClass = excludedThisClass;
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
 *     return excludedThisClass.equals(clazz);
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
 *     return excludedThisClass.equals(f.getDeclaredClass());
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p><strong>Excludes fields and objects based on a particular annotation:</strong>
 | 
			
		||||
 * <pre class="code">
 | 
			
		||||
 * public @interface FooAnnotation {
 | 
			
		||||
 *   // some implementation here
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * // Excludes any field (or class) that is tagged with an "@FooAnnotation"
 | 
			
		||||
 * private static class FooAnnotationExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
 *   public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
 *     return clazz.getAnnotation(FooAnnotation.class) != null;
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
 *     return f.getAnnotation(FooAnnotation.class) != null;
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Now if you want to configure {@code Gson} to use a user defined exclusion strategy, then
 | 
			
		||||
 * the {@code GsonBuilder} is required. The following is an example of how you can use the
 | 
			
		||||
 * {@code GsonBuilder} to configure Gson to use one of the above sample:
 | 
			
		||||
 * <pre class="code">
 | 
			
		||||
 * ExclusionStrategy excludeStrings = new UserDefinedExclusionStrategy(String.class);
 | 
			
		||||
 * Gson gson = new GsonBuilder()
 | 
			
		||||
 *     .setExclusionStrategies(excludeStrings)
 | 
			
		||||
 *     .create();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @see GsonBuilder#setExclusionStrategies(ExclusionStrategy...)
 | 
			
		||||
 *
 | 
			
		||||
 * @since 1.4
 | 
			
		||||
 */
 | 
			
		||||
public interface ExclusionStrategy {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param f the field object that is under test
 | 
			
		||||
   * @return true if the field should be ignored; otherwise false
 | 
			
		||||
   */
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param clazz the class object that is under test
 | 
			
		||||
   * @return true if the class should be ignored; otherwise false
 | 
			
		||||
   */
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    Expose annotation = f.getAnnotation(Expose.class);
 | 
			
		||||
    if (annotation == null) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return !annotation.deserialize();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    Expose annotation = f.getAnnotation(Expose.class);
 | 
			
		||||
    if (annotation == null) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return !annotation.serialize();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										229
									
								
								src/com/bukkit/mcteam/gson/FieldAttributes.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								src/com/bukkit/mcteam/gson/FieldAttributes.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,229 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A data object that stores attributes of a field.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class is immutable; therefore, it can be safely shared across threads.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @since 1.4
 | 
			
		||||
 */
 | 
			
		||||
public final class FieldAttributes {
 | 
			
		||||
  private static final String MAX_CACHE_PROPERTY_NAME =
 | 
			
		||||
      "com.bukkit.mcteam.gson.annotation_cache_size_hint";
 | 
			
		||||
 | 
			
		||||
  private static final Cache<Pair<Class<?>, String>, Collection<Annotation>> ANNOTATION_CACHE =
 | 
			
		||||
      new LruCache<Pair<Class<?>,String>, Collection<Annotation>>(getMaxCacheSize());
 | 
			
		||||
 | 
			
		||||
  private final Class<?> declaringClazz;
 | 
			
		||||
  private final Field field;
 | 
			
		||||
  private final Class<?> declaredType;
 | 
			
		||||
  private final boolean isSynthetic;
 | 
			
		||||
  private final int modifiers;
 | 
			
		||||
  private final String name;
 | 
			
		||||
 | 
			
		||||
  // Fields used for lazy initialization
 | 
			
		||||
  private Type genericType;
 | 
			
		||||
  private Collection<Annotation> annotations;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a Field Attributes object from the {@code f}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param f the field to pull attributes from
 | 
			
		||||
   */
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static int getMaxCacheSize() {
 | 
			
		||||
    final int defaultMaxCacheSize = 2000;
 | 
			
		||||
    try {
 | 
			
		||||
      String propertyValue = System.getProperty(
 | 
			
		||||
          MAX_CACHE_PROPERTY_NAME, String.valueOf(defaultMaxCacheSize));
 | 
			
		||||
      return Integer.parseInt(propertyValue);
 | 
			
		||||
    } catch (NumberFormatException e) {
 | 
			
		||||
      return defaultMaxCacheSize;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the declaring class that contains this field
 | 
			
		||||
   */
 | 
			
		||||
  public Class<?> getDeclaringClass() {
 | 
			
		||||
    return declaringClazz;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the name of the field
 | 
			
		||||
   */
 | 
			
		||||
  public String getName() {
 | 
			
		||||
    return name;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * <p>For example, assume the following class definition:
 | 
			
		||||
   * <pre class="code">
 | 
			
		||||
   * public class Foo {
 | 
			
		||||
   *   private String bar;
 | 
			
		||||
   *   private List<String> red;
 | 
			
		||||
   * }
 | 
			
		||||
   *
 | 
			
		||||
   * Type listParmeterizedType = new TypeToken<List<String>>() {}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   *
 | 
			
		||||
   * <p>This method would return {@code String.class} for the {@code bar} field and
 | 
			
		||||
   * {@code listParameterizedType} for the {@code red} field.
 | 
			
		||||
   *
 | 
			
		||||
   * @return the specific type declared for this field
 | 
			
		||||
   */
 | 
			
		||||
  public Type getDeclaredType() {
 | 
			
		||||
    if (genericType == null) {
 | 
			
		||||
      genericType = field.getGenericType();
 | 
			
		||||
    }
 | 
			
		||||
    return genericType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the {@code Class<?>} object that was declared for this field.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>For example, assume the following class definition:
 | 
			
		||||
   * <pre class="code">
 | 
			
		||||
   * public class Foo {
 | 
			
		||||
   *   private String bar;
 | 
			
		||||
   *   private List<String> red;
 | 
			
		||||
   * }
 | 
			
		||||
   * </pre>
 | 
			
		||||
   *
 | 
			
		||||
   * <p>This method would return {@code String.class} for the {@code bar} field and
 | 
			
		||||
   * {@code List.class} for the {@code red} field.
 | 
			
		||||
   *
 | 
			
		||||
   * @return the specific class object that was declared for the field
 | 
			
		||||
   */
 | 
			
		||||
  public Class<?> getDeclaredClass() {
 | 
			
		||||
    return declaredType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the {@code T} annotation object from this field if it exist; otherwise returns
 | 
			
		||||
   * {@code null}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param annotation the class of the annotation that will be retrieved
 | 
			
		||||
   * @return the annotation instance if it is bound to the field; otherwise {@code null}
 | 
			
		||||
   */
 | 
			
		||||
  public <T extends Annotation> T getAnnotation(Class<T> annotation) {
 | 
			
		||||
    return getAnnotationFromArray(getAnnotations(), annotation);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the annotations that are present on this field.
 | 
			
		||||
   *
 | 
			
		||||
   * @return an array of all the annotations set on the field
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public Collection<Annotation> getAnnotations() {
 | 
			
		||||
    if (annotations == null) {
 | 
			
		||||
      Pair<Class<?>, String> key = new Pair<Class<?>, String>(declaringClazz, name);
 | 
			
		||||
      annotations = ANNOTATION_CACHE.getElement(key);
 | 
			
		||||
      if (annotations == null) {
 | 
			
		||||
        annotations = Collections.unmodifiableCollection(
 | 
			
		||||
            Arrays.asList(field.getAnnotations()));
 | 
			
		||||
        ANNOTATION_CACHE.addElement(key, annotations);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return annotations;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns {@code true} if the field is defined with the {@code modifier}.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>This method is meant to be called as:
 | 
			
		||||
   * <pre class="code">
 | 
			
		||||
   * boolean hasPublicModifier = fieldAttribute.hasModifier(java.lang.reflect.Modifier.PUBLIC);
 | 
			
		||||
   * </pre>
 | 
			
		||||
   *
 | 
			
		||||
   * @see java.lang.reflect.Modifier
 | 
			
		||||
   */
 | 
			
		||||
  public boolean hasModifier(int modifier) {
 | 
			
		||||
    return (modifiers & modifier) != 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This is exposed internally only for the removing synthetic fields from the JSON output.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws IllegalAccessException
 | 
			
		||||
   * @throws IllegalArgumentException
 | 
			
		||||
   */
 | 
			
		||||
  void set(Object instance, Object value) throws IllegalAccessException {
 | 
			
		||||
    field.set(instance, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This is exposed internally only for the removing synthetic fields from the JSON output.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if the field is synthetic; otherwise false
 | 
			
		||||
   * @throws IllegalAccessException
 | 
			
		||||
   * @throws IllegalArgumentException
 | 
			
		||||
   */
 | 
			
		||||
  Object get(Object instance) throws IllegalAccessException {
 | 
			
		||||
    return field.get(instance);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This is exposed internally only for the removing synthetic fields from the JSON output.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if the field is synthetic; otherwise false
 | 
			
		||||
   */
 | 
			
		||||
  boolean isSynthetic() {
 | 
			
		||||
    return isSynthetic;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @deprecated remove this when {@link FieldNamingStrategy} is deleted.
 | 
			
		||||
   */
 | 
			
		||||
  @Deprecated
 | 
			
		||||
  Field getFieldObject() {
 | 
			
		||||
    return field;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  private static <T extends Annotation> T getAnnotationFromArray(
 | 
			
		||||
      Collection<Annotation> annotations, Class<T> annotation) {
 | 
			
		||||
    for (Annotation a : annotations) {
 | 
			
		||||
      if (a.annotationType() == annotation) {
 | 
			
		||||
        return (T) a;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								src/com/bukkit/mcteam/gson/FieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/com/bukkit/mcteam/gson/FieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An enumeration that defines a few standard naming conventions for JSON field names.
 | 
			
		||||
 * This enumeration should be used in conjunction with {@link com.bukkit.mcteam.gson.GsonBuilder}
 | 
			
		||||
 * to configure a {@link com.bukkit.mcteam.gson.Gson} instance to properly translate Java field
 | 
			
		||||
 * names into the desired JSON field names.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public enum FieldNamingPolicy {
 | 
			
		||||
  /**
 | 
			
		||||
   * Using this naming policy with Gson will ensure that the first "letter" of the Java
 | 
			
		||||
   * field name is capitalized when serialized to its JSON form.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>someFieldName ---> SomeFieldName</li>
 | 
			
		||||
   *   <li>_someFieldName ---> _SomeFieldName</li>
 | 
			
		||||
   * </ul>
 | 
			
		||||
   */
 | 
			
		||||
  UPPER_CAMEL_CASE(new ModifyFirstLetterNamingPolicy(
 | 
			
		||||
      ModifyFirstLetterNamingPolicy.LetterModifier.UPPER)),
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Using this naming policy with Gson will ensure that the first "letter" of the Java
 | 
			
		||||
   * field name is capitalized when serialized to its JSON form and the words will be
 | 
			
		||||
   * separated by a space.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>someFieldName ---> Some Field Name</li>
 | 
			
		||||
   *   <li>_someFieldName ---> _Some Field Name</li>
 | 
			
		||||
   * </ul>
 | 
			
		||||
   * 
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  UPPER_CAMEL_CASE_WITH_SPACES(new UpperCamelCaseSeparatorNamingPolicy(" ")),
 | 
			
		||||
          
 | 
			
		||||
  /**
 | 
			
		||||
   * Using this naming policy with Gson will modify the Java Field name from its camel cased
 | 
			
		||||
   * form to a lower case field name where each word is separated by an underscore (_).
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>someFieldName ---> some_field_name</li>
 | 
			
		||||
   *   <li>_someFieldName ---> _some_field_name</li>
 | 
			
		||||
   *   <li>aStringField ---> a_string_field</li>
 | 
			
		||||
   *   <li>aURL ---> a_u_r_l</li>
 | 
			
		||||
   * </ul>
 | 
			
		||||
   */
 | 
			
		||||
  LOWER_CASE_WITH_UNDERSCORES(new LowerCamelCaseSeparatorNamingPolicy("_")),
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Using this naming policy with Gson will modify the Java Field name from its camel cased
 | 
			
		||||
   * form to a lower case field name where each word is separated by a dash (-).
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":</p>
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>someFieldName ---> some-field-name</li>
 | 
			
		||||
   *   <li>_someFieldName ---> _some-field-name</li>
 | 
			
		||||
   *   <li>aStringField ---> a-string-field</li>
 | 
			
		||||
   *   <li>aURL ---> a-u-r-l</li>
 | 
			
		||||
   * </ul>
 | 
			
		||||
   * Using dashes in JavaScript is not recommended since dash is also used for a minus sign in
 | 
			
		||||
   * expressions. This requires that a field named with dashes is always accessed as a quoted
 | 
			
		||||
   * property like {@code myobject['my-field']}. Accessing it as an object field
 | 
			
		||||
   * {@code myobject.my-field} will result in an unintended javascript expression.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  LOWER_CASE_WITH_DASHES(new LowerCamelCaseSeparatorNamingPolicy("-"));
 | 
			
		||||
 | 
			
		||||
  private final FieldNamingStrategy2 namingPolicy;
 | 
			
		||||
 | 
			
		||||
  private FieldNamingPolicy(FieldNamingStrategy2 namingPolicy) {
 | 
			
		||||
    this.namingPolicy = namingPolicy;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FieldNamingStrategy2 getFieldNamingPolicy() {
 | 
			
		||||
    return namingPolicy;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A mechanism for providing custom field naming in Gson.  This allows the client code to translate
 | 
			
		||||
 * field names into a particular convention that is not supported as a normal Java field
 | 
			
		||||
 * declaration rules.  For example, Java does not support "-" characters in a field name.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * @since 1.3
 | 
			
		||||
 */
 | 
			
		||||
public interface FieldNamingStrategy {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Translates the field name into its JSON field name representation.
 | 
			
		||||
   *
 | 
			
		||||
   * @param f the field object that we are translating
 | 
			
		||||
   * @return the translated field name.
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public String translateName(Field f);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy2.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy2.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The new mechanism for providing custom field naming in Gson.  This allows the client code
 | 
			
		||||
 * to translate field names into a particular convention that is not supported as a normal
 | 
			
		||||
 * Java field declaration rules.  For example, Java does not support "-" characters in a
 | 
			
		||||
 * field name.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
interface FieldNamingStrategy2 {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Translates the field name into its JSON field name representation.
 | 
			
		||||
   *
 | 
			
		||||
   * @param f the field that is being translated
 | 
			
		||||
   * @return the translated field name.
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public String translateName(FieldAttributes f);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy2Adapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/com/bukkit/mcteam/gson/FieldNamingStrategy2Adapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adapts the old "deprecated" {@link FieldNamingStrategy} to the new {@link FieldNamingStrategy2}
 | 
			
		||||
 * type. 
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class FieldNamingStrategy2Adapter implements FieldNamingStrategy2 {
 | 
			
		||||
  private final FieldNamingStrategy adaptee;
 | 
			
		||||
 | 
			
		||||
  public FieldNamingStrategy2Adapter(FieldNamingStrategy adaptee) {
 | 
			
		||||
    Preconditions.checkNotNull(adaptee);
 | 
			
		||||
    this.adaptee = adaptee;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  @SuppressWarnings("deprecation")
 | 
			
		||||
  public String translateName(FieldAttributes f) {
 | 
			
		||||
    return adaptee.translateName(f.getFieldObject());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								src/com/bukkit/mcteam/gson/GenericArrayTypeImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/com/bukkit/mcteam/gson/GenericArrayTypeImpl.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										595
									
								
								src/com/bukkit/mcteam/gson/Gson.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										595
									
								
								src/com/bukkit/mcteam/gson/Gson.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,595 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonReader;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonToken;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonWriter;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.MalformedJsonException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.io.StringReader;
 | 
			
		||||
import java.io.StringWriter;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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)}
 | 
			
		||||
 * methods on it.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration
 | 
			
		||||
 * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
 | 
			
		||||
 * configuration options such as versioning support, pretty printing, custom
 | 
			
		||||
 * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Here is an example of how Gson is used for a simple Class:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Gson gson = new Gson(); // Or use new GsonBuilder().create();
 | 
			
		||||
 * MyType target = new MyType();
 | 
			
		||||
 * String json = gson.toJson(target); // serializes target to Json
 | 
			
		||||
 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>If the object that your are serializing/deserializing is a {@code ParameterizedType}
 | 
			
		||||
 * (i.e. contains at least one type parameter and may be an array) then you must use the
 | 
			
		||||
 * {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method.  Here is an
 | 
			
		||||
 * example for serializing and deserialing a {@code ParameterizedType}:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Type listType = new TypeToken<List<String>>() {}.getType();
 | 
			
		||||
 * List<String> target = new LinkedList<String>();
 | 
			
		||||
 * target.add("blah");
 | 
			
		||||
 *
 | 
			
		||||
 * Gson gson = new Gson();
 | 
			
		||||
 * String json = gson.toJson(target, listType);
 | 
			
		||||
 * List<String> target2 = gson.fromJson(json, listType);
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
 | 
			
		||||
 * for a more complete set of examples.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @see com.bukkit.mcteam.gson.reflect.TypeToken
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
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
 | 
			
		||||
  static final AnonymousAndLocalClassExclusionStrategy DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY =
 | 
			
		||||
      new AnonymousAndLocalClassExclusionStrategy();
 | 
			
		||||
  static final SyntheticFieldExclusionStrategy DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY =
 | 
			
		||||
      new SyntheticFieldExclusionStrategy(true);
 | 
			
		||||
  static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
 | 
			
		||||
      new ModifierBasedExclusionStrategy(new int[] { Modifier.TRANSIENT, Modifier.STATIC });
 | 
			
		||||
  static final FieldNamingStrategy2 DEFAULT_NAMING_POLICY =
 | 
			
		||||
      new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
 | 
			
		||||
 | 
			
		||||
  private static final ExclusionStrategy DEFAULT_EXCLUSION_STRATEGY =
 | 
			
		||||
      createExclusionStrategy(VersionConstants.IGNORE_VERSIONS);
 | 
			
		||||
 | 
			
		||||
  private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
 | 
			
		||||
 | 
			
		||||
  private final ExclusionStrategy serializationStrategy;
 | 
			
		||||
 | 
			
		||||
  private final ExclusionStrategy deserializationStrategy;
 | 
			
		||||
 | 
			
		||||
  private final FieldNamingStrategy2 fieldNamingPolicy;
 | 
			
		||||
  private final MappedObjectConstructor objectConstructor;
 | 
			
		||||
 | 
			
		||||
  /** Map containing Type or Class objects as keys */
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
 | 
			
		||||
 | 
			
		||||
  /** Map containing Type or Class objects as keys */
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
 | 
			
		||||
 | 
			
		||||
  private final boolean serializeNulls;
 | 
			
		||||
  private final boolean htmlSafe;
 | 
			
		||||
  private final boolean generateNonExecutableJson;
 | 
			
		||||
  private final boolean prettyPrinting;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a Gson object with default configuration. The default configuration has the
 | 
			
		||||
   * following settings:
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>The JSON generated by <code>toJson</code> methods is in compact representation. This
 | 
			
		||||
   *   means that all the unneeded white-space is removed. You can change this behavior with
 | 
			
		||||
   *   {@link GsonBuilder#setPrettyPrinting()}. </li>
 | 
			
		||||
   *   <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are
 | 
			
		||||
   *   kept as is since an array is an ordered list. Moreover, if a field is not null, but its
 | 
			
		||||
   *   generated JSON is empty, the field is kept. You can configure Gson to serialize null values
 | 
			
		||||
   *   by setting {@link GsonBuilder#serializeNulls()}.</li>
 | 
			
		||||
   *   <li>Gson provides default serialization and deserialization for Enums, {@link Map},
 | 
			
		||||
   *   {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date},
 | 
			
		||||
   *   {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer
 | 
			
		||||
   *   to change the default representation, you can do so by registering a type adapter through
 | 
			
		||||
   *   {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li>
 | 
			
		||||
   *   <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format
 | 
			
		||||
   *   ignores the millisecond portion of the date during serialization. You can change
 | 
			
		||||
   *   this by invoking {@link GsonBuilder#setDateFormat(int)} or
 | 
			
		||||
   *   {@link GsonBuilder#setDateFormat(String)}. </li>
 | 
			
		||||
   *   <li>By default, Gson ignores the {@link com.bukkit.mcteam.gson.annotations.Expose} annotation.
 | 
			
		||||
   *   You can enable Gson to serialize/deserialize only those fields marked with this annotation
 | 
			
		||||
   *   through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li>
 | 
			
		||||
   *   <li>By default, Gson ignores the {@link com.bukkit.mcteam.gson.annotations.Since} annotation. You
 | 
			
		||||
   *   can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li>
 | 
			
		||||
   *   <li>The default field naming policy for the output Json is same as in Java. So, a Java class
 | 
			
		||||
   *   field <code>versionNumber</code> will be output as <code>"versionNumber@quot;</code> in
 | 
			
		||||
   *   Json. The same rules are applied for mapping incoming Json to the Java classes. You can
 | 
			
		||||
   *   change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li>
 | 
			
		||||
   *   <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from
 | 
			
		||||
   *   consideration for serialization and deserialization. You can change this behavior through
 | 
			
		||||
   *   {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li>
 | 
			
		||||
   * </ul>
 | 
			
		||||
   */
 | 
			
		||||
  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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Gson(ExclusionStrategy serializationStrategy, ExclusionStrategy deserializationStrategy,
 | 
			
		||||
       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.fieldNamingPolicy = fieldNamingPolicy;
 | 
			
		||||
    this.objectConstructor = objectConstructor;
 | 
			
		||||
    this.serializeNulls = serializeNulls;
 | 
			
		||||
    this.serializers = serializers;
 | 
			
		||||
    this.deserializers = deserializers;
 | 
			
		||||
    this.generateNonExecutableJson = generateNonExecutableGson;
 | 
			
		||||
    this.htmlSafe = htmlSafe;
 | 
			
		||||
    this.prettyPrinting = prettyPrinting;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private ObjectNavigatorFactory createDefaultObjectNavigatorFactory(ExclusionStrategy strategy) {
 | 
			
		||||
    return new ObjectNavigatorFactory(strategy, fieldNamingPolicy);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static ExclusionStrategy createExclusionStrategy(double version) {
 | 
			
		||||
    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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object into its equivalent representation as a tree of
 | 
			
		||||
   * {@link JsonElement}s. This method should be used when the specified object is not a generic
 | 
			
		||||
   * type. This method uses {@link Class#getClass()} to get the type for the specified object, but
 | 
			
		||||
   * the {@code getClass()} loses the generic type information because of the Type Erasure feature
 | 
			
		||||
   * of Java. Note that this method works fine if the any of the object fields are of generic type,
 | 
			
		||||
   * just the object itself should not be of a generic type. If the object is of generic type, use
 | 
			
		||||
   * {@link #toJsonTree(Object, Type)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which Json representation is to be created setting for Gson
 | 
			
		||||
   * @return Json representation of {@code src}.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement toJsonTree(Object src) {
 | 
			
		||||
    if (src == null) {
 | 
			
		||||
      return JsonNull.createJsonNull();
 | 
			
		||||
    }
 | 
			
		||||
    return toJsonTree(src, src.getClass());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object, including those of generic types, into its
 | 
			
		||||
   * equivalent representation as a tree of {@link JsonElement}s. This method must be used if the
 | 
			
		||||
   * specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)}
 | 
			
		||||
   * instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which JSON representation is to be created
 | 
			
		||||
   * @param typeOfSrc The specific genericized type of src. You can obtain
 | 
			
		||||
   * this type by using the {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example,
 | 
			
		||||
   * to get the type for {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @return Json representation of {@code src}
 | 
			
		||||
   * @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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object into its equivalent Json representation.
 | 
			
		||||
   * This method should be used when the specified object is not a generic type. This method uses
 | 
			
		||||
   * {@link Class#getClass()} to get the type for the specified object, but the
 | 
			
		||||
   * {@code getClass()} loses the generic type information because of the Type Erasure feature
 | 
			
		||||
   * of Java. Note that this method works fine if the any of the object fields are of generic type,
 | 
			
		||||
   * just the object itself should not be of a generic type. If the object is of generic type, use
 | 
			
		||||
   * {@link #toJson(Object, Type)} instead. If you want to write out the object to a
 | 
			
		||||
   * {@link Writer}, use {@link #toJson(Object, Appendable)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which Json representation is to be created setting for Gson
 | 
			
		||||
   * @return Json representation of {@code src}.
 | 
			
		||||
   */
 | 
			
		||||
  public String toJson(Object src) {
 | 
			
		||||
    if (src == null) {
 | 
			
		||||
      return serializeNulls ? NULL_STRING : "";
 | 
			
		||||
    }
 | 
			
		||||
    return toJson(src, src.getClass());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object, including those of generic types, into its
 | 
			
		||||
   * equivalent Json representation. This method must be used if the specified object is a generic
 | 
			
		||||
   * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out
 | 
			
		||||
   * the object to a {@link Appendable}, use {@link #toJson(Object, Type, Appendable)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which JSON representation is to be created
 | 
			
		||||
   * @param typeOfSrc The specific genericized type of src. You can obtain
 | 
			
		||||
   * this type by using the {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example,
 | 
			
		||||
   * to get the type for {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @return Json representation of {@code src}
 | 
			
		||||
   */
 | 
			
		||||
  public String toJson(Object src, Type typeOfSrc) {
 | 
			
		||||
    StringWriter writer = new StringWriter();
 | 
			
		||||
    toJson(toJsonTree(src, typeOfSrc), writer);
 | 
			
		||||
    return writer.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object into its equivalent Json representation.
 | 
			
		||||
   * This method should be used when the specified object is not a generic type. This method uses
 | 
			
		||||
   * {@link Class#getClass()} to get the type for the specified object, but the
 | 
			
		||||
   * {@code getClass()} loses the generic type information because of the Type Erasure feature
 | 
			
		||||
   * of Java. Note that this method works fine if the any of the object fields are of generic type,
 | 
			
		||||
   * just the object itself should not be of a generic type. If the object is of generic type, use
 | 
			
		||||
   * {@link #toJson(Object, Type, Appendable)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which Json representation is to be created setting for Gson
 | 
			
		||||
   * @param writer Writer to which the Json representation needs to be written
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the writer
 | 
			
		||||
   * @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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method serializes the specified object, including those of generic types, into its
 | 
			
		||||
   * equivalent Json representation. This method must be used if the specified object is a generic
 | 
			
		||||
   * type. For non-generic objects, use {@link #toJson(Object, Appendable)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object for which JSON representation is to be created
 | 
			
		||||
   * @param typeOfSrc The specific genericized type of src. You can obtain
 | 
			
		||||
   * this type by using the {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example,
 | 
			
		||||
   * to get the type for {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @param writer Writer to which the Json representation of src needs to be written.
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the writer
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
 | 
			
		||||
    JsonElement jsonElement = toJsonTree(src, typeOfSrc);
 | 
			
		||||
    toJson(jsonElement, writer);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
 | 
			
		||||
   * {@code writer}.
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the writer
 | 
			
		||||
   */
 | 
			
		||||
  public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
 | 
			
		||||
    toJson(toJsonTree(src, typeOfSrc), writer);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Converts a tree of {@link JsonElement}s into its equivalent JSON representation.
 | 
			
		||||
   *
 | 
			
		||||
   * @param jsonElement root of a tree of {@link JsonElement}s
 | 
			
		||||
   * @return JSON String representation of the tree
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public String toJson(JsonElement jsonElement) {
 | 
			
		||||
    StringWriter writer = new StringWriter();
 | 
			
		||||
    toJson(jsonElement, writer);
 | 
			
		||||
    return writer.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Writes out the equivalent JSON for a tree of {@link JsonElement}s.
 | 
			
		||||
   *
 | 
			
		||||
   * @param jsonElement root of a tree of {@link JsonElement}s
 | 
			
		||||
   * @param writer Writer to which the Json representation needs to be written
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the writer
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException {
 | 
			
		||||
    try {
 | 
			
		||||
      if (generateNonExecutableJson) {
 | 
			
		||||
        writer.append(JSON_NON_EXECUTABLE_PREFIX);
 | 
			
		||||
      }
 | 
			
		||||
      JsonWriter jsonWriter = new JsonWriter(Streams.writerForAppendable(writer));
 | 
			
		||||
      if (prettyPrinting) {
 | 
			
		||||
        jsonWriter.setIndent("  ");
 | 
			
		||||
      }
 | 
			
		||||
      toJson(jsonElement, jsonWriter);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Writes the JSON for {@code jsonElement} to {@code writer}.
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the writer
 | 
			
		||||
   */
 | 
			
		||||
  public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
 | 
			
		||||
    boolean oldLenient = writer.isLenient();
 | 
			
		||||
    writer.setLenient(true);
 | 
			
		||||
    boolean oldHtmlSafe = writer.isHtmlSafe();
 | 
			
		||||
    writer.setHtmlSafe(htmlSafe);
 | 
			
		||||
    try {
 | 
			
		||||
      Streams.write(jsonElement, serializeNulls, writer);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new JsonIOException(e);
 | 
			
		||||
    } finally {
 | 
			
		||||
      writer.setLenient(oldLenient);
 | 
			
		||||
      writer.setHtmlSafe(oldHtmlSafe);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the specified Json into an object of the specified class. It is not
 | 
			
		||||
   * suitable to use if the specified class is a generic type since it will not have the generic
 | 
			
		||||
   * type information because of the Type Erasure feature of Java. Therefore, this method should not
 | 
			
		||||
   * be used if the desired type is a generic type. Note that this method works fine if the any of
 | 
			
		||||
   * the fields of the specified object are generics, just the object itself should not be a
 | 
			
		||||
   * generic type. For the cases when the object is of generic type, invoke
 | 
			
		||||
   * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
 | 
			
		||||
   * a String, use {@link #fromJson(Reader, Class)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the string from which the object is to be deserialized
 | 
			
		||||
   * @param classOfT the class of T
 | 
			
		||||
   * @return an object of type T from the string
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type
 | 
			
		||||
   * classOfT
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
 | 
			
		||||
    Object object = fromJson(json, (Type) classOfT);
 | 
			
		||||
    return Primitives.wrap(classOfT).cast(object);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the specified Json into an object of the specified type. This method
 | 
			
		||||
   * is useful if the specified object is a generic type. For non-generic objects, use
 | 
			
		||||
   * {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
 | 
			
		||||
   * a String, use {@link #fromJson(Reader, Type)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the string from which the object is to be deserialized
 | 
			
		||||
   * @param typeOfT The specific genericized type of src. You can obtain this type by using the
 | 
			
		||||
   * {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example, to get the type for
 | 
			
		||||
   * {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @return an object of type T from the string
 | 
			
		||||
   * @throws JsonParseException if json is not a valid representation for an object of type typeOfT
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type
 | 
			
		||||
   */
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
 | 
			
		||||
    if (json == null) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    StringReader reader = new StringReader(json);
 | 
			
		||||
    T target = (T) fromJson(reader, typeOfT);
 | 
			
		||||
    return target;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the Json read from the specified reader into an object of the
 | 
			
		||||
   * specified class. It is not suitable to use if the specified class is a generic type since it
 | 
			
		||||
   * will not have the generic type information because of the Type Erasure feature of Java.
 | 
			
		||||
   * Therefore, this method should not be used if the desired type is a generic type. Note that
 | 
			
		||||
   * this method works fine if the any of the fields of the specified object are generics, just the
 | 
			
		||||
   * object itself should not be a generic type. For the cases when the object is of generic type,
 | 
			
		||||
   * invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
 | 
			
		||||
   * {@link Reader}, use {@link #fromJson(String, Class)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the reader producing the Json from which the object is to be deserialized.
 | 
			
		||||
   * @param classOfT the class of T
 | 
			
		||||
   * @return an object of type T from the string
 | 
			
		||||
   * @throws JsonIOException if there was a problem reading from the Reader
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
 | 
			
		||||
    JsonReader jsonReader = new JsonReader(json);
 | 
			
		||||
    Object object = fromJson(jsonReader, classOfT);
 | 
			
		||||
    assertFullConsumption(object, jsonReader);
 | 
			
		||||
    return Primitives.wrap(classOfT).cast(object);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the Json read from the specified reader into an object of the
 | 
			
		||||
   * specified type. This method is useful if the specified object is a generic type. For
 | 
			
		||||
   * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
 | 
			
		||||
   * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the reader producing Json from which the object is to be deserialized
 | 
			
		||||
   * @param typeOfT The specific genericized type of src. You can obtain this type by using the
 | 
			
		||||
   * {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example, to get the type for
 | 
			
		||||
   * {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @return an object of type T from the json
 | 
			
		||||
   * @throws JsonIOException if there was a problem reading from the Reader
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
 | 
			
		||||
    JsonReader jsonReader = new JsonReader(json);
 | 
			
		||||
    T object = this.<T>fromJson(jsonReader, typeOfT);
 | 
			
		||||
    assertFullConsumption(object, jsonReader);
 | 
			
		||||
    return object;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void assertFullConsumption(Object obj, JsonReader reader) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) {
 | 
			
		||||
        throw new JsonIOException("JSON document was not fully consumed.");
 | 
			
		||||
      }
 | 
			
		||||
    } catch (MalformedJsonException e) {
 | 
			
		||||
      throw new JsonSyntaxException(e);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new JsonIOException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Reads the next JSON value from {@code reader} and convert it to an object
 | 
			
		||||
   * of type {@code typeOfT}.
 | 
			
		||||
   * Since Type is not parameterized by T, this method is type unsafe and should be used carefully
 | 
			
		||||
   *
 | 
			
		||||
   * @throws JsonIOException if there was a problem writing to the Reader
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type
 | 
			
		||||
   */
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
 | 
			
		||||
    boolean oldLenient = reader.isLenient();
 | 
			
		||||
    reader.setLenient(true);
 | 
			
		||||
    try {
 | 
			
		||||
      JsonElement root = Streams.parse(reader);
 | 
			
		||||
      return (T) fromJson(root, typeOfT);
 | 
			
		||||
    } finally {
 | 
			
		||||
      reader.setLenient(oldLenient);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the Json read from the specified parse tree into an object of the
 | 
			
		||||
   * specified type. It is not suitable to use if the specified class is a generic type since it
 | 
			
		||||
   * will not have the generic type information because of the Type Erasure feature of Java.
 | 
			
		||||
   * Therefore, this method should not be used if the desired type is a generic type. Note that
 | 
			
		||||
   * this method works fine if the any of the fields of the specified object are generics, just the
 | 
			
		||||
   * object itself should not be a generic type. For the cases when the object is of generic type,
 | 
			
		||||
   * invoke {@link #fromJson(JsonElement, Type)}.
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
 | 
			
		||||
   * be deserialized
 | 
			
		||||
   * @param classOfT The class of T
 | 
			
		||||
   * @return an object of type T from the json
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
 | 
			
		||||
    Object object = fromJson(json, (Type) classOfT);
 | 
			
		||||
    return Primitives.wrap(classOfT).cast(object);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This method deserializes the Json read from the specified parse tree into an object of the
 | 
			
		||||
   * specified type. This method is useful if the specified object is a generic type. For
 | 
			
		||||
   * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type of the desired object
 | 
			
		||||
   * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
 | 
			
		||||
   * be deserialized
 | 
			
		||||
   * @param typeOfT The specific genericized type of src. You can obtain this type by using the
 | 
			
		||||
   * {@link com.bukkit.mcteam.gson.reflect.TypeToken} class. For example, to get the type for
 | 
			
		||||
   * {@code Collection<Foo>}, you should use:
 | 
			
		||||
   * <pre>
 | 
			
		||||
   * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
 | 
			
		||||
   * </pre>
 | 
			
		||||
   * @return an object of type T from the json
 | 
			
		||||
   * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException {
 | 
			
		||||
    if (json == null) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    JsonDeserializationContext context = new JsonDeserializationContextDefault(
 | 
			
		||||
        createDefaultObjectNavigatorFactory(deserializationStrategy), 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("{")
 | 
			
		||||
  	    .append("serializeNulls:").append(serializeNulls)
 | 
			
		||||
  	    .append(",serializers:").append(serializers)
 | 
			
		||||
  	    .append(",deserializers:").append(deserializers)
 | 
			
		||||
 | 
			
		||||
      	// using the name instanceCreator instead of ObjectConstructor since the users of Gson are
 | 
			
		||||
      	// more familiar with the concept of Instance Creators. Moreover, the objectConstructor is
 | 
			
		||||
      	// just a utility class around instance creators, and its toString() only displays them.
 | 
			
		||||
        .append(",instanceCreators:").append(objectConstructor)
 | 
			
		||||
        .append("}");
 | 
			
		||||
  	return sb.toString();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										570
									
								
								src/com/bukkit/mcteam/gson/GsonBuilder.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										570
									
								
								src/com/bukkit/mcteam/gson/GsonBuilder.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,570 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
 | 
			
		||||
 * options other than the default. For {@link Gson} with default configuration, it is simpler to
 | 
			
		||||
 * use {@code new Gson()}. {@code GsonBuilder} is best used by creating it, and then invoking its
 | 
			
		||||
 * various configuration methods, and finally calling create.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example shows how to use the {@code GsonBuilder} to construct a Gson
 | 
			
		||||
 * instance:
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Gson gson = new GsonBuilder()
 | 
			
		||||
 *     .registerTypeAdapter(Id.class, new IdTypeAdapter())
 | 
			
		||||
 *     .serializeNulls()
 | 
			
		||||
 *     .setDateFormat(DateFormat.LONG)
 | 
			
		||||
 *     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
 | 
			
		||||
 *     .setPrettyPrinting()
 | 
			
		||||
 *     .setVersion(1.0)
 | 
			
		||||
 *     .create();
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>NOTE: the order of invocation of configuration methods does not matter.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class GsonBuilder {
 | 
			
		||||
  private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
 | 
			
		||||
      new InnerClassExclusionStrategy();
 | 
			
		||||
  private static final ExposeAnnotationSerializationExclusionStrategy
 | 
			
		||||
    exposeAnnotationSerializationExclusionStrategy =
 | 
			
		||||
      new ExposeAnnotationSerializationExclusionStrategy();
 | 
			
		||||
  private static final ExposeAnnotationDeserializationExclusionStrategy
 | 
			
		||||
    exposeAnnotationDeserializationExclusionStrategy =
 | 
			
		||||
      new ExposeAnnotationDeserializationExclusionStrategy();
 | 
			
		||||
 | 
			
		||||
  private final Collection<ExclusionStrategy> exclusionStrategies =
 | 
			
		||||
      new HashSet<ExclusionStrategy>();
 | 
			
		||||
 | 
			
		||||
  private double ignoreVersionsAfter;
 | 
			
		||||
  private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
 | 
			
		||||
  private boolean serializeInnerClasses;
 | 
			
		||||
  private boolean excludeFieldsWithoutExposeAnnotation;
 | 
			
		||||
  private LongSerializationPolicy longSerializationPolicy;
 | 
			
		||||
  private FieldNamingStrategy2 fieldNamingPolicy;
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
 | 
			
		||||
  private boolean serializeNulls;
 | 
			
		||||
  private String datePattern;
 | 
			
		||||
  private int dateStyle;
 | 
			
		||||
  private int timeStyle;
 | 
			
		||||
  private boolean serializeSpecialFloatingPointValues;
 | 
			
		||||
  private boolean escapeHtmlChars;
 | 
			
		||||
  private boolean prettyPrinting;
 | 
			
		||||
  private boolean generateNonExecutableJson;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a GsonBuilder instance that can be used to build Gson with various configuration
 | 
			
		||||
   * settings. GsonBuilder follows the builder pattern, and it is typically used by first
 | 
			
		||||
   * invoking various configuration methods to set desired options, and finally calling
 | 
			
		||||
   * {@link #create()}.
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder() {
 | 
			
		||||
    // add default exclusion strategies
 | 
			
		||||
    exclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
 | 
			
		||||
    exclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
 | 
			
		||||
 | 
			
		||||
    // setup default values
 | 
			
		||||
    ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
 | 
			
		||||
    serializeInnerClasses = true;
 | 
			
		||||
    prettyPrinting = false;
 | 
			
		||||
    escapeHtmlChars = true;
 | 
			
		||||
    modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
 | 
			
		||||
    excludeFieldsWithoutExposeAnnotation = false;
 | 
			
		||||
    longSerializationPolicy = LongSerializationPolicy.DEFAULT;
 | 
			
		||||
    fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY;
 | 
			
		||||
    instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
 | 
			
		||||
    serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
 | 
			
		||||
    deserializers = new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
 | 
			
		||||
    serializeNulls = false;
 | 
			
		||||
    dateStyle = DateFormat.DEFAULT;
 | 
			
		||||
    timeStyle = DateFormat.DEFAULT;
 | 
			
		||||
    serializeSpecialFloatingPointValues = false;
 | 
			
		||||
    generateNonExecutableJson = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to enable versioning support.
 | 
			
		||||
   *
 | 
			
		||||
   * @param ignoreVersionsAfter any field or type marked with a version higher than this value
 | 
			
		||||
   * are ignored during serialization or deserialization.
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setVersion(double ignoreVersionsAfter) {
 | 
			
		||||
    this.ignoreVersionsAfter = ignoreVersionsAfter;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to excludes all class fields that have the specified modifiers. By default,
 | 
			
		||||
   * Gson will exclude all fields marked transient or static. This method will override that
 | 
			
		||||
   * behavior.
 | 
			
		||||
   *
 | 
			
		||||
   * @param modifiers the field modifiers. You must use the modifiers specified in the
 | 
			
		||||
   * {@link java.lang.reflect.Modifier} class. For example,
 | 
			
		||||
   * {@link java.lang.reflect.Modifier#TRANSIENT},
 | 
			
		||||
   * {@link java.lang.reflect.Modifier#STATIC}.
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
 | 
			
		||||
    modifierBasedExclusionStrategy = new ModifierBasedExclusionStrategy(modifiers);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Makes the output JSON non-executable in Javascript by prefixing the generated JSON with some
 | 
			
		||||
   * special text. This prevents attacks from third-party sites through script sourcing. See
 | 
			
		||||
   * <a href="http://code.google.com/p/google-gson/issues/detail?id=42">Gson Issue 42</a>
 | 
			
		||||
   * for details.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder generateNonExecutableJson() {
 | 
			
		||||
    this.generateNonExecutableJson = true;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to exclude all fields from consideration for serialization or deserialization
 | 
			
		||||
   * that do not have the {@link com.bukkit.mcteam.gson.annotations.Expose} annotation.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
 | 
			
		||||
    excludeFieldsWithoutExposeAnnotation = true;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure Gson to serialize null fields. By default, Gson omits all fields that are null
 | 
			
		||||
   * during serialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder serializeNulls() {
 | 
			
		||||
    this.serializeNulls = true;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to exclude inner classes during serialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder disableInnerClassSerialization() {
 | 
			
		||||
    serializeInnerClasses = false;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to apply a specific serialization policy for {@code Long} and {@code long}
 | 
			
		||||
   * objects.
 | 
			
		||||
   *
 | 
			
		||||
   * @param serializationPolicy the particular policy to use for serializing longs.
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
 | 
			
		||||
    this.longSerializationPolicy = serializationPolicy;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to apply a specific naming policy to an object's field during serialization
 | 
			
		||||
   * and deserialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @param namingConvention the JSON field naming convention to use for serialization and
 | 
			
		||||
   * deserialization.
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
 | 
			
		||||
    return setFieldNamingStrategy(namingConvention.getFieldNamingPolicy());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to apply a specific naming policy strategy to an object's field during
 | 
			
		||||
   * serialization and deserialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @param fieldNamingStrategy the actual naming strategy to apply to the fields
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
 | 
			
		||||
    return setFieldNamingStrategy(new FieldNamingStrategy2Adapter(fieldNamingStrategy));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to apply a specific naming policy strategy to an object's field during
 | 
			
		||||
   * serialization and deserialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @param fieldNamingStrategy the actual naming strategy to apply to the fields
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  GsonBuilder setFieldNamingStrategy(FieldNamingStrategy2 fieldNamingStrategy) {
 | 
			
		||||
    this.fieldNamingPolicy =
 | 
			
		||||
        new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingStrategy);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to apply a set of exclusion strategies during both serialization and
 | 
			
		||||
   * deserialization. Each of the {@code strategies} will be applied as a disjunction rule.
 | 
			
		||||
   * This means that if one of the {@code strategies} suggests that a field (or class) should be
 | 
			
		||||
   * skipped then that field (or object) is skipped during serializaiton/deserialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @param strategies the set of strategy object to apply during object (de)serialization.
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
 | 
			
		||||
    for (ExclusionStrategy strategy : strategies) {
 | 
			
		||||
      exclusionStrategies.add(strategy);
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to output Json that fits in a page for pretty printing. This option only
 | 
			
		||||
   * affects Json serialization.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setPrettyPrinting() {
 | 
			
		||||
    prettyPrinting = true;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * By default, Gson escapes HTML characters such as < > etc. Use this option to configure
 | 
			
		||||
   * Gson to pass-through HTML characters as is.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder disableHtmlEscaping() {
 | 
			
		||||
    this.escapeHtmlChars = false;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to serialize {@code Date} objects according to the pattern provided. You can
 | 
			
		||||
   * call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
 | 
			
		||||
   * will be used to decide the serialization format.
 | 
			
		||||
   *
 | 
			
		||||
   * <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>
 | 
			
		||||
   *
 | 
			
		||||
   * @param pattern the pattern that dates will be serialized/deserialized to/from
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setDateFormat(String pattern) {
 | 
			
		||||
    // TODO(Joel): Make this fail fast if it is an invalid date format
 | 
			
		||||
    this.datePattern = pattern;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to to serialize {@code Date} objects according to the style value provided.
 | 
			
		||||
   * You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
 | 
			
		||||
   * invocation will be used to decide the serialization format.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Note that this style value should be one of the predefined constants in the
 | 
			
		||||
   * {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
 | 
			
		||||
   * information on the valid style constants.</p>
 | 
			
		||||
   *
 | 
			
		||||
   * @param style the predefined date style that date objects will be serialized/deserialized
 | 
			
		||||
   * to/from
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setDateFormat(int style) {
 | 
			
		||||
    this.dateStyle = style;
 | 
			
		||||
    this.datePattern = null;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to to serialize {@code Date} objects according to the style value provided.
 | 
			
		||||
   * You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
 | 
			
		||||
   * invocation will be used to decide the serialization format.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Note that this style value should be one of the predefined constants in the
 | 
			
		||||
   * {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
 | 
			
		||||
   * information on the valid style constants.</p>
 | 
			
		||||
   *
 | 
			
		||||
   * @param dateStyle the predefined date style that date objects will be serialized/deserialized
 | 
			
		||||
   * to/from
 | 
			
		||||
   * @param timeStyle the predefined style for the time portion of the date objects
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
 | 
			
		||||
    this.dateStyle = dateStyle;
 | 
			
		||||
    this.timeStyle = timeStyle;
 | 
			
		||||
    this.datePattern = null;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson for custom serialization or deserialization. This method combines the
 | 
			
		||||
   * registration of an {@link InstanceCreator}, {@link JsonSerializer}, and a
 | 
			
		||||
   * {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements
 | 
			
		||||
   * all the required interfaces for custom serialization with Gson. If an instance creator,
 | 
			
		||||
   * serializer or deserializer was previously registered for the specified {@code type}, it is
 | 
			
		||||
   * overwritten.
 | 
			
		||||
   *
 | 
			
		||||
   * @param type the type definition for the type adapter being registered
 | 
			
		||||
   * @param typeAdapter This object must implement at least one of the {@link InstanceCreator},
 | 
			
		||||
   * {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
 | 
			
		||||
   * @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<?>
 | 
			
		||||
        || typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
 | 
			
		||||
    if (typeAdapter instanceof InstanceCreator<?>) {
 | 
			
		||||
      registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    if (typeAdapter instanceof JsonSerializer<?>) {
 | 
			
		||||
      registerSerializer(type, (JsonSerializer<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    if (typeAdapter instanceof JsonDeserializer<?>) {
 | 
			
		||||
      registerDeserializer(type, (JsonDeserializer<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to use a custom {@link InstanceCreator} for the specified type. If an instance
 | 
			
		||||
   * creator was previously registered for the specified class, it is overwritten. Since this method
 | 
			
		||||
   * takes a type instead of a Class object, it can be used to register a specific handler for a
 | 
			
		||||
   * generic type corresponding to a raw type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type for which instance creator is being registered
 | 
			
		||||
   * @param typeOfT The Type definition for T
 | 
			
		||||
   * @param instanceCreator the instance creator for T
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  private <T> GsonBuilder registerInstanceCreator(Type typeOfT,
 | 
			
		||||
      InstanceCreator<? extends T> instanceCreator) {
 | 
			
		||||
    instanceCreators.register(typeOfT, instanceCreator);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to use a custom JSON serializer for the specified type. You should use this
 | 
			
		||||
   * method if you want to register different serializers for different generic types corresponding
 | 
			
		||||
   * to a raw type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type for which the serializer is being registered
 | 
			
		||||
   * @param typeOfT The type definition for T
 | 
			
		||||
   * @param serializer the custom serializer
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  private <T> GsonBuilder registerSerializer(Type typeOfT, final JsonSerializer<T> serializer) {
 | 
			
		||||
    serializers.register(typeOfT, serializer);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson to use a custom JSON deserializer for the specified type. You should use this
 | 
			
		||||
   * method if you want to register different deserializers for different generic types
 | 
			
		||||
   * corresponding to a raw type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param <T> the type for which the deserializer is being registered
 | 
			
		||||
   * @param typeOfT The type definition for T
 | 
			
		||||
   * @param deserializer the custom deserializer
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   */
 | 
			
		||||
  private <T> GsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer<T> deserializer) {
 | 
			
		||||
    deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper<T>(deserializer));
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configures Gson for custom serialization or deserialization for an inheritance type hierarchy.
 | 
			
		||||
   * This method combines the registration of an {@link InstanceCreator}, {@link JsonSerializer},
 | 
			
		||||
   * and a {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter}
 | 
			
		||||
   * implements all the required interfaces for custom serialization with Gson.
 | 
			
		||||
   * If an instance creator, serializer or deserializer was previously registered for the specified
 | 
			
		||||
   * type hierarchy, it is overwritten. If an instance creator, serializer or deserializer is
 | 
			
		||||
   * registered for a specific type in the type hierarchy, it will be invoked instead of the one
 | 
			
		||||
   * registered for the type hierarchy.
 | 
			
		||||
   *
 | 
			
		||||
   * @param baseType the class definition for the type adapter being registered for the base class
 | 
			
		||||
   *        or interface
 | 
			
		||||
   * @param typeAdapter This object must implement at least one of the {@link InstanceCreator},
 | 
			
		||||
   * {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
 | 
			
		||||
   * @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<?>
 | 
			
		||||
    || typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
 | 
			
		||||
    if (typeAdapter instanceof InstanceCreator<?>) {
 | 
			
		||||
      registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    if (typeAdapter instanceof JsonSerializer<?>) {
 | 
			
		||||
      registerSerializerForTypeHierarchy(baseType, (JsonSerializer<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    if (typeAdapter instanceof JsonDeserializer<?>) {
 | 
			
		||||
      registerDeserializerForTypeHierarchy(baseType, (JsonDeserializer<?>) typeAdapter);
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private <T> GsonBuilder registerInstanceCreatorForTypeHierarchy(Class<?> classOfT,
 | 
			
		||||
      InstanceCreator<? extends T> instanceCreator) {
 | 
			
		||||
    instanceCreators.registerForTypeHierarchy(classOfT, instanceCreator);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private <T> GsonBuilder registerSerializerForTypeHierarchy(Class<?> classOfT,
 | 
			
		||||
      final JsonSerializer<T> serializer) {
 | 
			
		||||
    serializers.registerForTypeHierarchy(classOfT, serializer);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private <T> GsonBuilder registerDeserializerForTypeHierarchy(Class<?> classOfT,
 | 
			
		||||
      JsonDeserializer<T> deserializer) {
 | 
			
		||||
    deserializers.registerForTypeHierarchy(classOfT,
 | 
			
		||||
        new JsonDeserializerExceptionWrapper<T>(deserializer));
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Section 2.4 of <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON specification</a> disallows
 | 
			
		||||
   * special double values (NaN, Infinity, -Infinity). However,
 | 
			
		||||
   * <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">Javascript
 | 
			
		||||
   * specification</a> (see section 4.3.20, 4.3.22, 4.3.23) allows these values as valid Javascript
 | 
			
		||||
   * values. Moreover, most JavaScript engines will accept these special values in JSON without
 | 
			
		||||
   * problem. So, at a practical level, it makes sense to accept these values as valid JSON even
 | 
			
		||||
   * though JSON specification disallows them.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>Gson always accepts these special values during deserialization. However, it outputs
 | 
			
		||||
   * strictly compliant JSON. Hence, if it encounters a float value {@link Float#NaN},
 | 
			
		||||
   * {@link Float#POSITIVE_INFINITY}, {@link Float#NEGATIVE_INFINITY}, or a double value
 | 
			
		||||
   * {@link Double#NaN}, {@link Double#POSITIVE_INFINITY}, {@link Double#NEGATIVE_INFINITY}, it
 | 
			
		||||
   * will throw an {@link IllegalArgumentException}. This method provides a way to override the
 | 
			
		||||
   * default behavior when you know that the JSON receiver will be able to handle these special
 | 
			
		||||
   * values.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public GsonBuilder serializeSpecialFloatingPointValues() {
 | 
			
		||||
    this.serializeSpecialFloatingPointValues = true;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a {@link Gson} instance based on the current configuration. This method is free of
 | 
			
		||||
   * side-effects to this {@code GsonBuilder} instance and hence can be called multiple times.
 | 
			
		||||
   *
 | 
			
		||||
   * @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);
 | 
			
		||||
    deserializationStrategies.add(modifierBasedExclusionStrategy);
 | 
			
		||||
 | 
			
		||||
    if (!serializeInnerClasses) {
 | 
			
		||||
      serializationStrategies.add(innerClassExclusionStrategy);
 | 
			
		||||
      deserializationStrategies.add(innerClassExclusionStrategy);
 | 
			
		||||
    }
 | 
			
		||||
    if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
 | 
			
		||||
      serializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
 | 
			
		||||
      deserializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
 | 
			
		||||
    }
 | 
			
		||||
    if (excludeFieldsWithoutExposeAnnotation) {
 | 
			
		||||
      serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
 | 
			
		||||
      deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
 | 
			
		||||
    }
 | 
			
		||||
    ExclusionStrategy serializationExclusionStrategy =
 | 
			
		||||
      new DisjunctionExclusionStrategy(serializationStrategies);
 | 
			
		||||
    ExclusionStrategy deserializationExclusionStrategy =
 | 
			
		||||
      new DisjunctionExclusionStrategy(deserializationStrategies);
 | 
			
		||||
 | 
			
		||||
    ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers = serializers.copyOf();
 | 
			
		||||
    ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers = deserializers.copyOf();
 | 
			
		||||
    addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
 | 
			
		||||
        customDeserializers);
 | 
			
		||||
 | 
			
		||||
    customSerializers.registerIfAbsent(DefaultTypeAdapters.getDefaultSerializers(
 | 
			
		||||
        serializeSpecialFloatingPointValues, longSerializationPolicy));
 | 
			
		||||
 | 
			
		||||
    customDeserializers.registerIfAbsent(DefaultTypeAdapters.getDefaultDeserializers());
 | 
			
		||||
 | 
			
		||||
    ParameterizedTypeHandlerMap<InstanceCreator<?>> customInstanceCreators =
 | 
			
		||||
        instanceCreators.copyOf();
 | 
			
		||||
    customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.getDefaultInstanceCreators());
 | 
			
		||||
 | 
			
		||||
    customSerializers.makeUnmodifiable();
 | 
			
		||||
    customDeserializers.makeUnmodifiable();
 | 
			
		||||
    instanceCreators.makeUnmodifiable();
 | 
			
		||||
 | 
			
		||||
    MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
 | 
			
		||||
 | 
			
		||||
    Gson gson = new Gson(serializationExclusionStrategy, deserializationExclusionStrategy,
 | 
			
		||||
        fieldNamingPolicy, objConstructor, serializeNulls, customSerializers,
 | 
			
		||||
        customDeserializers, generateNonExecutableJson, escapeHtmlChars, prettyPrinting);
 | 
			
		||||
    return gson;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
 | 
			
		||||
    DefaultDateTypeAdapter dateTypeAdapter = null;
 | 
			
		||||
    if (datePattern != null && !"".equals(datePattern.trim())) {
 | 
			
		||||
      dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
 | 
			
		||||
    } else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
 | 
			
		||||
      dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dateTypeAdapter != null) {
 | 
			
		||||
      if (!serializers.hasSpecificHandlerFor(Date.class)) {
 | 
			
		||||
        serializers.register(Date.class, dateTypeAdapter);
 | 
			
		||||
      }
 | 
			
		||||
      if (!deserializers.hasSpecificHandlerFor(Date.class)) {
 | 
			
		||||
        deserializers.register(Date.class, dateTypeAdapter);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								src/com/bukkit/mcteam/gson/InnerClassExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/com/bukkit/mcteam/gson/InnerClassExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Modifier;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Strategy for excluding inner classes.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
class InnerClassExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    return isInnerClass(f.getDeclaredClass());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return isInnerClass(clazz);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isInnerClass(Class<?> clazz) {
 | 
			
		||||
    return clazz.isMemberClass() && !isStatic(clazz);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isStatic(Class<?> clazz) {
 | 
			
		||||
    return (clazz.getModifiers() & Modifier.STATIC) != 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/com/bukkit/mcteam/gson/InstanceCreator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/com/bukkit/mcteam/gson/InstanceCreator.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This interface is implemented to create instances of a class that does not define a no-args
 | 
			
		||||
 * constructor. If you can modify the class, you should instead add a private, or public
 | 
			
		||||
 * no-args constructor. However, that is not possible for library classes, such as JDK classes, or
 | 
			
		||||
 * a third-party library that you do not have source-code of. In such cases, you should define an
 | 
			
		||||
 * instance creator for the class. Implementations of this interface should be registered with
 | 
			
		||||
 * {@link GsonBuilder#registerTypeAdapter(Type, Object)} method before Gson will be able to use
 | 
			
		||||
 * them.
 | 
			
		||||
 * <p>Let us look at an example where defining an InstanceCreator might be useful. The
 | 
			
		||||
 * {@code Id} class defined below does not have a default no-args constructor.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class Id<T> {
 | 
			
		||||
 *   private final Class<T> clazz;
 | 
			
		||||
 *   private final long value;
 | 
			
		||||
 *   public Id(Class<T> clazz, long value) {
 | 
			
		||||
 *     this.clazz = clazz;
 | 
			
		||||
 *     this.value = value;
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>If Gson encounters an object of type {@code Id} during deserialization, it will throw an
 | 
			
		||||
 * exception. The easiest way to solve this problem will be to add a (public or private) no-args
 | 
			
		||||
 * constructor as follows:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * private Id() {
 | 
			
		||||
 *   this(Object.class, 0L);
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>However, let us assume that the developer does not have access to the source-code of the
 | 
			
		||||
 * {@code Id} class, or does not want to define a no-args constructor for it. The developer
 | 
			
		||||
 * can solve this problem by defining an {@code InstanceCreator} for {@code Id}:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IdInstanceCreator implements InstanceCreator<Id> {
 | 
			
		||||
 *   public Id createInstance(Type type) {
 | 
			
		||||
 *     return new Id(Object.class, 0L);
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Note that it does not matter what the fields of the created instance contain since Gson will
 | 
			
		||||
 * overwrite them with the deserialized values specified in Json. You should also ensure that a
 | 
			
		||||
 * <i>new</i> object is returned, not a common object since its fields will be overwritten.
 | 
			
		||||
 * The developer will need to register {@code IdInstanceCreator} with Gson as follows:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdInstanceCreator()).create();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> the type of object that will be created by this implementation.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public interface InstanceCreator<T> {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gson invokes this call-back method during deserialization to create an instance of the
 | 
			
		||||
   * specified type. The fields of the returned instance are overwritten with the data present
 | 
			
		||||
   * in the Json. Since the prior contents of the object are destroyed and overwritten, do not
 | 
			
		||||
   * return an instance that is useful elsewhere. In particular, do not return a common instance,
 | 
			
		||||
   * always use {@code new} to create a new instance.
 | 
			
		||||
   *
 | 
			
		||||
   * @param type the parameterized T represented as a {@link Type}.
 | 
			
		||||
   * @return a default object instance of type T.
 | 
			
		||||
   */
 | 
			
		||||
  public T createInstance(Type type);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								src/com/bukkit/mcteam/gson/JavaFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/com/bukkit/mcteam/gson/JavaFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple implementation of the {@link FieldNamingStrategy2} interface such that it does not
 | 
			
		||||
 * perform any string translation of the incoming field name.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IntWrapper {
 | 
			
		||||
 *   public int integerField = 0;
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * JavaFieldNamingPolicy policy = new JavaFieldNamingPolicy();
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(IntWrapper.class.getField("integerField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("integerField".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This is the default {@link FieldNamingStrategy2} used by Gson.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class JavaFieldNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
 | 
			
		||||
    return target;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										312
									
								
								src/com/bukkit/mcteam/gson/JsonArray.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								src/com/bukkit/mcteam/gson/JsonArray.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,312 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representing an array type in Json. An array is a list of {@link JsonElement}s each of
 | 
			
		||||
 * which can be of a different type. This is an ordered list, meaning that the order in which
 | 
			
		||||
 * elements are added is preserved.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
 | 
			
		||||
  private final List<JsonElement> elements;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates an empty JsonArray.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonArray() {
 | 
			
		||||
    elements = new ArrayList<JsonElement>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adds the specified element to self.
 | 
			
		||||
   *
 | 
			
		||||
   * @param element the element that needs to be added to the array.
 | 
			
		||||
   */
 | 
			
		||||
  public void add(JsonElement element) {
 | 
			
		||||
    if (element == null) {
 | 
			
		||||
      element = JsonNull.createJsonNull();
 | 
			
		||||
    }
 | 
			
		||||
    elements.add(element);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adds all the elements of the specified array to self.
 | 
			
		||||
   *
 | 
			
		||||
   * @param array the array whose elements need to be added to the array.
 | 
			
		||||
   */
 | 
			
		||||
  public void addAll(JsonArray array) {
 | 
			
		||||
    elements.addAll(array.elements);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Reverses the elements of the array.
 | 
			
		||||
   */
 | 
			
		||||
  void reverse() {
 | 
			
		||||
    Collections.reverse(elements);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the number of elements in the array.
 | 
			
		||||
   *
 | 
			
		||||
   * @return the number of elements in the array.
 | 
			
		||||
   */
 | 
			
		||||
  public int size() {
 | 
			
		||||
    return elements.size();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns an iterator to navigate the elemetns of the array. Since the array is an ordered list,
 | 
			
		||||
   * the iterator navigates the elements in the order they were inserted.
 | 
			
		||||
   *
 | 
			
		||||
   * @return an iterator to navigate the elements of the array.
 | 
			
		||||
   */
 | 
			
		||||
  public Iterator<JsonElement> iterator() {
 | 
			
		||||
    return elements.iterator();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the ith element of the array.
 | 
			
		||||
   *
 | 
			
		||||
   * @param i the index of the element that is being sought.
 | 
			
		||||
   * @return the element present at the ith index.
 | 
			
		||||
   * @throws IndexOutOfBoundsException if i is negative or greater than or equal to the
 | 
			
		||||
   * {@link #size()} of the array.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement get(int i) {
 | 
			
		||||
    return elements.get(i);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a {@link Number} if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a number if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid Number.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public Number getAsNumber() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsNumber();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a {@link String} if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a String if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid String.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getAsString() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsString();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a double if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a double if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid double.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public double getAsDouble() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsDouble();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a {@link BigDecimal} if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigDecimal} if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive}.
 | 
			
		||||
   * @throws NumberFormatException if the element at index 0 is not a valid {@link BigDecimal}.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public BigDecimal getAsBigDecimal() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsBigDecimal();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a {@link BigInteger} if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigInteger} if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive}.
 | 
			
		||||
   * @throws NumberFormatException if the element at index 0 is not a valid {@link BigInteger}.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public BigInteger getAsBigInteger() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsBigInteger();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a float if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a float if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid float.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public float getAsFloat() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsFloat();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a long if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a long if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid long.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public long getAsLong() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsLong();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as an integer if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as an integer if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid integer.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getAsInt() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsInt();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public byte getAsByte() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsByte();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public char getAsCharacter() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsCharacter();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a primitive short if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive short if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid short.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public short getAsShort() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsShort();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as a boolean if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a boolean if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid boolean.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean getAsBoolean() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsBoolean();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this array as an Object if it contains a single element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as an Object if it is single element array.
 | 
			
		||||
   * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and
 | 
			
		||||
   * is not a valid Object.
 | 
			
		||||
   * @throws IllegalStateException if the array has more than one element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  Object getAsObject() {
 | 
			
		||||
    if (elements.size() == 1) {
 | 
			
		||||
      return elements.get(0).getAsObject();
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void toString(Appendable sb, Escaper escaper) throws IOException {
 | 
			
		||||
    sb.append('[');
 | 
			
		||||
    boolean first = true;
 | 
			
		||||
    for (JsonElement element : elements) {
 | 
			
		||||
      if (first) {
 | 
			
		||||
        first = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        sb.append(',');
 | 
			
		||||
      }
 | 
			
		||||
      element.toString(sb, escaper);
 | 
			
		||||
    }
 | 
			
		||||
    sb.append(']');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								src/com/bukkit/mcteam/gson/JsonArrayDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/com/bukkit/mcteam/gson/JsonArrayDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A visitor that populates fields of an object with data from its equivalent
 | 
			
		||||
 * JSON representation
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class JsonArrayDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
 | 
			
		||||
 | 
			
		||||
  JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType,
 | 
			
		||||
      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
 | 
			
		||||
      JsonDeserializationContext context) {
 | 
			
		||||
    super(jsonArray, arrayType, factory, 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);
 | 
			
		||||
      // We know that we are getting back an array of the required type, so
 | 
			
		||||
      // this typecasting is safe.
 | 
			
		||||
      return (T) objectConstructor.constructArray(arrayTypeInfo.getSecondLevelType(),
 | 
			
		||||
          jsonArray.size());
 | 
			
		||||
    }
 | 
			
		||||
    // is a collection
 | 
			
		||||
    return (T) objectConstructor.construct(typeInfo.getRawClass());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArray(Object array, Type arrayType) {
 | 
			
		||||
    if (!json.isJsonArray()) {
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
      if (jsonChild == null || jsonChild.isJsonNull()) {
 | 
			
		||||
        child = null;
 | 
			
		||||
      } else if (jsonChild instanceof JsonObject) {
 | 
			
		||||
        child = visitChildAsObject(arrayTypeInfo.getComponentRawType(), jsonChild);
 | 
			
		||||
      } else if (jsonChild instanceof JsonArray) {
 | 
			
		||||
        child = visitChildAsArray(arrayTypeInfo.getSecondLevelType(), jsonChild.getAsJsonArray());
 | 
			
		||||
      } else if (jsonChild instanceof JsonPrimitive) {
 | 
			
		||||
        child = visitChildAsObject(arrayTypeInfo.getComponentRawType(),
 | 
			
		||||
            jsonChild.getAsJsonPrimitive());
 | 
			
		||||
      } else {
 | 
			
		||||
        throw new IllegalStateException();
 | 
			
		||||
      }
 | 
			
		||||
      Array.set(array, i, child);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We should not implement any other method from Visitor interface since
 | 
			
		||||
  // all other methods should be invoked on JsonObjectDeserializationVisitor
 | 
			
		||||
  // instead.
 | 
			
		||||
 | 
			
		||||
  public void startVisitingObject(Object node) {
 | 
			
		||||
    throw new JsonParseException("Expecting array but found object: " + node);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    throw new JsonParseException("Expecting array but found array field " + f.getName() + ": "
 | 
			
		||||
        + obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    throw new JsonParseException("Expecting array but found object field " + f.getName() + ": " 
 | 
			
		||||
        + obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField, Object parent) {
 | 
			
		||||
    throw new JsonParseException("Expecting array but found field " + f.getName() + ": " 
 | 
			
		||||
        + parent);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitPrimitive(Object primitive) {
 | 
			
		||||
    throw new JsonParseException(
 | 
			
		||||
        "Type information is unavailable, and the target is not a primitive: " + json);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializationContext.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializationContext.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Context for deserialization that is passed to a custom deserializer during invocation of its 
 | 
			
		||||
 * {@link JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)}
 | 
			
		||||
 * method. 
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public interface JsonDeserializationContext {
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Invokes default deserialization on the specified object. It should never be invoked on 
 | 
			
		||||
   * the element received as a parameter of the 
 | 
			
		||||
   * {@link JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)} method. Doing
 | 
			
		||||
   * so will result in an infinite loop since Gson will in-turn call the custom deserializer again. 
 | 
			
		||||
 | 
			
		||||
   * @param json the parse tree.
 | 
			
		||||
   * @param typeOfT type of the expected return value.
 | 
			
		||||
   * @param <T> The type of the deserialized object.
 | 
			
		||||
   * @return An object of type typeOfT.
 | 
			
		||||
   * @throws JsonParseException if the parse tree does not contain expected data.
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * implementation of a deserialization context for Gson
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 */
 | 
			
		||||
final class JsonDeserializationContextDefault implements JsonDeserializationContext {
 | 
			
		||||
 | 
			
		||||
  private final ObjectNavigatorFactory navigatorFactory;
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
 | 
			
		||||
  private final MappedObjectConstructor objectConstructor;
 | 
			
		||||
 | 
			
		||||
  JsonDeserializationContextDefault(ObjectNavigatorFactory navigatorFactory,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
 | 
			
		||||
      MappedObjectConstructor objectConstructor) {
 | 
			
		||||
    this.navigatorFactory = navigatorFactory;
 | 
			
		||||
    this.deserializers = deserializers;
 | 
			
		||||
    this.objectConstructor = objectConstructor;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ObjectConstructor getObjectConstructor() {
 | 
			
		||||
    return objectConstructor;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
 | 
			
		||||
    if (json == null || json.isJsonNull()) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else if (json.isJsonArray()) {
 | 
			
		||||
      return (T) fromJsonArray(typeOfT, json.getAsJsonArray(), this);
 | 
			
		||||
    } else if (json.isJsonObject()) {
 | 
			
		||||
      return (T) fromJsonObject(typeOfT, json.getAsJsonObject(), this);
 | 
			
		||||
    } else if (json.isJsonPrimitive()) {
 | 
			
		||||
      return (T) fromJsonPrimitive(typeOfT, json.getAsJsonPrimitive(), this);
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
    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);
 | 
			
		||||
    return visitor.getTarget();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  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);
 | 
			
		||||
    Object target = visitor.getTarget();
 | 
			
		||||
    return (T) target;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract data value container for the {@link ObjectNavigator.Visitor}
 | 
			
		||||
 * implementations.  This class exposes the {@link #getTarget()} method
 | 
			
		||||
 * which returns the class that was visited by this object.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor {
 | 
			
		||||
 | 
			
		||||
  protected final ObjectNavigatorFactory factory;
 | 
			
		||||
  protected final ObjectConstructor objectConstructor;
 | 
			
		||||
  protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
 | 
			
		||||
  protected T target;
 | 
			
		||||
  protected final JsonElement json;
 | 
			
		||||
  protected final Type targetType;
 | 
			
		||||
  protected final JsonDeserializationContext context;
 | 
			
		||||
  protected boolean constructed;
 | 
			
		||||
 | 
			
		||||
  public JsonDeserializationVisitor(JsonElement json, Type targetType,
 | 
			
		||||
      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
 | 
			
		||||
      JsonDeserializationContext context) {
 | 
			
		||||
    Preconditions.checkNotNull(json);
 | 
			
		||||
    this.targetType = targetType;
 | 
			
		||||
    this.factory = factory;
 | 
			
		||||
    this.objectConstructor = objectConstructor;
 | 
			
		||||
    this.deserializers = deserializers;
 | 
			
		||||
    this.json = json;
 | 
			
		||||
    this.context = context;
 | 
			
		||||
    this.constructed = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public T getTarget() {
 | 
			
		||||
    if (!constructed) {
 | 
			
		||||
      target = constructTarget();
 | 
			
		||||
      constructed = true;
 | 
			
		||||
    }
 | 
			
		||||
    return target;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected abstract T constructTarget();
 | 
			
		||||
 | 
			
		||||
  public void start(ObjectTypePair node) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void end(ObjectTypePair node) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public final boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
 | 
			
		||||
    Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
 | 
			
		||||
    if (pair == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }    
 | 
			
		||||
    Object value = invokeCustomDeserializer(json, pair);
 | 
			
		||||
    target = (T) value;
 | 
			
		||||
    constructed = true;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected Object invokeCustomDeserializer(JsonElement element, 
 | 
			
		||||
      Pair<JsonDeserializer<?>, ObjectTypePair> pair) {
 | 
			
		||||
    if (element == null || element.isJsonNull()) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    Type objType = pair.second.type;
 | 
			
		||||
    return (pair.first).deserialize(element, objType, context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  final Object visitChildAsObject(Type childType, JsonElement jsonChild) {
 | 
			
		||||
    JsonDeserializationVisitor<?> childVisitor =
 | 
			
		||||
        new JsonObjectDeserializationVisitor<Object>(jsonChild, childType,
 | 
			
		||||
            factory, 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);
 | 
			
		||||
    return visitChild(childType, childVisitor);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
 | 
			
		||||
    ObjectNavigator on = factory.create(new ObjectTypePair(null, type, false));
 | 
			
		||||
    on.accept(childVisitor);
 | 
			
		||||
    // the underlying object may have changed during the construction phase
 | 
			
		||||
    // This happens primarily because of custom deserializers
 | 
			
		||||
    return childVisitor.getTarget();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializer.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/com/bukkit/mcteam/gson/JsonDeserializer.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * <p>Interface representing a custom deserializer for Json. You should write a custom
 | 
			
		||||
 * deserializer, if you are not happy with the default deserialization done by Gson. You will
 | 
			
		||||
 * also need to register this deserializer through
 | 
			
		||||
 * {@link GsonBuilder#registerTypeAdapter(Type, Object)}.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Let us look at example where defining a deserializer will be useful. The {@code Id} class
 | 
			
		||||
 * defined below has two fields: {@code clazz} and {@code value}.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class Id<T> {
 | 
			
		||||
 *   private final Class<T> clazz;
 | 
			
		||||
 *   private final long value;
 | 
			
		||||
 *   public Id(Class<T> clazz, long value) {
 | 
			
		||||
 *     this.clazz = clazz;
 | 
			
		||||
 *     this.value = value;
 | 
			
		||||
 *   }
 | 
			
		||||
 *   public long getValue() {
 | 
			
		||||
 *     return value;
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The default deserialization of {@code Id(com.foo.MyObject.class, 20L)} will require the
 | 
			
		||||
 * Json string to be <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you already know
 | 
			
		||||
 * the type of the field that the {@code Id} will be deserialized into, and hence just want to
 | 
			
		||||
 * deserialize it from a Json string {@code 20}. You can achieve that by writing a custom
 | 
			
		||||
 * deserializer:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IdDeserializer implements JsonDeserializer<Id>() {
 | 
			
		||||
 *   public Id fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
 *       throws JsonParseException {
 | 
			
		||||
 *     return (Id) new Id((Class)typeOfT, id.getValue());
 | 
			
		||||
 *   }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>You will also need to register {@code IdDeserializer} with Gson as follows:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> type for which the deserializer is being registered. It is possible that a
 | 
			
		||||
 * deserializer may be asked to deserialize a specific generic type of the T.
 | 
			
		||||
 */
 | 
			
		||||
public interface JsonDeserializer<T> {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gson invokes this call-back method during deserialization when it encounters a field of the
 | 
			
		||||
   * specified type.
 | 
			
		||||
   * <p>In the implementation of this call-back method, you should consider invoking
 | 
			
		||||
   * {@link JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects
 | 
			
		||||
   * for any non-trivial field of the returned object. However, you should never invoke it on the
 | 
			
		||||
   * the same type passing {@code json} since that will cause an infinite loop (Gson will call your
 | 
			
		||||
   * call-back method again).
 | 
			
		||||
   *
 | 
			
		||||
   * @param json The Json data being deserialized
 | 
			
		||||
   * @param typeOfT The type of the Object to deserialize to
 | 
			
		||||
   * @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
 | 
			
		||||
   * @throws JsonParseException if json is not in the expected format of {@code typeofT}
 | 
			
		||||
   */
 | 
			
		||||
  public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
      throws JsonParseException;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decorators a {@code JsonDeserializer} instance with exception handling.  This wrapper class
 | 
			
		||||
 * ensures that a {@code JsonDeserializer} will not propagate any exception other than a
 | 
			
		||||
 * {@link JsonParseException}.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> type of the deserializer being wrapped.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
class JsonDeserializerExceptionWrapper<T> implements JsonDeserializer<T> {
 | 
			
		||||
 | 
			
		||||
  private final JsonDeserializer<T> delegate;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns a wrapped {@link JsonDeserializer} object that has been decorated with
 | 
			
		||||
   * {@link JsonParseException} handling.
 | 
			
		||||
   *
 | 
			
		||||
   * @param delegate the {@code JsonDeserializer} instance to be wrapped.
 | 
			
		||||
   * @throws IllegalArgumentException if {@code delegate} is {@code null}.
 | 
			
		||||
   */
 | 
			
		||||
  JsonDeserializerExceptionWrapper(JsonDeserializer<T> delegate) {
 | 
			
		||||
    Preconditions.checkNotNull(delegate);
 | 
			
		||||
    this.delegate = delegate;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
 | 
			
		||||
      throws JsonParseException {
 | 
			
		||||
    try {
 | 
			
		||||
      return delegate.deserialize(json, typeOfT, context);
 | 
			
		||||
    } catch (JsonParseException e) {
 | 
			
		||||
      // just rethrow the exception
 | 
			
		||||
      throw e;
 | 
			
		||||
    } catch (Exception e) {
 | 
			
		||||
      // rethrow as a JsonParseException
 | 
			
		||||
      StringBuilder errorMsg = new StringBuilder()
 | 
			
		||||
          .append("The JsonDeserializer ")
 | 
			
		||||
          .append(delegate)
 | 
			
		||||
          .append(" failed to deserialized json object ")
 | 
			
		||||
          .append(json)
 | 
			
		||||
          .append(" given the type ")
 | 
			
		||||
          .append(typeOfT);
 | 
			
		||||
      throw new JsonParseException(errorMsg.toString(), e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  @Override
 | 
			
		||||
  public String toString() {
 | 
			
		||||
    return delegate.toString();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										338
									
								
								src/com/bukkit/mcteam/gson/JsonElement.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								src/com/bukkit/mcteam/gson/JsonElement.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,338 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representing an element of Json. It could either be a {@link JsonObject}, a
 | 
			
		||||
 * {@link JsonArray}, a {@link JsonPrimitive} or a {@link JsonNull}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public abstract class JsonElement {
 | 
			
		||||
  private static final Escaper BASIC_ESCAPER = new Escaper(false);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * provides check for verifying if this element is an array or not.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this element is of type {@link JsonArray}, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isJsonArray() {
 | 
			
		||||
    return this instanceof JsonArray;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * provides check for verifying if this element is a Json object or not.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this element is of type {@link JsonObject}, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isJsonObject() {
 | 
			
		||||
    return this instanceof JsonObject;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * provides check for verifying if this element is a primitive or not.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this element is of type {@link JsonPrimitive}, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isJsonPrimitive() {
 | 
			
		||||
    return this instanceof JsonPrimitive;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * provides check for verifying if this element represents a null value or not.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this element is of type {@link JsonNull}, false otherwise.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isJsonNull() {
 | 
			
		||||
    return this instanceof JsonNull;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link JsonObject}. If the element is of some
 | 
			
		||||
   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
 | 
			
		||||
   * after ensuring that this element is of the desired type by calling {@link #isJsonObject()}
 | 
			
		||||
   * first.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link JsonObject}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of another type.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonObject getAsJsonObject() {
 | 
			
		||||
    if (isJsonObject()) {
 | 
			
		||||
      return (JsonObject) this;
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException("This is not a JSON Object.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link JsonArray}. If the element is of some
 | 
			
		||||
   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
 | 
			
		||||
   * after ensuring that this element is of the desired type by calling {@link #isJsonArray()}
 | 
			
		||||
   * first.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link JsonArray}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of another type.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonArray getAsJsonArray() {
 | 
			
		||||
    if (isJsonArray()) {
 | 
			
		||||
      return (JsonArray) this;
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException("This is not a JSON Array.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link JsonPrimitive}. If the element is of some
 | 
			
		||||
   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
 | 
			
		||||
   * after ensuring that this element is of the desired type by calling {@link #isJsonPrimitive()}
 | 
			
		||||
   * first.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link JsonPrimitive}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of another type.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive getAsJsonPrimitive() {
 | 
			
		||||
    if (isJsonPrimitive()) {
 | 
			
		||||
      return (JsonPrimitive) this;
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException("This is not a JSON Primitive.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link JsonNull}. If the element is of some
 | 
			
		||||
   * other type, a {@link ClassCastException} will result. Hence it is best to use this method
 | 
			
		||||
   * after ensuring that this element is of the desired type by calling {@link #isJsonNull()}
 | 
			
		||||
   * first.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link JsonNull}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of another type.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public JsonNull getAsJsonNull() {
 | 
			
		||||
    if (isJsonNull()) {
 | 
			
		||||
      return (JsonNull) this;
 | 
			
		||||
    }
 | 
			
		||||
    throw new IllegalStateException("This is not a JSON Null.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a boolean value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive boolean value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * boolean value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean getAsBoolean() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link Boolean} value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link Boolean} value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * boolean value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  Boolean getAsBooleanWrapper() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link Number}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link Number}.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * number.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public Number getAsNumber() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a string value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a string value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * string value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public String getAsString() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive double value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive double value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * double value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public double getAsDouble() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive float value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive float value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * float value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public float getAsFloat() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive long value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive long value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * long value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public long getAsLong() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive integer value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive integer value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * integer value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public int getAsInt() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive byte value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive byte value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * byte value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public byte getAsByte() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive character value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive char value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * char value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public char getAsCharacter() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link BigDecimal}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigDecimal}.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive}.
 | 
			
		||||
   * * @throws NumberFormatException if the element is not a valid {@link BigDecimal}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public BigDecimal getAsBigDecimal() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link BigInteger}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigInteger}.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive}.
 | 
			
		||||
   * @throws NumberFormatException if the element is not a valid {@link BigInteger}.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   * @since 1.2
 | 
			
		||||
   */
 | 
			
		||||
  public BigInteger getAsBigInteger() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a primitive short value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a primitive short value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * short value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  public short getAsShort() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as an {@link Object} value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as an Object value.
 | 
			
		||||
   * @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
 | 
			
		||||
   * Object value.
 | 
			
		||||
   * @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
 | 
			
		||||
   * more than a single element.
 | 
			
		||||
   */
 | 
			
		||||
  Object getAsObject() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns a String representation of this element.
 | 
			
		||||
   *
 | 
			
		||||
   * @return String the string representation of this element.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public String toString() {
 | 
			
		||||
    try {
 | 
			
		||||
      StringBuilder sb = new StringBuilder();
 | 
			
		||||
      toString(sb, BASIC_ESCAPER);
 | 
			
		||||
      return sb.toString();
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected abstract void toString(Appendable sb, Escaper escaper) throws IOException;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/com/bukkit/mcteam/gson/JsonElementVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/com/bukkit/mcteam/gson/JsonElementVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Definition of a visitor for a JsonElement tree.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 */
 | 
			
		||||
interface JsonElementVisitor {
 | 
			
		||||
  void visitPrimitive(JsonPrimitive primitive) throws IOException;
 | 
			
		||||
  void visitNull() throws IOException;
 | 
			
		||||
 | 
			
		||||
  void startArray(JsonArray array) throws IOException;
 | 
			
		||||
  void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) throws IOException;
 | 
			
		||||
  void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) throws IOException;
 | 
			
		||||
  void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) throws IOException;
 | 
			
		||||
  void visitNullArrayMember(JsonArray parent, boolean isFirst) throws IOException;
 | 
			
		||||
  void endArray(JsonArray array) throws IOException;
 | 
			
		||||
  
 | 
			
		||||
  void startObject(JsonObject object) throws IOException;
 | 
			
		||||
  void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, 
 | 
			
		||||
      boolean isFirst) throws IOException;
 | 
			
		||||
  void visitObjectMember(JsonObject parent, String memberName, JsonArray member, 
 | 
			
		||||
      boolean isFirst) throws IOException;
 | 
			
		||||
  void visitObjectMember(JsonObject parent, String memberName, JsonObject member, 
 | 
			
		||||
      boolean isFirst) throws IOException;
 | 
			
		||||
  void visitNullObjectMember(JsonObject parent, String memberName, 
 | 
			
		||||
      boolean isFirst) throws IOException;
 | 
			
		||||
  void endObject(JsonObject object) throws IOException;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								src/com/bukkit/mcteam/gson/JsonFieldNameValidator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/com/bukkit/mcteam/gson/JsonFieldNameValidator.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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 com.bukkit.mcteam.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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/com/bukkit/mcteam/gson/JsonIOException.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/com/bukkit/mcteam/gson/JsonIOException.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This exception is raised when Gson was unable to read an input stream
 | 
			
		||||
 * or write to one.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonIOException extends JsonParseException {
 | 
			
		||||
 | 
			
		||||
  private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
  public JsonIOException(String msg) {
 | 
			
		||||
    super(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public JsonIOException(String msg, Throwable cause) {
 | 
			
		||||
    super(msg, cause);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates exception with the specified cause. Consider using
 | 
			
		||||
   * {@link #JsonIOException(String, Throwable)} instead if you can describe what happened.
 | 
			
		||||
   *
 | 
			
		||||
   * @param cause root exception that caused this exception to be thrown.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonIOException(Throwable cause) {
 | 
			
		||||
    super(cause);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/com/bukkit/mcteam/gson/JsonNull.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/com/bukkit/mcteam/gson/JsonNull.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representing a Json {@code null} value.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * @since 1.2
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonNull extends JsonElement {
 | 
			
		||||
  private static final JsonNull INSTANCE = new JsonNull();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a new JsonNull object.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonNull() {
 | 
			
		||||
    // Do nothing
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void toString(Appendable sb, Escaper escaper) throws IOException {
 | 
			
		||||
    sb.append("null");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * All instances of JsonNull have the same hash code since they are indistinguishable
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int hashCode() {
 | 
			
		||||
    return JsonNull.class.hashCode();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * All instances of JsonNull are the same
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean equals(Object other) {
 | 
			
		||||
    return other instanceof JsonNull;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Creation method used to return an instance of a {@link JsonNull}.  To reduce the memory
 | 
			
		||||
   * footprint, a single object has been created for this class; therefore the same instance is
 | 
			
		||||
   * being returned for each invocation of this method. This method is kept private since we 
 | 
			
		||||
   * prefer the users to use {@link JsonNull#JsonNull()} which is similar to how other JsonElements
 | 
			
		||||
   * are created. Note that all instances of JsonNull return true for {@link #equals(Object)} 
 | 
			
		||||
   * when compared to each other.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a instance of a {@link JsonNull}
 | 
			
		||||
   */
 | 
			
		||||
  static JsonNull createJsonNull() {
 | 
			
		||||
    return INSTANCE;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										208
									
								
								src/com/bukkit/mcteam/gson/JsonObject.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								src/com/bukkit/mcteam/gson/JsonObject.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representing an object type in Json. An object consists of name-value pairs where names
 | 
			
		||||
 * are strings, and values are any other type of {@link JsonElement}. This allows for a creating a
 | 
			
		||||
 * tree of JsonElements. The member elements of this object are maintained in order they were added.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonObject extends JsonElement {
 | 
			
		||||
  // We are using a linked hash map because it is important to preserve
 | 
			
		||||
  // the order in which elements are inserted. This is needed to ensure
 | 
			
		||||
  // that the fields of an object are inserted in the order they were
 | 
			
		||||
  // defined in the class.
 | 
			
		||||
  private final Map<String, JsonElement> members;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates an empty JsonObject.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonObject() {
 | 
			
		||||
    members = new LinkedHashMap<String, JsonElement>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adds a member, which is a name-value pair, to self. The name must be a String, but the value
 | 
			
		||||
   * can be an arbitrary JsonElement, thereby allowing you to build a full tree of JsonElements
 | 
			
		||||
   * rooted at this node.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member.
 | 
			
		||||
   * @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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Removes the {@code property} from this {@link JsonObject}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member that should be removed.
 | 
			
		||||
   * @return the {@link JsonElement} object that is being removed.
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement remove(String property) {
 | 
			
		||||
    return members.remove(property);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to add a primitive member. The specified value is converted to a
 | 
			
		||||
   * JsonPrimitive of String.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member.
 | 
			
		||||
   * @param value the string value associated with the member.
 | 
			
		||||
   */
 | 
			
		||||
  public void addProperty(String property, String value) {
 | 
			
		||||
    add(property, createJsonElement(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to add a primitive member. The specified value is converted to a
 | 
			
		||||
   * JsonPrimitive of Number.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member.
 | 
			
		||||
   * @param value the number value associated with the member.
 | 
			
		||||
   */
 | 
			
		||||
  public void addProperty(String property, Number value) {
 | 
			
		||||
    add(property, createJsonElement(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to add a boolean member. The specified value is converted to a
 | 
			
		||||
   * JsonPrimitive of Boolean.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member.
 | 
			
		||||
   * @param value the number value associated with the member.
 | 
			
		||||
   */
 | 
			
		||||
  public void addProperty(String property, Boolean value) {
 | 
			
		||||
    add(property, createJsonElement(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to add a char member. The specified value is converted to a
 | 
			
		||||
   * JsonPrimitive of Character.
 | 
			
		||||
   *
 | 
			
		||||
   * @param property name of the member.
 | 
			
		||||
   * @param value the number value associated with the member.
 | 
			
		||||
   */
 | 
			
		||||
  public void addProperty(String property, Character value) {
 | 
			
		||||
    add(property, createJsonElement(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates the proper {@link JsonElement} object from the given {@code value} object.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value the object to generate the {@link JsonElement} for
 | 
			
		||||
   * @return a {@link JsonPrimitive} if the {@code value} is not null, otherwise a {@link JsonNull}
 | 
			
		||||
   */
 | 
			
		||||
  private JsonElement createJsonElement(Object value) {
 | 
			
		||||
    return value == null ? JsonNull.createJsonNull() : new JsonPrimitive(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns a set of members of this object. The set is ordered, and the order is in which the
 | 
			
		||||
   * elements were added.
 | 
			
		||||
   *
 | 
			
		||||
   * @return a set of members of this object.
 | 
			
		||||
   */
 | 
			
		||||
  public Set<Map.Entry<String, JsonElement>> entrySet() {
 | 
			
		||||
    return members.entrySet();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to check if a member with the specified name is present in this object.
 | 
			
		||||
   *
 | 
			
		||||
   * @param memberName name of the member that is being checked for presence.
 | 
			
		||||
   * @return true if there is a member with the specified name, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean has(String memberName) {
 | 
			
		||||
    return members.containsKey(memberName);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the member with the specified name.
 | 
			
		||||
   *
 | 
			
		||||
   * @param memberName name of the member that is being requested.
 | 
			
		||||
   * @return the member matching the name. Null if no such member exists.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement get(String memberName) {
 | 
			
		||||
    if (members.containsKey(memberName)) {
 | 
			
		||||
      JsonElement member = members.get(memberName);
 | 
			
		||||
      return member == null ? JsonNull.createJsonNull() : member;
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to get the specified member as a JsonPrimitive element.
 | 
			
		||||
   *
 | 
			
		||||
   * @param memberName name of the member being requested.
 | 
			
		||||
   * @return the JsonPrimitive corresponding to the specified member.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive getAsJsonPrimitive(String memberName) {
 | 
			
		||||
    return (JsonPrimitive) members.get(memberName);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to get the specified member as a JsonArray.
 | 
			
		||||
   *
 | 
			
		||||
   * @param memberName name of the member being requested.
 | 
			
		||||
   * @return the JsonArray corresponding to the specified member.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonArray getAsJsonArray(String memberName) {
 | 
			
		||||
    return (JsonArray) members.get(memberName);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convenience method to get the specified member as a JsonObject.
 | 
			
		||||
   *
 | 
			
		||||
   * @param memberName name of the member being requested.
 | 
			
		||||
   * @return the JsonObject corresponding to the specified member.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonObject getAsJsonObject(String memberName) {
 | 
			
		||||
    return (JsonObject) members.get(memberName);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void toString(Appendable sb, Escaper escaper) throws IOException {
 | 
			
		||||
    sb.append('{');
 | 
			
		||||
    boolean first = true;
 | 
			
		||||
    for (Map.Entry<String, JsonElement> entry : members.entrySet()) {
 | 
			
		||||
      if (first) {
 | 
			
		||||
        first = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        sb.append(',');
 | 
			
		||||
      }
 | 
			
		||||
      sb.append('\"');
 | 
			
		||||
      sb.append(escaper.escapeJsonString(entry.getKey()));
 | 
			
		||||
      sb.append("\":");
 | 
			
		||||
      entry.getValue().toString(sb, escaper);
 | 
			
		||||
    }
 | 
			
		||||
    sb.append('}');
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								src/com/bukkit/mcteam/gson/JsonObjectDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								src/com/bukkit/mcteam/gson/JsonObjectDeserializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A visitor that populates fields of an object with data from its equivalent
 | 
			
		||||
 * JSON representation
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class JsonObjectDeserializationVisitor<T> extends JsonDeserializationVisitor<T> {
 | 
			
		||||
 | 
			
		||||
  JsonObjectDeserializationVisitor(JsonElement json, Type type,
 | 
			
		||||
      ObjectNavigatorFactory factory, ObjectConstructor objectConstructor,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
 | 
			
		||||
      JsonDeserializationContext context) {
 | 
			
		||||
    super(json, type, factory, objectConstructor, deserializers, context);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  protected T constructTarget() {
 | 
			
		||||
    return (T) objectConstructor.construct(targetType);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void startVisitingObject(Object node) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArray(Object array, Type componentType) {
 | 
			
		||||
    // should not be called since this case should invoke JsonArrayDeserializationVisitor
 | 
			
		||||
    throw new JsonParseException("Expecting object but found array: " + array);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (!json.isJsonObject()) {
 | 
			
		||||
        throw new JsonParseException("Expecting object found: " + json); 
 | 
			
		||||
      }
 | 
			
		||||
      JsonObject jsonObject = json.getAsJsonObject();
 | 
			
		||||
      String fName = getFieldName(f);
 | 
			
		||||
      JsonElement jsonChild = jsonObject.get(fName);
 | 
			
		||||
      if (jsonChild != null) {
 | 
			
		||||
        Object child = visitChildAsObject(typeOfF, jsonChild);
 | 
			
		||||
        f.set(obj, child);
 | 
			
		||||
      } else {
 | 
			
		||||
        f.set(obj, null);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (IllegalAccessException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (!json.isJsonObject()) {
 | 
			
		||||
        throw new JsonParseException("Expecting object found: " + json); 
 | 
			
		||||
      }
 | 
			
		||||
      JsonObject jsonObject = json.getAsJsonObject();
 | 
			
		||||
      String fName = getFieldName(f);
 | 
			
		||||
      JsonArray jsonChild = (JsonArray) jsonObject.get(fName);
 | 
			
		||||
      if (jsonChild != null) {
 | 
			
		||||
        Object array = visitChildAsArray(typeOfF, jsonChild);
 | 
			
		||||
        f.set(obj, array);
 | 
			
		||||
      } else {
 | 
			
		||||
        f.set(obj, null);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (IllegalAccessException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private String getFieldName(FieldAttributes f) {
 | 
			
		||||
    FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
 | 
			
		||||
    return namingPolicy.translateName(f);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
 | 
			
		||||
    try {
 | 
			
		||||
      String fName = getFieldName(f);
 | 
			
		||||
      if (!json.isJsonObject()) {
 | 
			
		||||
        throw new JsonParseException("Expecting object found: " + json); 
 | 
			
		||||
      }
 | 
			
		||||
      JsonElement child = json.getAsJsonObject().get(fName);
 | 
			
		||||
      TypeInfo typeInfo = new TypeInfo(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()) {
 | 
			
		||||
          f.set(parent, null);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      ObjectTypePair objTypePair = new ObjectTypePair(null, declaredTypeOfField, false);
 | 
			
		||||
      Pair<JsonDeserializer<?>, ObjectTypePair> pair = objTypePair.getMatchingHandler(deserializers);
 | 
			
		||||
      if (pair == null) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }      
 | 
			
		||||
      Object value = invokeCustomDeserializer(child, pair);
 | 
			
		||||
      if (value != null || !typeInfo.isPrimitive()) {
 | 
			
		||||
        f.set(parent, value);
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    } catch (IllegalAccessException e) {
 | 
			
		||||
      throw new RuntimeException();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public void visitPrimitive(Object primitive) {
 | 
			
		||||
    if (!json.isJsonPrimitive()) {
 | 
			
		||||
      throw new JsonParseException(
 | 
			
		||||
          "Type information is unavailable, and the target object is not a primitive: " + json);
 | 
			
		||||
    }
 | 
			
		||||
    JsonPrimitive prim = json.getAsJsonPrimitive();
 | 
			
		||||
    target = (T) prim.getAsObject();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								src/com/bukkit/mcteam/gson/JsonParseException.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/com/bukkit/mcteam/gson/JsonParseException.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This exception is raised if there is a serious issue that occurs during parsing of a Json
 | 
			
		||||
 * string.  One of the main usages for this class is for the Gson infrastructure.  If the incoming
 | 
			
		||||
 * Json is bad/malicious, an instance of this exception is raised.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This exception is a {@link RuntimeException} because it is exposed to the client.  Using a
 | 
			
		||||
 * {@link RuntimeException} avoids bad coding practices on the client side where they catch the
 | 
			
		||||
 * exception and do nothing.  It is often the case that you want to blow up if there is a parsing
 | 
			
		||||
 * error (i.e. often clients do not know how to recover from a {@link JsonParseException}.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public class JsonParseException extends RuntimeException {
 | 
			
		||||
  static final long serialVersionUID = -4086729973971783390L;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates exception with the specified message. If you are wrapping another exception, consider
 | 
			
		||||
   * using {@link #JsonParseException(String, Throwable)} instead.
 | 
			
		||||
   *
 | 
			
		||||
   * @param msg error message describing a possible cause of this exception.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonParseException(String msg) {
 | 
			
		||||
    super(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates exception with the specified message and cause.
 | 
			
		||||
   *
 | 
			
		||||
   * @param msg error message describing what happened.
 | 
			
		||||
   * @param cause root exception that caused this exception to be thrown.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonParseException(String msg, Throwable cause) {
 | 
			
		||||
    super(msg, cause);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates exception with the specified cause. Consider using
 | 
			
		||||
   * {@link #JsonParseException(String, Throwable)} instead if you can describe what happened.
 | 
			
		||||
   *
 | 
			
		||||
   * @param cause root exception that caused this exception to be thrown.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonParseException(Throwable cause) {
 | 
			
		||||
    super(cause);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										97
									
								
								src/com/bukkit/mcteam/gson/JsonParser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								src/com/bukkit/mcteam/gson/JsonParser.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonReader;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonToken;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.MalformedJsonException;
 | 
			
		||||
import java.io.EOFException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.io.StringReader;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A parser to parse Json into a parse tree of {@link JsonElement}s
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * @since 1.3
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonParser {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Parses the specified JSON string into a parse tree
 | 
			
		||||
   *
 | 
			
		||||
   * @param json JSON text
 | 
			
		||||
   * @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
 | 
			
		||||
   * @throws JsonParseException if the specified text is not valid JSON
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement parse(String json) throws JsonSyntaxException {
 | 
			
		||||
    return parse(new StringReader(json));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Parses the specified JSON string into a parse tree
 | 
			
		||||
   *
 | 
			
		||||
   * @param json JSON text
 | 
			
		||||
   * @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
 | 
			
		||||
   * @throws JsonParseException if the specified text is not valid JSON
 | 
			
		||||
   * @since 1.3
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement parse(Reader json) throws JsonIOException, JsonSyntaxException {
 | 
			
		||||
    try {
 | 
			
		||||
      JsonReader jsonReader = new JsonReader(json);
 | 
			
		||||
      JsonElement element = parse(jsonReader);
 | 
			
		||||
      if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT) {
 | 
			
		||||
        throw new JsonSyntaxException("Did not consume the entire document.");
 | 
			
		||||
      }
 | 
			
		||||
      return element;
 | 
			
		||||
    } catch (MalformedJsonException e) {
 | 
			
		||||
      throw new JsonSyntaxException(e);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new JsonIOException(e);
 | 
			
		||||
    } catch (NumberFormatException e) {
 | 
			
		||||
      throw new JsonSyntaxException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the next value from the JSON stream as a parse tree.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws JsonParseException if there is an IOException or if the specified
 | 
			
		||||
   *     text is not valid JSON
 | 
			
		||||
   * @since 1.6
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement parse(JsonReader json) throws JsonIOException, JsonSyntaxException {
 | 
			
		||||
    boolean lenient = json.isLenient();
 | 
			
		||||
    json.setLenient(true);
 | 
			
		||||
    try {
 | 
			
		||||
      return Streams.parse(json);
 | 
			
		||||
    } catch (StackOverflowError e) {
 | 
			
		||||
      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
 | 
			
		||||
    } catch (OutOfMemoryError e) {
 | 
			
		||||
      throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
 | 
			
		||||
    } catch (JsonParseException e) {
 | 
			
		||||
      if (e.getCause() instanceof EOFException) {
 | 
			
		||||
        return JsonNull.createJsonNull();
 | 
			
		||||
      }
 | 
			
		||||
      throw e;
 | 
			
		||||
    } finally {
 | 
			
		||||
      json.setLenient(lenient);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										387
									
								
								src/com/bukkit/mcteam/gson/JsonPrimitive.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								src/com/bukkit/mcteam/gson/JsonPrimitive.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,387 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.BigInteger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representing a Json primitive value. A primitive value
 | 
			
		||||
 * is either a String, a Java primitive, or a Java primitive
 | 
			
		||||
 * wrapper type.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonPrimitive extends JsonElement {
 | 
			
		||||
  private static final Class<?>[] PRIMITIVE_TYPES = { int.class, long.class, short.class,
 | 
			
		||||
      float.class, double.class, byte.class, boolean.class, char.class, Integer.class, Long.class,
 | 
			
		||||
      Short.class, Float.class, Double.class, Byte.class, Boolean.class, Character.class };
 | 
			
		||||
 | 
			
		||||
  private static final BigInteger INTEGER_MAX = BigInteger.valueOf(Integer.MAX_VALUE);
 | 
			
		||||
  private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
 | 
			
		||||
 | 
			
		||||
  private Object value;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a primitive containing a boolean value.
 | 
			
		||||
   *
 | 
			
		||||
   * @param bool the value to create the primitive with.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive(Boolean bool) {
 | 
			
		||||
    setValue(bool);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a primitive containing a {@link Number}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param number the value to create the primitive with.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive(Number number) {
 | 
			
		||||
    setValue(number);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a primitive containing a String value.
 | 
			
		||||
   *
 | 
			
		||||
   * @param string the value to create the primitive with.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive(String string) {
 | 
			
		||||
    setValue(string);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a primitive containing a character. The character is turned into a one character String
 | 
			
		||||
   * since Json only supports String.
 | 
			
		||||
   *
 | 
			
		||||
   * @param c the value to create the primitive with.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonPrimitive(Character c) {
 | 
			
		||||
    setValue(c);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a primitive using the specified Object. It must be an instance of {@link Number}, a
 | 
			
		||||
   * Java primitive type, or a String.
 | 
			
		||||
   *
 | 
			
		||||
   * @param primitive the value to create the primitive with.
 | 
			
		||||
   */
 | 
			
		||||
  JsonPrimitive(Object primitive) {
 | 
			
		||||
    setValue(primitive);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void setValue(Object primitive) {
 | 
			
		||||
    if (primitive instanceof Character) {
 | 
			
		||||
      // convert characters to strings since in JSON, characters are represented as a single
 | 
			
		||||
      // character string
 | 
			
		||||
      char c = ((Character) primitive).charValue();
 | 
			
		||||
      this.value = String.valueOf(c);
 | 
			
		||||
    } else {
 | 
			
		||||
      Preconditions.checkArgument(primitive instanceof Number
 | 
			
		||||
          || isPrimitiveOrString(primitive));
 | 
			
		||||
      this.value = primitive;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check whether this primitive contains a boolean value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this primitive contains a boolean value, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isBoolean() {
 | 
			
		||||
    return value instanceof Boolean;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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() {
 | 
			
		||||
    return (Boolean) value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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() {
 | 
			
		||||
    return isBoolean() ? getAsBooleanWrapper().booleanValue() : Boolean.parseBoolean(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check whether this primitive contains a Number.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this primitive contains a Number, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isNumber() {
 | 
			
		||||
    return value instanceof Number;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public Number getAsNumber() {
 | 
			
		||||
    return value instanceof String ? stringToNumber((String) value) : (Number) value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static Number stringToNumber(String value) {
 | 
			
		||||
    try {
 | 
			
		||||
      long longValue = Long.parseLong(value);
 | 
			
		||||
      if (longValue >= Integer.MIN_VALUE && longValue <= Integer.MAX_VALUE) {
 | 
			
		||||
        return (int) longValue;
 | 
			
		||||
      }
 | 
			
		||||
      return longValue;
 | 
			
		||||
    } catch (NumberFormatException ignored) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      return new BigDecimal(value);
 | 
			
		||||
    } catch (NumberFormatException ignored) {
 | 
			
		||||
      return Double.parseDouble(value); // probably NaN, -Infinity or Infinity
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check whether this primitive contains a String value.
 | 
			
		||||
   *
 | 
			
		||||
   * @return true if this primitive contains a String value, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isString() {
 | 
			
		||||
    return value instanceof String;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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() {
 | 
			
		||||
    if (isNumber()) {
 | 
			
		||||
      return getAsNumber().toString();
 | 
			
		||||
    } else if (isBoolean()) {
 | 
			
		||||
      return getAsBooleanWrapper().toString();
 | 
			
		||||
    } else {
 | 
			
		||||
      return (String) value;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public double getAsDouble() {
 | 
			
		||||
    return isNumber() ? getAsNumber().doubleValue() : Double.parseDouble(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link BigDecimal}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigDecimal}.
 | 
			
		||||
   * @throws NumberFormatException if the value contained is not a valid {@link BigDecimal}.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public BigDecimal getAsBigDecimal() {
 | 
			
		||||
    return value instanceof BigDecimal ? (BigDecimal) value : new BigDecimal(value.toString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as a {@link BigInteger}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as a {@link BigInteger}.
 | 
			
		||||
   * @throws NumberFormatException if the value contained is not a valid {@link BigInteger}.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public BigInteger getAsBigInteger() {
 | 
			
		||||
    return value instanceof BigInteger ? (BigInteger) value : new BigInteger(value.toString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public float getAsFloat() {
 | 
			
		||||
    return isNumber() ? getAsNumber().floatValue() : Float.parseFloat(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public long getAsLong() {
 | 
			
		||||
    return isNumber() ? getAsNumber().longValue() : Long.parseLong(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public short getAsShort() {
 | 
			
		||||
    return isNumber() ? getAsNumber().shortValue() : Short.parseShort(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 /**
 | 
			
		||||
  * 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.
 | 
			
		||||
  */
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getAsInt() {
 | 
			
		||||
    return isNumber() ? getAsNumber().intValue() : Integer.parseInt(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public byte getAsByte() {
 | 
			
		||||
    return isNumber() ? getAsNumber().byteValue() : Byte.parseByte(getAsString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public char getAsCharacter() {
 | 
			
		||||
    return getAsString().charAt(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * convenience method to get this element as an Object.
 | 
			
		||||
   *
 | 
			
		||||
   * @return get this element as an Object that can be converted to a suitable value.
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  Object getAsObject() {
 | 
			
		||||
    if (value instanceof BigInteger) {
 | 
			
		||||
      BigInteger big = (BigInteger) value;
 | 
			
		||||
      if (big.compareTo(INTEGER_MAX) < 0) {
 | 
			
		||||
        return big.intValue();
 | 
			
		||||
      } else if (big.compareTo(LONG_MAX) < 0) {
 | 
			
		||||
        return big.longValue();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // No need to convert to float or double since those lose precision
 | 
			
		||||
    return value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected void toString(Appendable sb, Escaper escaper) throws IOException {
 | 
			
		||||
    if (isString()) {
 | 
			
		||||
      sb.append('"');
 | 
			
		||||
      sb.append(escaper.escapeJsonString(value.toString()));
 | 
			
		||||
      sb.append('"');
 | 
			
		||||
    } else {
 | 
			
		||||
      sb.append(value.toString());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static boolean isPrimitiveOrString(Object target) {
 | 
			
		||||
    if (target instanceof String) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Class<?> classOfPrimitive = target.getClass();
 | 
			
		||||
    for (Class<?> standardPrimitive : PRIMITIVE_TYPES) {
 | 
			
		||||
      if (standardPrimitive.isAssignableFrom(classOfPrimitive)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int hashCode() {
 | 
			
		||||
    if (value == null) {
 | 
			
		||||
      return 31;
 | 
			
		||||
    }
 | 
			
		||||
    // Using recommended hashing algorithm from Effective Java for longs and doubles
 | 
			
		||||
    if (isIntegral(this)) {
 | 
			
		||||
      long value = getAsNumber().longValue();
 | 
			
		||||
      return (int) (value ^ (value >>> 32));
 | 
			
		||||
    }
 | 
			
		||||
    if (isFloatingPoint(this)) {
 | 
			
		||||
      long value = Double.doubleToLongBits(getAsNumber().doubleValue());
 | 
			
		||||
      return (int) (value ^ (value >>> 32));
 | 
			
		||||
    }
 | 
			
		||||
    return value.hashCode();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean equals(Object obj) {
 | 
			
		||||
    if (this == obj) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (obj == null || getClass() != obj.getClass()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    JsonPrimitive other = (JsonPrimitive)obj;
 | 
			
		||||
    if (value == null) {
 | 
			
		||||
      return other.value == null;
 | 
			
		||||
    }
 | 
			
		||||
    if (isIntegral(this) && isIntegral(other)) {
 | 
			
		||||
      return getAsNumber().longValue() == other.getAsNumber().longValue();
 | 
			
		||||
    }
 | 
			
		||||
    if (isFloatingPoint(this) && isFloatingPoint(other)) {
 | 
			
		||||
      return getAsNumber().doubleValue() == other.getAsNumber().doubleValue();
 | 
			
		||||
    }
 | 
			
		||||
    return value.equals(other.value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if the specified number is an integral type
 | 
			
		||||
   * (Long, Integer, Short, Byte, BigInteger)
 | 
			
		||||
   */
 | 
			
		||||
  private static boolean isIntegral(JsonPrimitive primitive) {
 | 
			
		||||
    if (primitive.value instanceof Number) {
 | 
			
		||||
      Number number = (Number) primitive.value;
 | 
			
		||||
      return number instanceof BigInteger || number instanceof Long || number instanceof Integer
 | 
			
		||||
      || number instanceof Short || number instanceof Byte;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if the specified number is a floating point type (BigDecimal, double, float)
 | 
			
		||||
   */
 | 
			
		||||
  private static boolean isFloatingPoint(JsonPrimitive primitive) {
 | 
			
		||||
    if (primitive.value instanceof Number) {
 | 
			
		||||
      Number number = (Number) primitive.value;
 | 
			
		||||
      return number instanceof BigDecimal || number instanceof Double || number instanceof Float;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/com/bukkit/mcteam/gson/JsonSerializationContext.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/com/bukkit/mcteam/gson/JsonSerializationContext.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Context for serialization that is passed to a custom serializer during invocation of its
 | 
			
		||||
 * {@link JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public interface JsonSerializationContext {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Invokes default serialization on the specified object.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object that needs to be serialized.
 | 
			
		||||
   * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement serialize(Object src);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Invokes default serialization on the specified object passing the specific type information.
 | 
			
		||||
   * It should never be invoked on the element received as a parameter of the
 | 
			
		||||
   * {@link JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method. Doing
 | 
			
		||||
   * so will result in an infinite loop since Gson will in-turn call the custom serializer again.
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object that needs to be serialized.
 | 
			
		||||
   * @param typeOfSrc the actual genericized type of src object.
 | 
			
		||||
   * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement serialize(Object src, Type typeOfSrc);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An implementation of serialization context for Gson.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 */
 | 
			
		||||
final class JsonSerializationContextDefault implements JsonSerializationContext {
 | 
			
		||||
 | 
			
		||||
  private final ObjectNavigatorFactory factory;
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
 | 
			
		||||
  private final boolean serializeNulls;
 | 
			
		||||
  private final MemoryRefStack ancestors;
 | 
			
		||||
 | 
			
		||||
  JsonSerializationContextDefault(ObjectNavigatorFactory factory, boolean serializeNulls,
 | 
			
		||||
      ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers) {
 | 
			
		||||
    this.factory = factory;
 | 
			
		||||
    this.serializeNulls = serializeNulls;
 | 
			
		||||
    this.serializers = serializers;
 | 
			
		||||
    this.ancestors = new MemoryRefStack();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public JsonElement serialize(Object src) {
 | 
			
		||||
    if (src == null) {
 | 
			
		||||
      return JsonNull.createJsonNull();
 | 
			
		||||
    }
 | 
			
		||||
    return serialize(src, src.getClass(), true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
    return visitor.getJsonElement();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										236
									
								
								src/com/bukkit/mcteam/gson/JsonSerializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								src/com/bukkit/mcteam/gson/JsonSerializationVisitor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,236 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A visitor that adds JSON elements corresponding to each field of an object
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
 | 
			
		||||
 | 
			
		||||
  private final ObjectNavigatorFactory factory;
 | 
			
		||||
  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;
 | 
			
		||||
    this.serializeNulls = serializeNulls;
 | 
			
		||||
    this.serializers = serializers;
 | 
			
		||||
    this.context = context;
 | 
			
		||||
    this.ancestors = ancestors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public Object getTarget() {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void start(ObjectTypePair node) {
 | 
			
		||||
    if (node == null) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (ancestors.contains(node)) {
 | 
			
		||||
      throw new CircularReferenceException(node);
 | 
			
		||||
    }
 | 
			
		||||
    ancestors.push(node);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void end(ObjectTypePair node) {
 | 
			
		||||
    if (node != null) {
 | 
			
		||||
      ancestors.pop();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void startVisitingObject(Object node) {
 | 
			
		||||
    assignToRoot(new JsonObject());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArray(Object array, Type arrayType) {
 | 
			
		||||
    assignToRoot(new JsonArray());
 | 
			
		||||
    int length = Array.getLength(array);
 | 
			
		||||
    TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType);
 | 
			
		||||
    Type componentType = fieldTypeInfo.getSecondLevelType();
 | 
			
		||||
    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));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitArrayField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (isFieldNull(f, obj)) {
 | 
			
		||||
        if (serializeNulls) {
 | 
			
		||||
          addChildAsElement(f, JsonNull.createJsonNull());
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        Object array = getFieldValue(f, obj);
 | 
			
		||||
        addAsChildOfObject(f, new ObjectTypePair(array, typeOfF, false));
 | 
			
		||||
      }
 | 
			
		||||
    } catch (CircularReferenceException e) {
 | 
			
		||||
      throw e.createDetailedException(f);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitObjectField(FieldAttributes f, Type typeOfF, Object obj) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (isFieldNull(f, obj)) {
 | 
			
		||||
        if (serializeNulls) {
 | 
			
		||||
          addChildAsElement(f, JsonNull.createJsonNull());
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        Object fieldValue = getFieldValue(f, obj);
 | 
			
		||||
        // we should not get more specific component type yet since it is
 | 
			
		||||
        // possible that a custom
 | 
			
		||||
        // serializer is registered for the componentType
 | 
			
		||||
        addAsChildOfObject(f, new ObjectTypePair(fieldValue, typeOfF, false));
 | 
			
		||||
      }
 | 
			
		||||
    } catch (CircularReferenceException e) {
 | 
			
		||||
      throw e.createDetailedException(f);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void visitPrimitive(Object obj) {
 | 
			
		||||
    JsonElement json = obj == null ? JsonNull.createJsonNull() : new JsonPrimitive(obj);
 | 
			
		||||
    assignToRoot(json);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void addAsChildOfObject(FieldAttributes f, ObjectTypePair fieldValuePair) {
 | 
			
		||||
    JsonElement childElement = getJsonElementForChild(fieldValuePair);
 | 
			
		||||
    addChildAsElement(f, childElement);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void addChildAsElement(FieldAttributes f, JsonElement childElement) {
 | 
			
		||||
    FieldNamingStrategy2 namingPolicy = factory.getFieldNamingPolicy();
 | 
			
		||||
    root.getAsJsonObject().add(namingPolicy.translateName(f), childElement);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void addAsArrayElement(ObjectTypePair elementTypePair) {
 | 
			
		||||
    if (elementTypePair.getObject() == null) {
 | 
			
		||||
      root.getAsJsonArray().add(JsonNull.createJsonNull());
 | 
			
		||||
    } else {
 | 
			
		||||
      JsonElement childElement = getJsonElementForChild(elementTypePair);
 | 
			
		||||
      root.getAsJsonArray().add(childElement);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private JsonElement getJsonElementForChild(ObjectTypePair fieldValueTypePair) {
 | 
			
		||||
    ObjectNavigator on = factory.create(fieldValueTypePair);
 | 
			
		||||
    JsonSerializationVisitor childVisitor =
 | 
			
		||||
        new JsonSerializationVisitor(factory, serializeNulls, serializers, context, ancestors);
 | 
			
		||||
    on.accept(childVisitor);
 | 
			
		||||
    return childVisitor.getJsonElement();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
 | 
			
		||||
    try {
 | 
			
		||||
      Object obj = objTypePair.getObject();
 | 
			
		||||
      if (obj == null) {
 | 
			
		||||
        if (serializeNulls) {
 | 
			
		||||
          assignToRoot(JsonNull.createJsonNull());
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      JsonElement element = findAndInvokeCustomSerializer(objTypePair);
 | 
			
		||||
      if (element != null) {
 | 
			
		||||
        assignToRoot(element);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    } catch (CircularReferenceException e) {
 | 
			
		||||
      throw e.createDetailedException(null);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * objTypePair.getObject() must not be null
 | 
			
		||||
   */
 | 
			
		||||
  @SuppressWarnings({"unchecked", "rawtypes"})
 | 
			
		||||
  private JsonElement findAndInvokeCustomSerializer(ObjectTypePair objTypePair) {
 | 
			
		||||
    Pair<JsonSerializer<?>,ObjectTypePair> pair = objTypePair.getMatchingHandler(serializers);
 | 
			
		||||
    if (pair == null) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    JsonSerializer serializer = pair.first;
 | 
			
		||||
    objTypePair = pair.second;
 | 
			
		||||
    start(objTypePair);
 | 
			
		||||
    try {
 | 
			
		||||
      JsonElement element =
 | 
			
		||||
          serializer.serialize(objTypePair.getObject(), objTypePair.getType(), context);
 | 
			
		||||
      return element == null ? JsonNull.createJsonNull() : element;
 | 
			
		||||
    } finally {
 | 
			
		||||
      end(objTypePair);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type declaredTypeOfField, Object parent) {
 | 
			
		||||
    try {
 | 
			
		||||
      Preconditions.checkState(root.isJsonObject());
 | 
			
		||||
      Object obj = f.get(parent);
 | 
			
		||||
      if (obj == null) {
 | 
			
		||||
        if (serializeNulls) {
 | 
			
		||||
          addChildAsElement(f, JsonNull.createJsonNull());
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      ObjectTypePair objTypePair = new ObjectTypePair(obj, declaredTypeOfField, false);
 | 
			
		||||
      JsonElement child = findAndInvokeCustomSerializer(objTypePair);
 | 
			
		||||
      if (child != null) {
 | 
			
		||||
        addChildAsElement(f, child);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      return false;
 | 
			
		||||
    } catch (IllegalAccessException e) {
 | 
			
		||||
      throw new RuntimeException();
 | 
			
		||||
    } catch (CircularReferenceException e) {
 | 
			
		||||
      throw e.createDetailedException(f);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void assignToRoot(JsonElement newRoot) {
 | 
			
		||||
    Preconditions.checkNotNull(newRoot);
 | 
			
		||||
    root = newRoot;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isFieldNull(FieldAttributes f, Object obj) {
 | 
			
		||||
    return getFieldValue(f, obj) == null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Object getFieldValue(FieldAttributes f, Object obj) {
 | 
			
		||||
    try {
 | 
			
		||||
      return f.get(obj);
 | 
			
		||||
    } catch (IllegalAccessException e) {
 | 
			
		||||
      throw new RuntimeException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public JsonElement getJsonElement() {
 | 
			
		||||
    return root;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/com/bukkit/mcteam/gson/JsonSerializer.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/com/bukkit/mcteam/gson/JsonSerializer.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface representing a custom serializer for Json. You should write a custom serializer, if
 | 
			
		||||
 * you are not happy with the default serialization done by Gson. You will also need to register
 | 
			
		||||
 * this serializer through {@link com.bukkit.mcteam.gson.GsonBuilder#registerTypeAdapter(Type, Object)}.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Let us look at example where defining a serializer will be useful. The {@code Id} class
 | 
			
		||||
 * defined below has two fields: {@code clazz} and {@code value}.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p><pre>
 | 
			
		||||
 * public class Id<T> {
 | 
			
		||||
 *   private final Class<T> clazz;
 | 
			
		||||
 *   private final long value;
 | 
			
		||||
 *
 | 
			
		||||
 *   public Id(Class<T> clazz, long value) {
 | 
			
		||||
 *     this.clazz = clazz;
 | 
			
		||||
 *     this.value = value;
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public long getValue() {
 | 
			
		||||
 *     return value;
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The default serialization of {@code Id(com.foo.MyObject.class, 20L)} will be
 | 
			
		||||
 * <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you just want the output to be
 | 
			
		||||
 * the value instead, which is {@code 20} in this case. You can achieve that by writing a custom
 | 
			
		||||
 * serializer:</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p><pre>
 | 
			
		||||
 * class IdSerializer implements JsonSerializer<Id>() {
 | 
			
		||||
 *   public JsonElement toJson(Id id, Type typeOfId, JsonSerializationContext context) {
 | 
			
		||||
 *     return new JsonPrimitive(id.getValue());
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>You will also need to register {@code IdSerializer} with Gson as follows:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create();
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> type for which the serializer is being registered. It is possible that a serializer
 | 
			
		||||
 *        may be asked to serialize a specific generic type of the T.
 | 
			
		||||
 */
 | 
			
		||||
public interface JsonSerializer<T> {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gson invokes this call-back method during serialization when it encounters a field of the
 | 
			
		||||
   * specified type.
 | 
			
		||||
   *
 | 
			
		||||
   * <p>In the implementation of this call-back method, you should consider invoking
 | 
			
		||||
   * {@link JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
 | 
			
		||||
   * non-trivial field of the {@code src} object. However, you should never invoke it on the
 | 
			
		||||
   * {@code src} object itself since that will cause an infinite loop (Gson will call your
 | 
			
		||||
   * call-back method again).</p>
 | 
			
		||||
   *
 | 
			
		||||
   * @param src the object that needs to be converted to Json.
 | 
			
		||||
   * @param typeOfSrc the actual type (fully genericized version) of the source object.
 | 
			
		||||
   * @return a JsonElement corresponding to the specified object.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								src/com/bukkit/mcteam/gson/JsonStreamParser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								src/com/bukkit/mcteam/gson/JsonStreamParser.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.EOFException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Reader;
 | 
			
		||||
import java.io.StringReader;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.NoSuchElementException;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonReader;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonToken;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.MalformedJsonException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
 | 
			
		||||
 * asynchronously.
 | 
			
		||||
 * 
 | 
			
		||||
 * <p>This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
 | 
			
		||||
 * properly use this class across multiple threads, you will need to add some external
 | 
			
		||||
 * synchronization.  For example:
 | 
			
		||||
 * 
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * JsonStreamParser parser = new JsonStreamParser("['first'] {'second':10} 'third'");
 | 
			
		||||
 * JsonElement element;
 | 
			
		||||
 * synchronized (parser) {  // synchronize on an object shared by threads
 | 
			
		||||
 *   if (parser.hasNext()) {
 | 
			
		||||
 *     element = parser.next();
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * @since 1.4
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonStreamParser implements Iterator<JsonElement> {
 | 
			
		||||
 | 
			
		||||
  private final JsonReader parser;
 | 
			
		||||
  private final Object lock;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param json The string containing JSON elements concatenated to each other.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public JsonStreamParser(String json) {
 | 
			
		||||
    this(new StringReader(json));      
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * @param reader The data stream containing JSON elements concatenated to each other.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public JsonStreamParser(Reader reader) {
 | 
			
		||||
    parser = new JsonReader(reader);
 | 
			
		||||
    parser.setLenient(true);
 | 
			
		||||
    lock = new Object();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the next available {@link JsonElement} on the reader. Null if none available.
 | 
			
		||||
   * 
 | 
			
		||||
   * @return the next available {@link JsonElement} on the reader. Null if none available.
 | 
			
		||||
   * @throws JsonParseException if the incoming stream is malformed JSON.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement next() throws JsonParseException {
 | 
			
		||||
    if (!hasNext()) {
 | 
			
		||||
      throw new NoSuchElementException();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    try {
 | 
			
		||||
      return Streams.parse(parser);
 | 
			
		||||
    } catch (StackOverflowError e) {
 | 
			
		||||
      throw new JsonParseException("Failed parsing JSON source to Json", e);
 | 
			
		||||
    } catch (OutOfMemoryError e) {
 | 
			
		||||
      throw new JsonParseException("Failed parsing JSON source to Json", e);
 | 
			
		||||
    } catch (JsonParseException e) {
 | 
			
		||||
      throw e.getCause() instanceof EOFException ? new NoSuchElementException() : e;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if a {@link JsonElement} is available on the input for consumption
 | 
			
		||||
   * @return true if a {@link JsonElement} is available on the input, false otherwise
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public boolean hasNext() {
 | 
			
		||||
    synchronized (lock) {
 | 
			
		||||
      try {
 | 
			
		||||
        return parser.peek() != JsonToken.END_DOCUMENT;
 | 
			
		||||
      } catch (MalformedJsonException e) {
 | 
			
		||||
        throw new JsonSyntaxException(e);
 | 
			
		||||
      } catch (IOException e) {
 | 
			
		||||
        throw new JsonIOException(e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * This optional {@link Iterator} method is not relevant for stream parsing and hence is not
 | 
			
		||||
   * implemented.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public void remove() {
 | 
			
		||||
    throw new UnsupportedOperationException();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/com/bukkit/mcteam/gson/JsonSyntaxException.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/com/bukkit/mcteam/gson/JsonSyntaxException.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This exception is raised when Gson attempts to read (or write) a malformed
 | 
			
		||||
 * JSON element.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonSyntaxException extends JsonParseException {
 | 
			
		||||
 | 
			
		||||
  private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
  public JsonSyntaxException(String msg) {
 | 
			
		||||
    super(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public JsonSyntaxException(String msg, Throwable cause) {
 | 
			
		||||
    super(msg, cause);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates exception with the specified cause. Consider using
 | 
			
		||||
   * {@link #JsonSyntaxException(String, Throwable)} instead if you can
 | 
			
		||||
   * describe what actually happened.
 | 
			
		||||
   *
 | 
			
		||||
   * @param cause root exception that caused this exception to be thrown.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonSyntaxException(Throwable cause) {
 | 
			
		||||
    super(cause);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								src/com/bukkit/mcteam/gson/JsonTreeNavigator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/com/bukkit/mcteam/gson/JsonTreeNavigator.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A navigator to navigate a tree of JsonElement nodes in Depth-first order
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 */
 | 
			
		||||
final class JsonTreeNavigator {
 | 
			
		||||
  private final JsonElementVisitor visitor;
 | 
			
		||||
  private final boolean visitNulls;
 | 
			
		||||
 | 
			
		||||
  JsonTreeNavigator(JsonElementVisitor visitor, boolean visitNulls) {
 | 
			
		||||
    this.visitor = visitor;
 | 
			
		||||
    this.visitNulls = visitNulls;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public void navigate(JsonElement element) throws IOException {
 | 
			
		||||
    if (element.isJsonNull()) {
 | 
			
		||||
      visitor.visitNull();
 | 
			
		||||
    } else if (element.isJsonArray()) {
 | 
			
		||||
      JsonArray array = element.getAsJsonArray();
 | 
			
		||||
      visitor.startArray(array);
 | 
			
		||||
      boolean isFirst = true;
 | 
			
		||||
      for (JsonElement child : array) {
 | 
			
		||||
        visitChild(array, child, isFirst);
 | 
			
		||||
        if (isFirst) {
 | 
			
		||||
          isFirst = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      visitor.endArray(array);
 | 
			
		||||
    } else if (element.isJsonObject()) {
 | 
			
		||||
      JsonObject object = element.getAsJsonObject();
 | 
			
		||||
      visitor.startObject(object);
 | 
			
		||||
      boolean isFirst = true;
 | 
			
		||||
      for (Map.Entry<String, JsonElement> member : object.entrySet()) {
 | 
			
		||||
        boolean visited = visitChild(object, member.getKey(), member.getValue(), isFirst);
 | 
			
		||||
        if (visited && isFirst) {
 | 
			
		||||
          isFirst = false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      visitor.endObject(object);
 | 
			
		||||
    } else { // must be JsonPrimitive
 | 
			
		||||
      visitor.visitPrimitive(element.getAsJsonPrimitive());
 | 
			
		||||
    }    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if the child was visited, false if it was skipped.
 | 
			
		||||
   */
 | 
			
		||||
  private boolean visitChild(JsonObject parent, String childName, JsonElement child, 
 | 
			
		||||
      boolean isFirst) throws IOException {
 | 
			
		||||
    if (child.isJsonNull()) {
 | 
			
		||||
      if (visitNulls) {
 | 
			
		||||
        visitor.visitNullObjectMember(parent, childName, isFirst);
 | 
			
		||||
        navigate(child.getAsJsonNull());
 | 
			
		||||
      } else { // Null value is being skipped.
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (child.isJsonArray()) {
 | 
			
		||||
      JsonArray childAsArray = child.getAsJsonArray();
 | 
			
		||||
      visitor.visitObjectMember(parent, childName, childAsArray, isFirst);
 | 
			
		||||
      navigate(childAsArray);
 | 
			
		||||
    } else if (child.isJsonObject()) {
 | 
			
		||||
      JsonObject childAsObject = child.getAsJsonObject();
 | 
			
		||||
      visitor.visitObjectMember(parent, childName, childAsObject, isFirst);
 | 
			
		||||
      navigate(childAsObject);
 | 
			
		||||
    } else { // is a JsonPrimitive
 | 
			
		||||
      visitor.visitObjectMember(parent, childName, child.getAsJsonPrimitive(), isFirst);          
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if the child was visited, false if it was skipped.
 | 
			
		||||
   */
 | 
			
		||||
  private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) throws IOException {
 | 
			
		||||
    if (child.isJsonNull()) {
 | 
			
		||||
      visitor.visitNullArrayMember(parent, isFirst);
 | 
			
		||||
      navigate(child);
 | 
			
		||||
	  } else if (child.isJsonArray()) {
 | 
			
		||||
      JsonArray childAsArray = child.getAsJsonArray();
 | 
			
		||||
      visitor.visitArrayMember(parent, childAsArray, isFirst);
 | 
			
		||||
      navigate(childAsArray);
 | 
			
		||||
    } else if (child.isJsonObject()) {
 | 
			
		||||
      JsonObject childAsObject = child.getAsJsonObject();
 | 
			
		||||
      visitor.visitArrayMember(parent, childAsObject, isFirst);
 | 
			
		||||
      navigate(childAsObject);
 | 
			
		||||
    } else { // is a JsonPrimitive
 | 
			
		||||
      visitor.visitArrayMember(parent, child.getAsJsonPrimitive(), isFirst);          
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								src/com/bukkit/mcteam/gson/LongSerializationPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/com/bukkit/mcteam/gson/LongSerializationPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines the expected format for a {@code long} or {@code Long} type when its serialized.
 | 
			
		||||
 *
 | 
			
		||||
 * @since 1.3
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
public enum LongSerializationPolicy {
 | 
			
		||||
  /**
 | 
			
		||||
   * This is the "default" serialization policy that will output a {@code long} object as a JSON
 | 
			
		||||
   * number.  For example, assume an object has a long field named "f" then the serialized output
 | 
			
		||||
   * would be:
 | 
			
		||||
   * {@code {"f":123}}.
 | 
			
		||||
   */
 | 
			
		||||
  DEFAULT(new DefaultStrategy()),
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Serializes a long value as a quoted string.  For example, assume an object has a long field 
 | 
			
		||||
   * named "f" then the serialized output would be:
 | 
			
		||||
   * {@code {"f":"123"}}.
 | 
			
		||||
   */
 | 
			
		||||
  STRING(new StringStrategy());
 | 
			
		||||
  
 | 
			
		||||
  private final Strategy strategy;
 | 
			
		||||
  
 | 
			
		||||
  private LongSerializationPolicy(Strategy strategy) {
 | 
			
		||||
    this.strategy = strategy;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Serialize this {@code value} using this serialization policy.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value the long value to be serialized into a {@link JsonElement}
 | 
			
		||||
   * @return the serialized version of {@code value}
 | 
			
		||||
   */
 | 
			
		||||
  public JsonElement serialize(Long value) {
 | 
			
		||||
    return strategy.serialize(value);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  private interface Strategy {
 | 
			
		||||
    JsonElement serialize(Long value);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  private static class DefaultStrategy implements Strategy {
 | 
			
		||||
    public JsonElement serialize(Long value) {
 | 
			
		||||
      return new JsonPrimitive(value);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  private static class StringStrategy implements Strategy {
 | 
			
		||||
    public JsonElement serialize(Long value) {
 | 
			
		||||
      return new JsonPrimitive(String.valueOf(value));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that ensures the JSON field names consist of only
 | 
			
		||||
 * lower case letters and are separated by a particular {@code separatorString}.
 | 
			
		||||
 *
 | 
			
		||||
 *<p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class StringWrapper {
 | 
			
		||||
 *   public String AStringField = "abcd";
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * LowerCamelCaseSeparatorNamingPolicy policy = new LowerCamelCaseSeparatorNamingPolicy("_");
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(StringWrapper.class.getField("AStringField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("a_string_field".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class LowerCamelCaseSeparatorNamingPolicy extends CompositionFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  public LowerCamelCaseSeparatorNamingPolicy(String separatorString) {
 | 
			
		||||
    super(new CamelCaseSeparatorNamingPolicy(separatorString), new LowerCaseNamingPolicy());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								src/com/bukkit/mcteam/gson/LowerCaseNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/com/bukkit/mcteam/gson/LowerCaseNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that ensures the JSON field names consist of only
 | 
			
		||||
 * lower case letters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IntWrapper {
 | 
			
		||||
 *   public int integerField = 0;
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * LowerCaseNamingPolicy policy = new LowerCaseNamingPolicy();
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(IntWrapper.class.getField("integerField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("integerfield".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class LowerCaseNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType,
 | 
			
		||||
      Collection<Annotation> annotations) {
 | 
			
		||||
    return target.toLowerCase();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/com/bukkit/mcteam/gson/LruCache.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/com/bukkit/mcteam/gson/LruCache.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An implementation of the {@link Cache} interface that evict objects from the cache using an
 | 
			
		||||
 * LRU (least recently used) algorithm.  Object start getting evicted from the cache once the
 | 
			
		||||
 * {@code maxCapacity} is reached.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class LruCache<K, V> extends LinkedHashMap<K, V> implements Cache<K, V> {
 | 
			
		||||
  private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
  private final int maxCapacity;
 | 
			
		||||
 | 
			
		||||
  LruCache(int maxCapacity) {
 | 
			
		||||
    super(maxCapacity, 0.7F, true);
 | 
			
		||||
    this.maxCapacity = maxCapacity;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void addElement(K key, V value) {
 | 
			
		||||
    put(key, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void clear() {
 | 
			
		||||
    super.clear();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public V getElement(K key) {
 | 
			
		||||
    return get(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public 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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										168
									
								
								src/com/bukkit/mcteam/gson/MapAsArrayTypeAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								src/com/bukkit/mcteam/gson/MapAsArrayTypeAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adapts maps containing complex keys as arrays of map entries.
 | 
			
		||||
 *
 | 
			
		||||
 * <h3>Maps as JSON objects</h3>
 | 
			
		||||
 * The standard GSON map type adapter converts Java {@link Map Maps} to JSON
 | 
			
		||||
 * Objects. This requires that map keys can be serialized as strings; this is
 | 
			
		||||
 * insufficient for some key types. For example, consider a map whose keys are
 | 
			
		||||
 * points on a grid. The default JSON form encodes reasonably: <pre>   {@code
 | 
			
		||||
 *   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>
 | 
			
		||||
 * 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>
 | 
			
		||||
 *
 | 
			
		||||
 * <h3>Maps as JSON arrays</h3>
 | 
			
		||||
 * An alternative approach taken by this type adapter is to encode maps as
 | 
			
		||||
 * arrays of map entries. Each map entry is a two element array containing a key
 | 
			
		||||
 * and a value. This approach is more flexible because any type can be used as
 | 
			
		||||
 * the map's key; not just strings. But it's also less portable because the
 | 
			
		||||
 * receiver of such JSON must be aware of the map entry convention.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Register this adapter when you are creating your GSON instance.
 | 
			
		||||
 * <pre>   {@code
 | 
			
		||||
 *   Gson gson = new GsonBuilder()
 | 
			
		||||
 *     .registerTypeAdapter(Map.class, new MapAsArrayTypeAdapter())
 | 
			
		||||
 *     .create();
 | 
			
		||||
 * }</pre>
 | 
			
		||||
 * This will change the structure of the JSON emitted by the code above. Now we
 | 
			
		||||
 * get an array. In this case the arrays elements are map entries:
 | 
			
		||||
 * <pre>   {@code
 | 
			
		||||
 *   [
 | 
			
		||||
 *     [
 | 
			
		||||
 *       {
 | 
			
		||||
 *         "x": 5,
 | 
			
		||||
 *         "y": 6
 | 
			
		||||
 *       },
 | 
			
		||||
 *       "a",
 | 
			
		||||
 *     ],
 | 
			
		||||
 *     [
 | 
			
		||||
 *       {
 | 
			
		||||
 *         "x": 8,
 | 
			
		||||
 *         "y": 8
 | 
			
		||||
 *       },
 | 
			
		||||
 *       "b"
 | 
			
		||||
 *     ]
 | 
			
		||||
 *   ]
 | 
			
		||||
 * }</pre>
 | 
			
		||||
 * This format will serialize and deserialize just fine as long as this adapter
 | 
			
		||||
 * is registered.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This adapter returns regular JSON objects for maps whose keys are not
 | 
			
		||||
 * complex. A key is complex if its JSON-serialized form is an array or an
 | 
			
		||||
 * object.
 | 
			
		||||
 */
 | 
			
		||||
public final class MapAsArrayTypeAdapter
 | 
			
		||||
    implements JsonSerializer<Map<?, ?>>, JsonDeserializer<Map<?, ?>> {
 | 
			
		||||
 | 
			
		||||
  public Map<?, ?> deserialize(JsonElement json, Type typeOfT,
 | 
			
		||||
      JsonDeserializationContext context) throws JsonParseException {
 | 
			
		||||
    Map<Object, Object> result = new LinkedHashMap<Object, Object>();
 | 
			
		||||
    Type[] keyAndValueType = typeToTypeArguments(typeOfT);
 | 
			
		||||
    if (json.isJsonArray()) {
 | 
			
		||||
      JsonArray array = json.getAsJsonArray();
 | 
			
		||||
      for (int i = 0; i < array.size(); i++) {
 | 
			
		||||
        JsonArray entryArray = array.get(i).getAsJsonArray();
 | 
			
		||||
        Object k = context.deserialize(entryArray.get(0), keyAndValueType[0]);
 | 
			
		||||
        Object v = context.deserialize(entryArray.get(1), keyAndValueType[1]);
 | 
			
		||||
        result.put(k, v);
 | 
			
		||||
      }
 | 
			
		||||
      checkSize(array, array.size(), result, result.size());
 | 
			
		||||
    } else {
 | 
			
		||||
      JsonObject object = json.getAsJsonObject();
 | 
			
		||||
      for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
 | 
			
		||||
        Object k = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueType[0]);
 | 
			
		||||
        Object v = context.deserialize(entry.getValue(), keyAndValueType[1]);
 | 
			
		||||
        result.put(k, v);
 | 
			
		||||
      }
 | 
			
		||||
      checkSize(object, object.entrySet().size(), result, result.size());
 | 
			
		||||
    }
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public JsonElement serialize(Map<?, ?> src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
    Type[] keyAndValueType = typeToTypeArguments(typeOfSrc);
 | 
			
		||||
    boolean serializeAsArray = false;
 | 
			
		||||
    List<JsonElement> keysAndValues = new ArrayList<JsonElement>();
 | 
			
		||||
    for (Map.Entry<?, ?> entry : src.entrySet()) {
 | 
			
		||||
      JsonElement key = context.serialize(entry.getKey(), keyAndValueType[0]);
 | 
			
		||||
      serializeAsArray |= key.isJsonObject() || key.isJsonArray();
 | 
			
		||||
      keysAndValues.add(key);
 | 
			
		||||
      keysAndValues.add(context.serialize(entry.getValue(), keyAndValueType[1]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (serializeAsArray) {
 | 
			
		||||
      JsonArray result = new JsonArray();
 | 
			
		||||
      for (int i = 0; i < keysAndValues.size(); i+=2) {
 | 
			
		||||
        JsonArray entryArray = new JsonArray();
 | 
			
		||||
        entryArray.add(keysAndValues.get(i));
 | 
			
		||||
        entryArray.add(keysAndValues.get(i + 1));
 | 
			
		||||
        result.add(entryArray);
 | 
			
		||||
      }
 | 
			
		||||
      return result;
 | 
			
		||||
    } else {
 | 
			
		||||
      JsonObject result = new JsonObject();
 | 
			
		||||
      for (int i = 0; i < keysAndValues.size(); i+=2) {
 | 
			
		||||
        result.add(keysAndValues.get(i).getAsString(), keysAndValues.get(i + 1));
 | 
			
		||||
      }
 | 
			
		||||
      checkSize(src, src.size(), result, result.entrySet().size());
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Type[] typeToTypeArguments(Type typeOfT) {
 | 
			
		||||
    if (typeOfT instanceof ParameterizedType) {
 | 
			
		||||
      Type[] typeArguments = ((ParameterizedType) typeOfT).getActualTypeArguments();
 | 
			
		||||
      if (typeArguments.length != 2) {
 | 
			
		||||
        throw new IllegalArgumentException("MapAsArrayTypeAdapter cannot handle " + typeOfT);
 | 
			
		||||
      }
 | 
			
		||||
      return typeArguments;
 | 
			
		||||
    }
 | 
			
		||||
    return new Type[] { Object.class, Object.class };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void checkSize(Object input, int inputSize, Object output, int outputSize) {
 | 
			
		||||
    if (inputSize != outputSize) {
 | 
			
		||||
      throw new JsonSyntaxException("Input size " + inputSize + " != output size " + outputSize
 | 
			
		||||
          + " for input " + input + " and output " + output);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								src/com/bukkit/mcteam/gson/MappedObjectConstructor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/com/bukkit/mcteam/gson/MappedObjectConstructor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.AccessibleObject;
 | 
			
		||||
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
 | 
			
		||||
 * {@link InstanceCreator} instances.  Registering an {@link InstanceCreator}
 | 
			
		||||
 * with this class will override the default object creation that is defined
 | 
			
		||||
 * by the ObjectConstructor that this class is wrapping.  Using this class
 | 
			
		||||
 * with the JSON framework provides the application with "pluggable" modules
 | 
			
		||||
 * to customize framework to suit the application's needs.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class MappedObjectConstructor implements ObjectConstructor {
 | 
			
		||||
  private static final Logger log = Logger.getLogger(MappedObjectConstructor.class.getName());
 | 
			
		||||
 | 
			
		||||
  private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap;
 | 
			
		||||
  
 | 
			
		||||
  public MappedObjectConstructor(
 | 
			
		||||
      ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators) {
 | 
			
		||||
    instanceCreatorMap = instanceCreators;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  public <T> T construct(Type typeOfT) {
 | 
			
		||||
    InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT);
 | 
			
		||||
    if (creator != null) {
 | 
			
		||||
      return creator.createInstance(typeOfT);
 | 
			
		||||
    }
 | 
			
		||||
    return (T) constructWithNoArgConstructor(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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @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;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    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() {
 | 
			
		||||
    return instanceCreatorMap.toString();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								src/com/bukkit/mcteam/gson/MemoryRefStack.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/com/bukkit/mcteam/gson/MemoryRefStack.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.util.Stack;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A stack data structure that only does a memory reference comparison
 | 
			
		||||
 * when looking for a particular item in the stack.  This stack does
 | 
			
		||||
 * not allow {@code null} values to be added.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class MemoryRefStack {
 | 
			
		||||
  private final Stack<ObjectTypePair> stack = new Stack<ObjectTypePair>();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adds a new element to the top of the stack.
 | 
			
		||||
   *
 | 
			
		||||
   * @param obj the object to add to the stack
 | 
			
		||||
   * @return the object that was added
 | 
			
		||||
   */
 | 
			
		||||
  public ObjectTypePair push(ObjectTypePair obj) {
 | 
			
		||||
    Preconditions.checkNotNull(obj);
 | 
			
		||||
 | 
			
		||||
    return stack.push(obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Removes the top element from the stack.
 | 
			
		||||
   *
 | 
			
		||||
   * @return the element being removed from the stack
 | 
			
		||||
   * @throws java.util.EmptyStackException thrown if the stack is empty
 | 
			
		||||
   */
 | 
			
		||||
  public ObjectTypePair pop() {
 | 
			
		||||
    return stack.pop();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isEmpty() {
 | 
			
		||||
    return stack.isEmpty();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieves the item from the top of the stack, but does not remove it.
 | 
			
		||||
   *
 | 
			
		||||
   * @return the item from the top of the stack
 | 
			
		||||
   * @throws java.util.EmptyStackException thrown if the stack is empty
 | 
			
		||||
   */
 | 
			
		||||
  public ObjectTypePair peek() {
 | 
			
		||||
    return stack.peek();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Performs a memory reference check to see it the {@code obj} exists in
 | 
			
		||||
   * the stack.
 | 
			
		||||
   *
 | 
			
		||||
   * @param obj the object to search for in the stack
 | 
			
		||||
   * @return true if this object is already in the stack otherwise false
 | 
			
		||||
   */
 | 
			
		||||
  public boolean contains(ObjectTypePair obj) {
 | 
			
		||||
    if (obj == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (ObjectTypePair stackObject : stack) {
 | 
			
		||||
      if (stackObject.getObject() == obj.getObject()
 | 
			
		||||
          && stackObject.type.equals(obj.type) ) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exclude fields based on particular field modifiers.  For a list of possible
 | 
			
		||||
 * modifiers, see {@link java.lang.reflect.Modifier}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class ModifierBasedExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
  private final Collection<Integer> modifiers;
 | 
			
		||||
 | 
			
		||||
  public ModifierBasedExclusionStrategy(int... modifiers) {
 | 
			
		||||
    this.modifiers = new HashSet<Integer>();
 | 
			
		||||
    if (modifiers != null) {
 | 
			
		||||
      for (int modifier : modifiers) {
 | 
			
		||||
        this.modifiers.add(modifier);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    for (int modifier : modifiers) {
 | 
			
		||||
      if (f.hasModifier(modifier)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								src/com/bukkit/mcteam/gson/ModifyFirstLetterNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/com/bukkit/mcteam/gson/ModifyFirstLetterNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that ensures the JSON field names begins with
 | 
			
		||||
 * an upper case letter.
 | 
			
		||||
 *
 | 
			
		||||
 *<p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class StringWrapper {
 | 
			
		||||
 *   public String stringField = "abcd";
 | 
			
		||||
 *   public String _stringField = "efg";
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * ModifyFirstLetterNamingPolicy policy =
 | 
			
		||||
 *     new ModifyFirstLetterNamingPolicy(LetterModifier.UPPER);
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(StringWrapper.class.getField("stringField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("StringField".equals(translatedFieldName));
 | 
			
		||||
 *
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(StringWrapper.class.getField("_stringField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("_StringField".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  public enum LetterModifier {
 | 
			
		||||
    UPPER,
 | 
			
		||||
    LOWER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private final LetterModifier letterModifier;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a new ModifyFirstLetterNamingPolicy that will either modify the first letter of the
 | 
			
		||||
   * target name to either UPPER case or LOWER case depending on the {@code modifier} parameter.
 | 
			
		||||
   *
 | 
			
		||||
   * @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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType,
 | 
			
		||||
      Collection<Annotation> annotations) {
 | 
			
		||||
    StringBuilder fieldNameBuilder = new StringBuilder();
 | 
			
		||||
    int index = 0;
 | 
			
		||||
    char firstCharacter = target.charAt(index);
 | 
			
		||||
 | 
			
		||||
    while (index < target.length() - 1) {
 | 
			
		||||
      if (Character.isLetter(firstCharacter)) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      fieldNameBuilder.append(firstCharacter);
 | 
			
		||||
      firstCharacter = target.charAt(++index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (index == target.length()) {
 | 
			
		||||
      return fieldNameBuilder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    boolean capitalizeFirstLetter = (letterModifier == LetterModifier.UPPER);
 | 
			
		||||
    if (capitalizeFirstLetter && !Character.isUpperCase(firstCharacter)) {
 | 
			
		||||
      String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), target, ++index);
 | 
			
		||||
      return fieldNameBuilder.append(modifiedTarget).toString();
 | 
			
		||||
    } else if (!capitalizeFirstLetter && Character.isUpperCase(firstCharacter)) {
 | 
			
		||||
      String modifiedTarget = modifyString(Character.toLowerCase(firstCharacter), target, ++index);
 | 
			
		||||
      return fieldNameBuilder.append(modifiedTarget).toString();
 | 
			
		||||
    } else {
 | 
			
		||||
      return target;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private String modifyString(char firstCharacter, String srcString, int indexOfSubstring) {
 | 
			
		||||
    return indexOfSubstring < srcString.length() ?
 | 
			
		||||
        firstCharacter + srcString.substring(indexOfSubstring)
 | 
			
		||||
        : String.valueOf(firstCharacter);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/com/bukkit/mcteam/gson/NullExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/com/bukkit/mcteam/gson/NullExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This acts as a "Null Object" pattern for the {@link ExclusionStrategy}.
 | 
			
		||||
 * Passing an instance of this class into the {@link ObjectNavigator} will
 | 
			
		||||
 * make the {@link ObjectNavigator} parse/visit every field of the object
 | 
			
		||||
 * being navigated.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class NullExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/com/bukkit/mcteam/gson/ObjectConstructor.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/com/bukkit/mcteam/gson/ObjectConstructor.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines a generic object construction factory.  The purpose of this class
 | 
			
		||||
 * is to construct a default instance of a class that can be used for object
 | 
			
		||||
 * navigation while deserialization from its JSON representation.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
interface ObjectConstructor {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a new instance of the given type.
 | 
			
		||||
   *
 | 
			
		||||
   * @param typeOfT the class type that should be instantiated
 | 
			
		||||
   * @return a default instance of the provided class.
 | 
			
		||||
   */
 | 
			
		||||
  public <T> T construct(Type typeOfT);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs an array type of the provided length.
 | 
			
		||||
   *
 | 
			
		||||
   * @param typeOfArrayElements type of objects in the array
 | 
			
		||||
   * @param length size of the array
 | 
			
		||||
   * @return new array of size length
 | 
			
		||||
   */
 | 
			
		||||
  public Object constructArray(Type typeOfArrayElements, int length);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								src/com/bukkit/mcteam/gson/ObjectNavigator.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/com/bukkit/mcteam/gson/ObjectNavigator.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.AccessibleObject;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides ability to apply a visitor to an object and all of its fields
 | 
			
		||||
 * recursively.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class ObjectNavigator {
 | 
			
		||||
 | 
			
		||||
  public interface Visitor {
 | 
			
		||||
    public void start(ObjectTypePair node);
 | 
			
		||||
 | 
			
		||||
    public void end(ObjectTypePair node);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called before the object navigator starts visiting the current
 | 
			
		||||
     * object
 | 
			
		||||
     */
 | 
			
		||||
    void startVisitingObject(Object node);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called to visit the current object if it is an array
 | 
			
		||||
     */
 | 
			
		||||
    void visitArray(Object array, Type componentType);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called to visit an object field of the current object
 | 
			
		||||
     */
 | 
			
		||||
    void visitObjectField(FieldAttributes f, Type typeOfF, Object obj);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called to visit an array field of the current object
 | 
			
		||||
     */
 | 
			
		||||
    void visitArrayField(FieldAttributes f, Type typeOfF, Object obj);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called to visit an object using a custom handler
 | 
			
		||||
     * 
 | 
			
		||||
     * @return true if a custom handler exists, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public boolean visitUsingCustomHandler(ObjectTypePair objTypePair);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This is called to visit a field of the current object using a custom
 | 
			
		||||
     * handler
 | 
			
		||||
     */
 | 
			
		||||
    public boolean visitFieldUsingCustomHandler(FieldAttributes f, Type actualTypeOfField,
 | 
			
		||||
        Object parent);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieve the current target
 | 
			
		||||
     */
 | 
			
		||||
    Object getTarget();
 | 
			
		||||
 | 
			
		||||
    void visitPrimitive(Object primitive);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private final ExclusionStrategy exclusionStrategy;
 | 
			
		||||
  private final ObjectTypePair objTypePair;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @param objTypePair
 | 
			
		||||
   *          The object,type (fully genericized) being navigated
 | 
			
		||||
   * @param exclusionStrategy
 | 
			
		||||
   *          the concrete 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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Navigate all the fields of the specified object. If a field is null, it
 | 
			
		||||
   * does not get visited.
 | 
			
		||||
   */
 | 
			
		||||
  public void accept(Visitor visitor) {
 | 
			
		||||
    TypeInfo objTypeInfo = new TypeInfo(objTypePair.type);
 | 
			
		||||
    if (exclusionStrategy.shouldSkipClass(objTypeInfo.getRawClass())) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
 | 
			
		||||
    if (!visitedWithCustomHandler) {
 | 
			
		||||
      Object obj = objTypePair.getObject();
 | 
			
		||||
      Object objectToVisit = (obj == null) ? visitor.getTarget() : obj;
 | 
			
		||||
      if (objectToVisit == null) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      objTypePair.setObject(objectToVisit);
 | 
			
		||||
      visitor.start(objTypePair);
 | 
			
		||||
      try {
 | 
			
		||||
        if (objTypeInfo.isArray()) {
 | 
			
		||||
          visitor.visitArray(objectToVisit, objTypePair.type);
 | 
			
		||||
        } else if (objTypeInfo.getActualType() == Object.class
 | 
			
		||||
            && isPrimitiveOrString(objectToVisit)) {
 | 
			
		||||
          // TODO(Joel): this is only used for deserialization of "primitives"
 | 
			
		||||
          // we should rethink this!!!
 | 
			
		||||
          visitor.visitPrimitive(objectToVisit);
 | 
			
		||||
          objectToVisit = 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);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } finally {
 | 
			
		||||
        visitor.end(objTypePair);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private 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);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/com/bukkit/mcteam/gson/ObjectNavigatorFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/com/bukkit/mcteam/gson/ObjectNavigatorFactory.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										136
									
								
								src/com/bukkit/mcteam/gson/ObjectTypePair.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/com/bukkit/mcteam/gson/ObjectTypePair.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A holder class for an object and its type
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 */
 | 
			
		||||
final class ObjectTypePair {
 | 
			
		||||
  private Object obj;
 | 
			
		||||
  final Type type;
 | 
			
		||||
  private final boolean preserveType;
 | 
			
		||||
 | 
			
		||||
  ObjectTypePair(Object obj, Type type, boolean preserveType) {
 | 
			
		||||
    this.obj = obj;
 | 
			
		||||
    this.type = type;
 | 
			
		||||
    this.preserveType = preserveType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Object getObject() {
 | 
			
		||||
    return obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void setObject(Object obj) {
 | 
			
		||||
    this.obj = obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Type getType() {
 | 
			
		||||
    return type;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String toString() {
 | 
			
		||||
    return String.format("preserveType: %b, type: %s, obj: %s", preserveType, type, obj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  <HANDLER> Pair<HANDLER, ObjectTypePair> getMatchingHandler(
 | 
			
		||||
      ParameterizedTypeHandlerMap<HANDLER> handlers) {
 | 
			
		||||
    HANDLER handler = null;
 | 
			
		||||
    if (!preserveType && obj != null) {
 | 
			
		||||
      // First try looking up the handler for the actual type
 | 
			
		||||
      ObjectTypePair moreSpecificType = toMoreSpecificType();    
 | 
			
		||||
      handler = handlers.getHandlerFor(moreSpecificType.type);
 | 
			
		||||
      if (handler != null) {
 | 
			
		||||
        return new Pair<HANDLER, ObjectTypePair>(handler, moreSpecificType);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Try the specified type
 | 
			
		||||
    handler = handlers.getHandlerFor(type);
 | 
			
		||||
    return handler == null ? null : new Pair<HANDLER, ObjectTypePair>(handler, this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ObjectTypePair toMoreSpecificType() {    
 | 
			
		||||
    if (preserveType || obj == null) {
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
    Type actualType = getActualTypeIfMoreSpecific(type, obj.getClass());
 | 
			
		||||
    if (actualType == type) {
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
    return new ObjectTypePair(obj, actualType, preserveType);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 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 
 | 
			
		||||
  // the actual object is of a raw type (which is a sub-class of the generic type).
 | 
			
		||||
  static Type getActualTypeIfMoreSpecific(Type type, Class<?> actualClass) {
 | 
			
		||||
    if (type instanceof Class<?>) {
 | 
			
		||||
      Class<?> typeAsClass = (Class<?>) type;
 | 
			
		||||
      if (typeAsClass.isAssignableFrom(actualClass)) {
 | 
			
		||||
        type = actualClass;
 | 
			
		||||
      }
 | 
			
		||||
      if (type == Object.class) {
 | 
			
		||||
        type = actualClass;
 | 
			
		||||
      } 
 | 
			
		||||
    }
 | 
			
		||||
    return type;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int hashCode() {
 | 
			
		||||
    // Not using type.hashCode() since I am not sure if the subclasses of type reimplement
 | 
			
		||||
    // hashCode() to be equal for equal types
 | 
			
		||||
    return ((obj == null) ? 31 : obj.hashCode());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean equals(Object obj) {
 | 
			
		||||
    if (this == obj) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (obj == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (getClass() != obj.getClass()) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    ObjectTypePair other = (ObjectTypePair) obj;
 | 
			
		||||
    if (this.obj == null) {
 | 
			
		||||
      if (other.obj != null) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (this.obj != other.obj) { // Checking for reference equality
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (type == null) {
 | 
			
		||||
      if (other.type != null) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (!type.equals(other.type)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    return preserveType == other.preserveType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isPreserveType() {
 | 
			
		||||
    return preserveType;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								src/com/bukkit/mcteam/gson/Pair.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/com/bukkit/mcteam/gson/Pair.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple object that holds onto a pair of object references, first and second.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @param <FIRST>
 | 
			
		||||
 * @param <SECOND>
 | 
			
		||||
 */
 | 
			
		||||
final class Pair<FIRST, SECOND> {
 | 
			
		||||
 | 
			
		||||
  final FIRST first;
 | 
			
		||||
  final SECOND second;
 | 
			
		||||
 | 
			
		||||
  Pair(FIRST first, SECOND second) {
 | 
			
		||||
    this.first = first;
 | 
			
		||||
    this.second = second;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int hashCode() {
 | 
			
		||||
    return 17 * ((first != null) ? first.hashCode() : 0)
 | 
			
		||||
        + 17 * ((second != null) ? second.hashCode() : 0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean equals(Object o) {
 | 
			
		||||
    if (!(o instanceof Pair<?, ?>)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Pair<?, ?> that = (Pair<?, ?>) o;
 | 
			
		||||
    return equal(this.first, that.first) && equal(this.second, that.second);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static boolean equal(Object a, Object b) {
 | 
			
		||||
    return a == b || (a != null && a.equals(b));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String toString() {
 | 
			
		||||
    return String.format("{%s,%s}", first, second);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										200
									
								
								src/com/bukkit/mcteam/gson/ParameterizedTypeHandlerMap.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								src/com/bukkit/mcteam/gson/ParameterizedTypeHandlerMap.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,200 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A map that provides ability to associate handlers for a specific type or all
 | 
			
		||||
 * of its sub-types
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * 
 | 
			
		||||
 * @param <T> The handler that will be looked up by type
 | 
			
		||||
 */
 | 
			
		||||
final class ParameterizedTypeHandlerMap<T> {
 | 
			
		||||
  private static final Logger logger =
 | 
			
		||||
      Logger.getLogger(ParameterizedTypeHandlerMap.class.getName());
 | 
			
		||||
  private final Map<Type, T> map = new HashMap<Type, T>();
 | 
			
		||||
  private final List<Pair<Class<?>, T>> typeHierarchyList = new ArrayList<Pair<Class<?>, T>>();
 | 
			
		||||
  private boolean modifiable = true;
 | 
			
		||||
 | 
			
		||||
  public synchronized void registerForTypeHierarchy(Class<?> typeOfT, T value) {
 | 
			
		||||
    Pair<Class<?>, T> pair = new Pair<Class<?>, T>(typeOfT, value);
 | 
			
		||||
    registerForTypeHierarchy(pair);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void registerForTypeHierarchy(Pair<Class<?>, T> pair) {
 | 
			
		||||
    if (!modifiable) {
 | 
			
		||||
      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
 | 
			
		||||
    }
 | 
			
		||||
    int index = getIndexOfSpecificHandlerForTypeHierarchy(pair.first);
 | 
			
		||||
    if (index >= 0) {
 | 
			
		||||
      logger.log(Level.WARNING, "Overriding the existing type handler for {0}", pair.first);
 | 
			
		||||
      typeHierarchyList.remove(index);
 | 
			
		||||
    }
 | 
			
		||||
    index = getIndexOfAnOverriddenHandler(pair.first);
 | 
			
		||||
    if (index >= 0) {
 | 
			
		||||
      throw new IllegalArgumentException("The specified type handler for type " + pair.first
 | 
			
		||||
          + " hides the previously registered type hierarchy handler for "
 | 
			
		||||
          + typeHierarchyList.get(index).first + ". Gson does not allow this.");
 | 
			
		||||
    }
 | 
			
		||||
    // We want stack behavior for adding to this list. A type adapter added subsequently should
 | 
			
		||||
    // override a previously registered one.
 | 
			
		||||
    typeHierarchyList.add(0, pair);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private int getIndexOfAnOverriddenHandler(Class<?> type) {
 | 
			
		||||
    for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
 | 
			
		||||
      Pair<Class<?>, T> entry = typeHierarchyList.get(i);
 | 
			
		||||
      if (type.isAssignableFrom(entry.first)) {
 | 
			
		||||
        return i;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void register(Type typeOfT, T value) {
 | 
			
		||||
    if (!modifiable) {
 | 
			
		||||
      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
 | 
			
		||||
    }
 | 
			
		||||
    if (hasSpecificHandlerFor(typeOfT)) {
 | 
			
		||||
      logger.log(Level.WARNING, "Overriding the existing type handler for {0}", typeOfT);
 | 
			
		||||
    }
 | 
			
		||||
    map.put(typeOfT, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void registerIfAbsent(ParameterizedTypeHandlerMap<T> other) {
 | 
			
		||||
    if (!modifiable) {
 | 
			
		||||
      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
 | 
			
		||||
    }
 | 
			
		||||
    for (Map.Entry<Type, T> entry : other.map.entrySet()) {
 | 
			
		||||
      if (!map.containsKey(entry.getKey())) {
 | 
			
		||||
        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);
 | 
			
		||||
      int index = getIndexOfSpecificHandlerForTypeHierarchy(entry.first);
 | 
			
		||||
      if (index < 0) {
 | 
			
		||||
        registerForTypeHierarchy(entry);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void registerIfAbsent(Type typeOfT, T value) {
 | 
			
		||||
    if (!modifiable) {
 | 
			
		||||
      throw new IllegalStateException("Attempted to modify an unmodifiable map.");
 | 
			
		||||
    }
 | 
			
		||||
    if (!map.containsKey(typeOfT)) {
 | 
			
		||||
      register(typeOfT, value);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized void makeUnmodifiable() {
 | 
			
		||||
    modifiable = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized T getHandlerFor(Type type) {
 | 
			
		||||
    T handler = map.get(type);
 | 
			
		||||
    if (handler == null) {
 | 
			
		||||
      Class<?> rawClass = TypeUtils.toRawClass(type);
 | 
			
		||||
      if (rawClass != type) {
 | 
			
		||||
        handler = getHandlerFor(rawClass);
 | 
			
		||||
      }
 | 
			
		||||
      if (handler == null) {
 | 
			
		||||
        // check if something registered for type hierarchy
 | 
			
		||||
        handler = getHandlerForTypeHierarchy(rawClass);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return handler;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private T getHandlerForTypeHierarchy(Class<?> type) {
 | 
			
		||||
    for (Pair<Class<?>, T> entry : typeHierarchyList) {
 | 
			
		||||
      if (entry.first.isAssignableFrom(type)) {
 | 
			
		||||
        return entry.second;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public synchronized boolean hasSpecificHandlerFor(Type type) {
 | 
			
		||||
    return map.containsKey(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private synchronized int getIndexOfSpecificHandlerForTypeHierarchy(Class<?> type) {
 | 
			
		||||
    for (int i = typeHierarchyList.size()-1; i >= 0; --i) {
 | 
			
		||||
      if (type.equals(typeHierarchyList.get(i).first)) {
 | 
			
		||||
        return i;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
    }
 | 
			
		||||
    return copy;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String toString() {
 | 
			
		||||
    StringBuilder sb = new StringBuilder("{mapForTypeHierarchy:{");
 | 
			
		||||
    boolean first = true;
 | 
			
		||||
    for (Pair<Class<?>, T> entry : typeHierarchyList) {
 | 
			
		||||
      if (first) {
 | 
			
		||||
        first = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        sb.append(',');
 | 
			
		||||
      }
 | 
			
		||||
      sb.append(typeToString(entry.first)).append(':');
 | 
			
		||||
      sb.append(entry.second);
 | 
			
		||||
    }
 | 
			
		||||
    sb.append("},map:{");
 | 
			
		||||
    first = true;
 | 
			
		||||
    for (Map.Entry<Type, T> entry : map.entrySet()) {
 | 
			
		||||
      if (first) {
 | 
			
		||||
        first = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        sb.append(',');
 | 
			
		||||
      }
 | 
			
		||||
      sb.append(typeToString(entry.getKey())).append(':');
 | 
			
		||||
      sb.append(entry.getValue());
 | 
			
		||||
    }
 | 
			
		||||
    sb.append("}");
 | 
			
		||||
    return sb.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private String typeToString(Type type) {
 | 
			
		||||
    return TypeUtils.toRawClass(type).getSimpleName();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										91
									
								
								src/com/bukkit/mcteam/gson/ParameterizedTypeImpl.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/com/bukkit/mcteam/gson/ParameterizedTypeImpl.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/com/bukkit/mcteam/gson/Preconditions.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/com/bukkit/mcteam/gson/Preconditions.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple utility class used to check method Preconditions.
 | 
			
		||||
 *
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public long divideBy(long value) {
 | 
			
		||||
 *   Preconditions.checkArgument(value != 0);
 | 
			
		||||
 *   return this.value / value;
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class Preconditions {
 | 
			
		||||
  public static void checkNotNull(Object obj) {
 | 
			
		||||
    checkArgument(obj != null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static void checkArgument(boolean condition) {
 | 
			
		||||
    if (!condition) {
 | 
			
		||||
      throw new IllegalArgumentException("condition failed: " + condition);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  public static void checkState(boolean condition) {
 | 
			
		||||
    if (!condition) {
 | 
			
		||||
      throw new IllegalArgumentException("condition failed: " + condition);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								src/com/bukkit/mcteam/gson/Primitives.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/com/bukkit/mcteam/gson/Primitives.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Contains static utility methods pertaining to primitive types and their
 | 
			
		||||
 * corresponding wrapper types.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kevin Bourrillion
 | 
			
		||||
 */
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
  /** A map from wrapper types to their corresponding primitive types. */
 | 
			
		||||
  public static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
 | 
			
		||||
 | 
			
		||||
  // Sad that we can't use a BiMap. :(
 | 
			
		||||
  
 | 
			
		||||
  static {
 | 
			
		||||
    Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
 | 
			
		||||
    Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
 | 
			
		||||
 | 
			
		||||
    add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, byte.class, Byte.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, char.class, Character.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, double.class, Double.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, float.class, Float.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, int.class, Integer.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, long.class, Long.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, short.class, Short.class);
 | 
			
		||||
    add(primToWrap, wrapToPrim, void.class, Void.class);
 | 
			
		||||
 | 
			
		||||
    PRIMITIVE_TO_WRAPPER_TYPE = Collections.unmodifiableMap(primToWrap);
 | 
			
		||||
    WRAPPER_TO_PRIMITIVE_TYPE = Collections.unmodifiableMap(wrapToPrim);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static void add(Map<Class<?>, Class<?>> forward,
 | 
			
		||||
      Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
 | 
			
		||||
    forward.put(key, value);
 | 
			
		||||
    backward.put(value, key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns {@code true} if {@code type} is one of the nine
 | 
			
		||||
   * primitive-wrapper types, such as {@link Integer}.
 | 
			
		||||
   *
 | 
			
		||||
   * @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;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 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 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);
 | 
			
		||||
    return (wrapped == null) ? type : wrapped;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the corresponding primitive type of {@code type} if it is a
 | 
			
		||||
   * wrapper type; otherwise returns {@code type} itself. Idempotent.
 | 
			
		||||
   * <pre>
 | 
			
		||||
   *     unwrap(Integer.class) == int.class
 | 
			
		||||
   *     unwrap(int.class) == int.class
 | 
			
		||||
   *     unwrap(String.class) == String.class
 | 
			
		||||
   * </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);
 | 
			
		||||
    return (unwrapped == null) ? type : unwrapped;
 | 
			
		||||
  }  
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/com/bukkit/mcteam/gson/RecursiveFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/com/bukkit/mcteam/gson/RecursiveFieldNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A mechanism for providing custom field naming in Gson.  This allows the client code to translate
 | 
			
		||||
 * field names into a particular convention that is not supported as a normal Java field
 | 
			
		||||
 * declaration rules.  For example, Java does not support "-" characters in a field name.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
abstract class RecursiveFieldNamingPolicy implements FieldNamingStrategy2 {
 | 
			
		||||
 | 
			
		||||
  public final String translateName(FieldAttributes f) {
 | 
			
		||||
    Preconditions.checkNotNull(f);
 | 
			
		||||
    return translateName(f.getName(), f.getDeclaredType(), f.getAnnotations());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Performs the specific string translation.
 | 
			
		||||
   *
 | 
			
		||||
   * @param target the string object that will be manipulation/translated
 | 
			
		||||
   * @param fieldType the actual type value of the field
 | 
			
		||||
   * @param annotations the annotations set on the field
 | 
			
		||||
   * @return the translated field name
 | 
			
		||||
   */
 | 
			
		||||
  protected abstract String translateName(String target, Type fieldType, Collection<Annotation> annotations);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,48 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.annotations.SerializedName;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that acts as a chain of responsibility.  If the
 | 
			
		||||
 * {@link com.bukkit.mcteam.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>
 | 
			
		||||
 *
 | 
			
		||||
 * @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) {
 | 
			
		||||
    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());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								src/com/bukkit/mcteam/gson/Streams.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/com/bukkit/mcteam/gson/Streams.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonReader;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.JsonWriter;
 | 
			
		||||
import com.bukkit.mcteam.gson.stream.MalformedJsonException;
 | 
			
		||||
import java.io.EOFException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads and writes GSON parse trees over streams.
 | 
			
		||||
 */
 | 
			
		||||
final class Streams {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Takes a reader in any state and returns the next value as a JsonElement.
 | 
			
		||||
   */
 | 
			
		||||
  static JsonElement parse(JsonReader reader) throws JsonParseException {
 | 
			
		||||
    boolean isEmpty = true;
 | 
			
		||||
    try {
 | 
			
		||||
      reader.peek();
 | 
			
		||||
      isEmpty = false;
 | 
			
		||||
      return parseRecursive(reader);
 | 
			
		||||
    } catch (EOFException e) {
 | 
			
		||||
      /*
 | 
			
		||||
       * For compatibility with JSON 1.5 and earlier, we return a JsonNull for
 | 
			
		||||
       * empty documents instead of throwing.
 | 
			
		||||
       */
 | 
			
		||||
      if (isEmpty) {
 | 
			
		||||
        return JsonNull.createJsonNull();
 | 
			
		||||
      }
 | 
			
		||||
      throw new JsonIOException(e);
 | 
			
		||||
    } catch (MalformedJsonException e) {
 | 
			
		||||
      throw new JsonSyntaxException(e);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new JsonIOException(e);
 | 
			
		||||
    } catch (NumberFormatException e) {
 | 
			
		||||
      throw new JsonSyntaxException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private static JsonElement parseRecursive(JsonReader reader) throws IOException {
 | 
			
		||||
    switch (reader.peek()) {
 | 
			
		||||
    case STRING:
 | 
			
		||||
      return new JsonPrimitive(reader.nextString());
 | 
			
		||||
    case NUMBER:
 | 
			
		||||
      String number = reader.nextString();
 | 
			
		||||
      return new JsonPrimitive(JsonPrimitive.stringToNumber(number));
 | 
			
		||||
    case BOOLEAN:
 | 
			
		||||
      return new JsonPrimitive(reader.nextBoolean());
 | 
			
		||||
    case NULL:
 | 
			
		||||
      reader.nextNull();
 | 
			
		||||
      return JsonNull.createJsonNull();
 | 
			
		||||
    case BEGIN_ARRAY:
 | 
			
		||||
      JsonArray array = new JsonArray();
 | 
			
		||||
      reader.beginArray();
 | 
			
		||||
      while (reader.hasNext()) {
 | 
			
		||||
        array.add(parseRecursive(reader));
 | 
			
		||||
      }
 | 
			
		||||
      reader.endArray();
 | 
			
		||||
      return array;
 | 
			
		||||
    case BEGIN_OBJECT:
 | 
			
		||||
      JsonObject object = new JsonObject();
 | 
			
		||||
      reader.beginObject();
 | 
			
		||||
      while (reader.hasNext()) {
 | 
			
		||||
        object.add(reader.nextName(), parseRecursive(reader));
 | 
			
		||||
      }
 | 
			
		||||
      reader.endObject();
 | 
			
		||||
      return object;
 | 
			
		||||
    case END_DOCUMENT:
 | 
			
		||||
    case NAME:
 | 
			
		||||
    case END_OBJECT:
 | 
			
		||||
    case END_ARRAY:
 | 
			
		||||
    default:
 | 
			
		||||
      throw new IllegalArgumentException();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Writes the JSON element to the writer, recursively.
 | 
			
		||||
   */
 | 
			
		||||
  static void write(JsonElement element, boolean serializeNulls, JsonWriter writer)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    if (element == null || element.isJsonNull()) {
 | 
			
		||||
      if (serializeNulls) {
 | 
			
		||||
        writer.nullValue();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else if (element.isJsonPrimitive()) {
 | 
			
		||||
      JsonPrimitive primitive = element.getAsJsonPrimitive();
 | 
			
		||||
      if (primitive.isNumber()) {
 | 
			
		||||
        writer.value(primitive.getAsNumber());
 | 
			
		||||
      } else if (primitive.isBoolean()) {
 | 
			
		||||
        writer.value(primitive.getAsBoolean());
 | 
			
		||||
      } else {
 | 
			
		||||
        writer.value(primitive.getAsString());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else if (element.isJsonArray()) {
 | 
			
		||||
      writer.beginArray();
 | 
			
		||||
      for (JsonElement e : element.getAsJsonArray()) {
 | 
			
		||||
        /* always print null when its parent element is an array! */
 | 
			
		||||
        if (e.isJsonNull()) {
 | 
			
		||||
          writer.nullValue();
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
        write(e, serializeNulls, writer);
 | 
			
		||||
      }
 | 
			
		||||
      writer.endArray();
 | 
			
		||||
 | 
			
		||||
    } else if (element.isJsonObject()) {
 | 
			
		||||
      writer.beginObject();
 | 
			
		||||
      for (Map.Entry<String, JsonElement> e : element.getAsJsonObject().entrySet()) {
 | 
			
		||||
        JsonElement value = e.getValue();
 | 
			
		||||
        if (!serializeNulls && value.isJsonNull()) {
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
        writer.name(e.getKey());
 | 
			
		||||
        write(value, serializeNulls, writer);
 | 
			
		||||
      }
 | 
			
		||||
      writer.endObject();
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      throw new IllegalArgumentException("Couldn't write " + element.getClass());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static Writer writerForAppendable(Appendable appendable) {
 | 
			
		||||
    return appendable instanceof Writer ? (Writer) appendable : new AppendableWriter(appendable);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Adapts an {@link Appendable} so it can be passed anywhere a {@link Writer}
 | 
			
		||||
   * is used.
 | 
			
		||||
   */
 | 
			
		||||
  private static class AppendableWriter extends Writer {
 | 
			
		||||
    private final Appendable appendable;
 | 
			
		||||
    private final CurrentWrite currentWrite = new CurrentWrite();
 | 
			
		||||
 | 
			
		||||
    private AppendableWriter(Appendable appendable) {
 | 
			
		||||
      this.appendable = appendable;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override public void write(char[] chars, int offset, int length) throws IOException {
 | 
			
		||||
      currentWrite.chars = chars;
 | 
			
		||||
      appendable.append(currentWrite, offset, offset + length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override public void write(int i) throws IOException {
 | 
			
		||||
      appendable.append((char) i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override public void flush() {}
 | 
			
		||||
    @Override public void close() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A mutable char sequence pointing at a single char[].
 | 
			
		||||
     */
 | 
			
		||||
    static class CurrentWrite implements CharSequence {
 | 
			
		||||
      char[] chars;
 | 
			
		||||
      public int length() {
 | 
			
		||||
        return chars.length;
 | 
			
		||||
      }
 | 
			
		||||
      public char charAt(int i) {
 | 
			
		||||
        return chars[i];
 | 
			
		||||
      }
 | 
			
		||||
      public CharSequence subSequence(int start, int end) {
 | 
			
		||||
        return new String(chars, start, end - start);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2009 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A data object that stores attributes of a field.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This class is immutable; therefore, it can be safely shared across threads.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 *
 | 
			
		||||
 * @since 1.4
 | 
			
		||||
 */
 | 
			
		||||
class SyntheticFieldExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
  private final boolean skipSyntheticFields;
 | 
			
		||||
 | 
			
		||||
  SyntheticFieldExclusionStrategy(boolean skipSyntheticFields) {
 | 
			
		||||
    this.skipSyntheticFields = skipSyntheticFields;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    return skipSyntheticFields && f.isSynthetic();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/com/bukkit/mcteam/gson/TypeAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/com/bukkit/mcteam/gson/TypeAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								src/com/bukkit/mcteam/gson/TypeInfo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/com/bukkit/mcteam/gson/TypeInfo.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/com/bukkit/mcteam/gson/TypeInfoArray.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/com/bukkit/mcteam/gson/TypeInfoArray.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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<String>[][] types, it will return the 
 | 
			
		||||
   * type representing Foo<String>[] 
 | 
			
		||||
   * (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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/com/bukkit/mcteam/gson/TypeInfoCollection.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/com/bukkit/mcteam/gson/TypeInfoCollection.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								src/com/bukkit/mcteam/gson/TypeInfoFactory.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								src/com/bukkit/mcteam/gson/TypeInfoFactory.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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!");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/com/bukkit/mcteam/gson/TypeInfoMap.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/com/bukkit/mcteam/gson/TypeInfoMap.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								src/com/bukkit/mcteam/gson/TypeUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/com/bukkit/mcteam/gson/TypeUtils.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.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
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that ensures the JSON field names consist of mixed
 | 
			
		||||
 * case letters starting with a capital and are separated by a particular
 | 
			
		||||
 * {@code separatorString}.
 | 
			
		||||
 *
 | 
			
		||||
 *<p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class StringWrapper {
 | 
			
		||||
 *   public String AStringField = "abcd";
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * UpperCamelCaseSeparatorNamingPolicy policy = new UpperCamelCaseSeparatorNamingPolicy("_");
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(StringWrapper.class.getField("AStringField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("A_String_Field".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class UpperCamelCaseSeparatorNamingPolicy extends CompositionFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  public UpperCamelCaseSeparatorNamingPolicy(String separatorString) {
 | 
			
		||||
    super(new CamelCaseSeparatorNamingPolicy(separatorString),
 | 
			
		||||
        new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/com/bukkit/mcteam/gson/UpperCaseNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/com/bukkit/mcteam/gson/UpperCaseNamingPolicy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link FieldNamingStrategy2} that ensures the JSON field names consist of only
 | 
			
		||||
 * upper case letters.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following is an example:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * class IntWrapper {
 | 
			
		||||
 *   public int integerField = 0;
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * UpperCaseNamingPolicy policy = new UpperCaseNamingPolicy();
 | 
			
		||||
 * String translatedFieldName =
 | 
			
		||||
 *     policy.translateName(IntWrapper.class.getField("integerField"));
 | 
			
		||||
 *
 | 
			
		||||
 * assert("INTEGERFIELD".equals(translatedFieldName));
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class UpperCaseNamingPolicy extends RecursiveFieldNamingPolicy {
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected String translateName(String target, Type fieldType, Collection<Annotation> annotations) {
 | 
			
		||||
    return target.toUpperCase();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								src/com/bukkit/mcteam/gson/VersionConstants.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/com/bukkit/mcteam/gson/VersionConstants.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class contain all constants for versioning support.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class VersionConstants {
 | 
			
		||||
  // Prevent instantiation
 | 
			
		||||
  private VersionConstants() { }
 | 
			
		||||
 | 
			
		||||
  static final double IGNORE_VERSIONS = -1D;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								src/com/bukkit/mcteam/gson/VersionExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/com/bukkit/mcteam/gson/VersionExclusionStrategy.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson;
 | 
			
		||||
 | 
			
		||||
import com.bukkit.mcteam.gson.annotations.Since;
 | 
			
		||||
import com.bukkit.mcteam.gson.annotations.Until;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This strategy will exclude any files and/or class that are passed the
 | 
			
		||||
 * {@link #version} value.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
final class VersionExclusionStrategy implements ExclusionStrategy {
 | 
			
		||||
  private final double version;
 | 
			
		||||
 | 
			
		||||
  public VersionExclusionStrategy(double version) {
 | 
			
		||||
    Preconditions.checkArgument(version >= 0.0D);
 | 
			
		||||
    this.version = version;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipField(FieldAttributes f) {
 | 
			
		||||
    return !isValidVersion(f.getAnnotation(Since.class), f.getAnnotation(Until.class));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean shouldSkipClass(Class<?> clazz) {
 | 
			
		||||
    return !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isValidVersion(Since since, Until until) {
 | 
			
		||||
    return (isValidSince(since) && isValidUntil(until));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isValidSince(Since annotation) {
 | 
			
		||||
    if (annotation != null) {
 | 
			
		||||
      double annotationVersion = annotation.value();
 | 
			
		||||
      if (annotationVersion > version) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean isValidUntil(Until annotation) {
 | 
			
		||||
    if (annotation != null) {
 | 
			
		||||
      double annotationVersion = annotation.value();
 | 
			
		||||
      if (annotationVersion <= version) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								src/com/bukkit/mcteam/gson/annotations/Expose.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/com/bukkit/mcteam/gson/annotations/Expose.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson.annotations;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An annotation that indicates this member should be exposed for JSON
 | 
			
		||||
 * serialization or deserialization.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This annotation has no effect unless you build {@link com.bukkit.mcteam.gson.Gson}
 | 
			
		||||
 * with a {@link com.bukkit.mcteam.gson.GsonBuilder} and invoke
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder#excludeFieldsWithoutExposeAnnotation()}
 | 
			
		||||
 * method.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Here is an example of how this annotation is meant to be used:
 | 
			
		||||
 * <p><pre>
 | 
			
		||||
 * public class User {
 | 
			
		||||
 *   @Expose private String firstName;
 | 
			
		||||
 *   @Expose(serialize = false) private String lastName;
 | 
			
		||||
 *   @Expose (serialize = false, deserialize = false) private String emailAddress;
 | 
			
		||||
 *   private String password;
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre></p>
 | 
			
		||||
 * If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()}
 | 
			
		||||
 * methods will use the {@code password} field along-with {@code firstName}, {@code lastName},
 | 
			
		||||
 * and {@code emailAddress} for serialization and deserialization. However, if you created Gson
 | 
			
		||||
 * with {@code Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()}
 | 
			
		||||
 * then the {@code toJson()} and {@code fromJson()} methods of Gson will exclude the
 | 
			
		||||
 * {@code password} field. This is because the {@code password} field is not marked with the
 | 
			
		||||
 * {@code @Expose} annotation. Gson will also exclude {@code lastName} and {@code emailAddress}
 | 
			
		||||
 * from serialization since {@code serialize} is set to {@code false}. Similarly, Gson will
 | 
			
		||||
 * exclude {@code emailAddress} from deserialization since {@code deserialize} is set to false.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Note that another way to achieve the same effect would have been to just mark the
 | 
			
		||||
 * {@code password} field as {@code transient}, and Gson would have excluded it even with default
 | 
			
		||||
 * settings. The {@code @Expose} annotation is useful in a style of programming where you want to
 | 
			
		||||
 * explicitly specify all fields that should get considered for serialization or deserialization.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target(ElementType.FIELD)
 | 
			
		||||
public @interface Expose {
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * If {@code true}, the field marked with this annotation is written out in the JSON while
 | 
			
		||||
   * serializing. If {@code false}, the field marked with this annotation is skipped from the
 | 
			
		||||
   * serialized output. Defaults to {@code true}.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public boolean serialize() default true;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * If {@code true}, the field marked with this annotation is deserialized from the JSON.
 | 
			
		||||
   * If {@code false}, the field marked with this annotation is skipped during deserialization. 
 | 
			
		||||
   * Defaults to {@code true}.
 | 
			
		||||
   * @since 1.4
 | 
			
		||||
   */
 | 
			
		||||
  public boolean deserialize() default true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								src/com/bukkit/mcteam/gson/annotations/SerializedName.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/com/bukkit/mcteam/gson/annotations/SerializedName.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson.annotations;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An annotation that indicates this member should be serialized to JSON with
 | 
			
		||||
 * the provided name value as its field name.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>This annotation will override any {@link com.bukkit.mcteam.gson.FieldNamingPolicy}, including
 | 
			
		||||
 * the default field naming policy, that may have been set on the {@link com.bukkit.mcteam.gson.Gson}
 | 
			
		||||
 * instance.  A different naming policy can set using the {@code GsonBuilder} class.  See
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder#setFieldNamingPolicy(com.bukkit.mcteam.gson.FieldNamingPolicy)}
 | 
			
		||||
 * for more information.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Here is an example of how this annotation is meant to be used:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class SomeClassWithFields {
 | 
			
		||||
 *   @SerializedName("name") private final String someField;
 | 
			
		||||
 *   private final String someOtherField;
 | 
			
		||||
 *
 | 
			
		||||
 *   public SomeClassWithFields(String a, String b) {
 | 
			
		||||
 *     this.someField = a;
 | 
			
		||||
 *     this.someOtherField = b;
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>The following shows the output that is generated when serializing an instance of the
 | 
			
		||||
 * above example class:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * SomeClassWithFields objectToSerialize = new SomeClassWithFields("a", "b");
 | 
			
		||||
 * Gson gson = new Gson();
 | 
			
		||||
 * String jsonRepresentation = gson.toJson(objectToSerialize);
 | 
			
		||||
 * System.out.println(jsonRepresentation);
 | 
			
		||||
 *
 | 
			
		||||
 * ===== OUTPUT =====
 | 
			
		||||
 * {"name":"a","someOtherField":"b"}
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>NOTE: The value you specify in this annotation must be a valid JSON field name.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @see com.bukkit.mcteam.gson.FieldNamingPolicy
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target(ElementType.FIELD)
 | 
			
		||||
public @interface SerializedName {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the desired name of the field when it is serialized
 | 
			
		||||
   */
 | 
			
		||||
  String value();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/com/bukkit/mcteam/gson/annotations/Since.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/com/bukkit/mcteam/gson/annotations/Since.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson.annotations;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An annotation that indicates the version number since a member or a type has been present.
 | 
			
		||||
 * This annotation is useful to manage versioning of your Json classes for a web-service.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This annotation has no effect unless you build {@link com.bukkit.mcteam.gson.Gson} with a
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder} and invoke
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder#setVersion(double)} method.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Here is an example of how this annotation is meant to be used:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class User {
 | 
			
		||||
 *   private String firstName;
 | 
			
		||||
 *   private String lastName;
 | 
			
		||||
 *   @Since(1.0) private String emailAddress;
 | 
			
		||||
 *   @Since(1.0) private String password;
 | 
			
		||||
 *   @Since(1.1) private Address address;
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()}
 | 
			
		||||
 * methods will use all the fields for serialization and deserialization. However, if you created
 | 
			
		||||
 * Gson with {@code Gson gson = new GsonBuilder().setVersion(1.0).create()} then the
 | 
			
		||||
 * {@code toJson()} and {@code fromJson()} methods of Gson will exclude the {@code address} field
 | 
			
		||||
 * since it's version number is set to {@code 1.1}.</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target({ElementType.FIELD, ElementType.TYPE})
 | 
			
		||||
public @interface Since {
 | 
			
		||||
  /**
 | 
			
		||||
   * the value indicating a version number since this member
 | 
			
		||||
   * or type has been present.
 | 
			
		||||
   */
 | 
			
		||||
  double value();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/com/bukkit/mcteam/gson/annotations/Until.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/com/bukkit/mcteam/gson/annotations/Until.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson.annotations;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.ElementType;
 | 
			
		||||
import java.lang.annotation.Retention;
 | 
			
		||||
import java.lang.annotation.RetentionPolicy;
 | 
			
		||||
import java.lang.annotation.Target;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An annotation that indicates the version number until a member or a type should be present.
 | 
			
		||||
 * Basically, if Gson is created with a version number that exceeds the value stored in the
 | 
			
		||||
 * {@code Until} annotation then the field will be ignored from the JSON output.  This annotation
 | 
			
		||||
 * is useful to manage versioning of your JSON classes for a web-service.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This annotation has no effect unless you build {@link com.bukkit.mcteam.gson.Gson} with a
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder} and invoke
 | 
			
		||||
 * {@link com.bukkit.mcteam.gson.GsonBuilder#setVersion(double)} method.
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Here is an example of how this annotation is meant to be used:</p>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * public class User {
 | 
			
		||||
 *   private String firstName;
 | 
			
		||||
 *   private String lastName;
 | 
			
		||||
 *   @Until(1.1) private String emailAddress;
 | 
			
		||||
 *   @Until(1.1) private String password;
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()}
 | 
			
		||||
 * methods will use all the fields for serialization and deserialization. However, if you created
 | 
			
		||||
 * Gson with {@code Gson gson = new GsonBuilder().setVersion(1.2).create()} then the
 | 
			
		||||
 * {@code toJson()} and {@code fromJson()} methods of Gson will exclude the {@code emailAddress}
 | 
			
		||||
 * and {@code password} fields from the example above, because the version number passed to the 
 | 
			
		||||
 * GsonBuilder, {@code 1.2}, exceeds the version number set on the {@code Until} annotation,
 | 
			
		||||
 * {@code 1.1}, for those fields.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh
 | 
			
		||||
 * @author Joel Leitch
 | 
			
		||||
 * @since 1.3
 | 
			
		||||
 */
 | 
			
		||||
@Retention(RetentionPolicy.RUNTIME)
 | 
			
		||||
@Target({ElementType.FIELD, ElementType.TYPE})
 | 
			
		||||
public @interface Until {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * the value indicating a version number until this member
 | 
			
		||||
   * or type should be ignored.
 | 
			
		||||
   */
 | 
			
		||||
  double value();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								src/com/bukkit/mcteam/gson/annotations/package-info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/com/bukkit/mcteam/gson/annotations/package-info.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This package provides annotations that can be used with {@link com.bukkit.mcteam.gson.Gson}.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Inderjeet Singh, Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
package com.bukkit.mcteam.gson.annotations;
 | 
			
		||||
							
								
								
									
										11
									
								
								src/com/bukkit/mcteam/gson/package-info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/com/bukkit/mcteam/gson/package-info.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This package provides the {@link com.bukkit.mcteam.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}
 | 
			
		||||
 * (to configure various options such as using versioning and so on).</p>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Inderjeet Singh, Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
package com.bukkit.mcteam.gson;
 | 
			
		||||
							
								
								
									
										375
									
								
								src/com/bukkit/mcteam/gson/reflect/TypeToken.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								src/com/bukkit/mcteam/gson/reflect/TypeToken.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,375 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 com.bukkit.mcteam.gson.reflect;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Array;
 | 
			
		||||
import java.lang.reflect.GenericArrayType;
 | 
			
		||||
import java.lang.reflect.ParameterizedType;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.lang.reflect.TypeVariable;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a generic type {@code T}.
 | 
			
		||||
 *
 | 
			
		||||
 * You can use this class to get the generic type for a class. For example,
 | 
			
		||||
 * to get the generic type for <code>Collection<Foo></code>, you can use:
 | 
			
		||||
 * <p>
 | 
			
		||||
 * <code>Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType()
 | 
			
		||||
 * </code>
 | 
			
		||||
 * 
 | 
			
		||||
 * <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.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Bob Lee
 | 
			
		||||
 * @author Sven Mawson
 | 
			
		||||
 */
 | 
			
		||||
public abstract class TypeToken<T> {
 | 
			
		||||
 | 
			
		||||
  final Class<? super T> rawType;
 | 
			
		||||
  final Type type;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Constructs a new type token. 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>
 | 
			
		||||
   */
 | 
			
		||||
  @SuppressWarnings("unchecked")
 | 
			
		||||
  protected TypeToken() {
 | 
			
		||||
    this.type = getSuperclassTypeParameter(getClass());
 | 
			
		||||
    this.rawType = (Class<? super T>) getRawType(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Unsafe. Constructs a type token 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;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets type from super class's type parameter.
 | 
			
		||||
   */
 | 
			
		||||
  static Type getSuperclassTypeParameter(Class<?> subclass) {
 | 
			
		||||
    Type superclass = subclass.getGenericSuperclass();
 | 
			
		||||
    if (superclass instanceof Class<?>) {
 | 
			
		||||
      throw new RuntimeException("Missing type parameter.");
 | 
			
		||||
    }
 | 
			
		||||
    return ((ParameterizedType) superclass).getActualTypeArguments()[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets type token from super class's type parameter.
 | 
			
		||||
   */
 | 
			
		||||
  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() {
 | 
			
		||||
    return rawType;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets underlying {@code Type} instance.
 | 
			
		||||
   */
 | 
			
		||||
  public Type getType() {
 | 
			
		||||
    return type;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check if this type is assignable from the given class object.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isAssignableFrom(Class<?> cls) {
 | 
			
		||||
    return isAssignableFrom((Type) cls);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check if this type is assignable from the given Type.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isAssignableFrom(Type from) {
 | 
			
		||||
    if (from == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (type.equals(from)) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (type instanceof Class<?>) {
 | 
			
		||||
      return rawType.isAssignableFrom(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))
 | 
			
		||||
          && isAssignableFrom(from, (GenericArrayType) type);
 | 
			
		||||
    } else {
 | 
			
		||||
      throw buildUnexpectedTypeError(
 | 
			
		||||
          type, Class.class, ParameterizedType.class, GenericArrayType.class);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Check if this type is assignable from the given type token.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isAssignableFrom(TypeToken<?> token) {
 | 
			
		||||
    return isAssignableFrom(token.getType());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Private helper function that performs some assignability checks for
 | 
			
		||||
   * the provided GenericArrayType.
 | 
			
		||||
   */
 | 
			
		||||
  private static boolean isAssignableFrom(Type from, GenericArrayType to) {
 | 
			
		||||
    Type toGenericComponentType = to.getGenericComponentType();
 | 
			
		||||
    if (toGenericComponentType instanceof ParameterizedType) {
 | 
			
		||||
      Type t = from;
 | 
			
		||||
      if (from instanceof GenericArrayType) {
 | 
			
		||||
        t = ((GenericArrayType) from).getGenericComponentType();
 | 
			
		||||
      } else if (from instanceof Class<?>) {
 | 
			
		||||
        Class<?> classType = (Class<?>) from;
 | 
			
		||||
        while (classType.isArray()) {
 | 
			
		||||
          classType = classType.getComponentType();
 | 
			
		||||
        }
 | 
			
		||||
        t = classType;
 | 
			
		||||
      }
 | 
			
		||||
      return isAssignableFrom(t, (ParameterizedType) toGenericComponentType,
 | 
			
		||||
          new HashMap<String, Type>());
 | 
			
		||||
    }
 | 
			
		||||
    // No generic defined on "to"; therefore, return true and let other
 | 
			
		||||
    // checks determine assignability
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Private recursive helper function to actually do the type-safe checking
 | 
			
		||||
   * of assignability.
 | 
			
		||||
   */
 | 
			
		||||
  private static boolean isAssignableFrom(Type from, ParameterizedType to,
 | 
			
		||||
      Map<String, Type> typeVarMap) {
 | 
			
		||||
 | 
			
		||||
    if (from == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (to.equals(from)) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // First figure out the class and any type information.
 | 
			
		||||
    Class<?> clazz = getRawType(from);
 | 
			
		||||
    ParameterizedType ptype = null;
 | 
			
		||||
    if (from instanceof ParameterizedType) {
 | 
			
		||||
      ptype = (ParameterizedType) from;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Load up parameterized variable info if it was parameterized.
 | 
			
		||||
    if (ptype != null) {
 | 
			
		||||
      Type[] tArgs = ptype.getActualTypeArguments();
 | 
			
		||||
      TypeVariable<?>[] tParams = clazz.getTypeParameters();
 | 
			
		||||
      for (int i = 0; i < tArgs.length; i++) {
 | 
			
		||||
        Type arg = tArgs[i];
 | 
			
		||||
        TypeVariable<?> var = tParams[i];
 | 
			
		||||
        while (arg instanceof TypeVariable<?>) {
 | 
			
		||||
          TypeVariable<?> v = (TypeVariable<?>) arg;
 | 
			
		||||
          arg = typeVarMap.get(v.getName());
 | 
			
		||||
        }
 | 
			
		||||
        typeVarMap.put(var.getName(), arg);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // check if they are equivalent under our current mapping.
 | 
			
		||||
      if (typeEquals(ptype, to, typeVarMap)) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (Type itype : clazz.getGenericInterfaces()) {
 | 
			
		||||
      if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap))) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Interfaces didn't work, try the superclass.
 | 
			
		||||
    Type sType = clazz.getGenericSuperclass();
 | 
			
		||||
    if (isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap))) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Checks if two parameterized types are exactly equal, under the variable
 | 
			
		||||
   * replacement described in the typeVarMap.
 | 
			
		||||
   */
 | 
			
		||||
  private static boolean typeEquals(ParameterizedType from,
 | 
			
		||||
      ParameterizedType to, Map<String, Type> typeVarMap) {
 | 
			
		||||
    if (from.getRawType().equals(to.getRawType())) {
 | 
			
		||||
      Type[] fromArgs = from.getActualTypeArguments();
 | 
			
		||||
      Type[] toArgs = to.getActualTypeArguments();
 | 
			
		||||
      for (int i = 0; i < fromArgs.length; i++) {
 | 
			
		||||
        if (!matches(fromArgs[i], toArgs[i], typeVarMap)) {
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
 | 
			
		||||
    // Build exception message
 | 
			
		||||
    StringBuilder exceptionMessage =
 | 
			
		||||
        new StringBuilder("Unexpected type. Expected one of: ");
 | 
			
		||||
    for (Class<?> clazz : expected) {
 | 
			
		||||
      exceptionMessage.append(clazz.getName()).append(", ");
 | 
			
		||||
    }
 | 
			
		||||
    exceptionMessage.append("but got: ").append(token.getClass().getName())
 | 
			
		||||
        .append(", for type token: ").append(token.toString()).append('.');
 | 
			
		||||
 | 
			
		||||
    return new AssertionError(exceptionMessage.toString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets type token for the given {@code Type} instance.
 | 
			
		||||
   */
 | 
			
		||||
  public static TypeToken<?> get(Type type) {
 | 
			
		||||
    return new SimpleTypeToken<Object>(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets type token 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);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								src/com/bukkit/mcteam/gson/reflect/package-info.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/com/bukkit/mcteam/gson/reflect/package-info.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This package provides utility classes for finding type information for generic types.
 | 
			
		||||
 *  
 | 
			
		||||
 * @author Inderjeet Singh, Joel Leitch
 | 
			
		||||
 */
 | 
			
		||||
package com.bukkit.mcteam.gson.reflect;
 | 
			
		||||
							
								
								
									
										1121
									
								
								src/com/bukkit/mcteam/gson/stream/JsonReader.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1121
									
								
								src/com/bukkit/mcteam/gson/stream/JsonReader.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										71
									
								
								src/com/bukkit/mcteam/gson/stream/JsonScope.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/com/bukkit/mcteam/gson/stream/JsonScope.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson.stream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Lexical scoping elements within a JSON reader or writer.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Jesse Wilson
 | 
			
		||||
 * @since 1.6
 | 
			
		||||
 */
 | 
			
		||||
enum JsonScope {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An array with no elements requires no separators or newlines before
 | 
			
		||||
     * it is closed.
 | 
			
		||||
     */
 | 
			
		||||
    EMPTY_ARRAY,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A array with at least one value requires a comma and newline before
 | 
			
		||||
     * the next element.
 | 
			
		||||
     */
 | 
			
		||||
    NONEMPTY_ARRAY,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An object with no name/value pairs requires no separators or newlines
 | 
			
		||||
     * before it is closed.
 | 
			
		||||
     */
 | 
			
		||||
    EMPTY_OBJECT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An object whose most recent element is a key. The next element must
 | 
			
		||||
     * be a value.
 | 
			
		||||
     */
 | 
			
		||||
    DANGLING_NAME,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An object with at least one name/value pair requires a comma and
 | 
			
		||||
     * newline before the next element.
 | 
			
		||||
     */
 | 
			
		||||
    NONEMPTY_OBJECT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * No object or array has been started.
 | 
			
		||||
     */
 | 
			
		||||
    EMPTY_DOCUMENT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A document with at an array or object.
 | 
			
		||||
     */
 | 
			
		||||
    NONEMPTY_DOCUMENT,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A document that's been closed and cannot be accessed.
 | 
			
		||||
     */
 | 
			
		||||
    CLOSED,
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								src/com/bukkit/mcteam/gson/stream/JsonToken.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/com/bukkit/mcteam/gson/stream/JsonToken.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson.stream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A structure, name or value type in a JSON-encoded string.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Jesse Wilson
 | 
			
		||||
 * @since 1.6
 | 
			
		||||
 */
 | 
			
		||||
public enum JsonToken {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The opening of a JSON array. Written using {@link JsonWriter#beginObject}
 | 
			
		||||
   * and read using {@link JsonReader#beginObject}.
 | 
			
		||||
   */
 | 
			
		||||
  BEGIN_ARRAY,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The closing of a JSON array. Written using {@link JsonWriter#endArray}
 | 
			
		||||
   * and read using {@link JsonReader#endArray}.
 | 
			
		||||
   */
 | 
			
		||||
  END_ARRAY,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The opening of a JSON object. Written using {@link JsonWriter#beginObject}
 | 
			
		||||
   * and read using {@link JsonReader#beginObject}.
 | 
			
		||||
   */
 | 
			
		||||
  BEGIN_OBJECT,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The closing of a JSON object. Written using {@link JsonWriter#endObject}
 | 
			
		||||
   * and read using {@link JsonReader#endObject}.
 | 
			
		||||
   */
 | 
			
		||||
  END_OBJECT,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A JSON property name. Within objects, tokens alternate between names and
 | 
			
		||||
   * their values. Written using {@link JsonWriter#name} and read using {@link
 | 
			
		||||
   * JsonReader#nextName}
 | 
			
		||||
   */
 | 
			
		||||
  NAME,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A JSON string.
 | 
			
		||||
   */
 | 
			
		||||
  STRING,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A JSON number represented in this API by a Java {@code double}, {@code
 | 
			
		||||
   * long}, or {@code int}.
 | 
			
		||||
   */
 | 
			
		||||
  NUMBER,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A JSON {@code true} or {@code false}.
 | 
			
		||||
   */
 | 
			
		||||
  BOOLEAN,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A JSON {@code null}.
 | 
			
		||||
   */
 | 
			
		||||
  NULL,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The end of the JSON stream. This sentinel value is returned by {@link
 | 
			
		||||
   * JsonReader#peek()} to signal that the JSON-encoded value has no more
 | 
			
		||||
   * tokens.
 | 
			
		||||
   */
 | 
			
		||||
  END_DOCUMENT
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										553
									
								
								src/com/bukkit/mcteam/gson/stream/JsonWriter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										553
									
								
								src/com/bukkit/mcteam/gson/stream/JsonWriter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,553 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson.stream;
 | 
			
		||||
 | 
			
		||||
import java.io.Closeable;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.Writer;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Writes a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
 | 
			
		||||
 * encoded value to a stream, one token at a time. The stream includes both
 | 
			
		||||
 * literal values (strings, numbers, booleans and nulls) as well as the begin
 | 
			
		||||
 * and end delimiters of objects and arrays.
 | 
			
		||||
 *
 | 
			
		||||
 * <h3>Encoding JSON</h3>
 | 
			
		||||
 * To encode your data as JSON, create a new {@code JsonWriter}. Each JSON
 | 
			
		||||
 * document must contain one top-level array or object. Call methods on the
 | 
			
		||||
 * writer as you walk the structure's contents, nesting arrays and objects as
 | 
			
		||||
 * necessary:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 *   <li>To write <strong>arrays</strong>, first call {@link #beginArray()}.
 | 
			
		||||
 *       Write each of the array's elements with the appropriate {@link #value}
 | 
			
		||||
 *       methods or by nesting other arrays and objects. Finally close the array
 | 
			
		||||
 *       using {@link #endArray()}.
 | 
			
		||||
 *   <li>To write <strong>objects</strong>, first call {@link #beginObject()}.
 | 
			
		||||
 *       Write each of the object's properties by alternating calls to
 | 
			
		||||
 *       {@link #name} with the property's value. Write property values with the
 | 
			
		||||
 *       appropriate {@link #value} method or by nesting other objects or arrays.
 | 
			
		||||
 *       Finally close the object using {@link #endObject()}.
 | 
			
		||||
 * </ul>
 | 
			
		||||
 *
 | 
			
		||||
 * <h3>Example</h3>
 | 
			
		||||
 * Suppose we'd like to encode a stream of messages such as the following: <pre> {@code
 | 
			
		||||
 * [
 | 
			
		||||
 *   {
 | 
			
		||||
 *     "id": 912345678901,
 | 
			
		||||
 *     "text": "How do I stream JSON in Java?",
 | 
			
		||||
 *     "geo": null,
 | 
			
		||||
 *     "user": {
 | 
			
		||||
 *       "name": "json_newb",
 | 
			
		||||
 *       "followers_count": 41
 | 
			
		||||
 *      }
 | 
			
		||||
 *   },
 | 
			
		||||
 *   {
 | 
			
		||||
 *     "id": 912345678902,
 | 
			
		||||
 *     "text": "@json_newb just use JsonWriter!",
 | 
			
		||||
 *     "geo": [50.454722, -104.606667],
 | 
			
		||||
 *     "user": {
 | 
			
		||||
 *       "name": "jesse",
 | 
			
		||||
 *       "followers_count": 2
 | 
			
		||||
 *     }
 | 
			
		||||
 *   }
 | 
			
		||||
 * ]}</pre>
 | 
			
		||||
 * This code encodes the above structure: <pre>   {@code
 | 
			
		||||
 *   public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
 | 
			
		||||
 *     JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
 | 
			
		||||
 *     writer.setIndentSpaces(4);
 | 
			
		||||
 *     writeMessagesArray(writer, messages);
 | 
			
		||||
 *     writer.close();
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public void writeMessagesArray(JsonWriter writer, List<Message> messages) throws IOException {
 | 
			
		||||
 *     writer.beginArray();
 | 
			
		||||
 *     for (Message message : messages) {
 | 
			
		||||
 *       writeMessage(writer, message);
 | 
			
		||||
 *     }
 | 
			
		||||
 *     writer.endArray();
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public void writeMessage(JsonWriter writer, Message message) throws IOException {
 | 
			
		||||
 *     writer.beginObject();
 | 
			
		||||
 *     writer.name("id").value(message.getId());
 | 
			
		||||
 *     writer.name("text").value(message.getText());
 | 
			
		||||
 *     if (message.getGeo() != null) {
 | 
			
		||||
 *       writer.name("geo");
 | 
			
		||||
 *       writeDoublesArray(writer, message.getGeo());
 | 
			
		||||
 *     } else {
 | 
			
		||||
 *       writer.name("geo").nullValue();
 | 
			
		||||
 *     }
 | 
			
		||||
 *     writer.name("user");
 | 
			
		||||
 *     writeUser(writer, message.getUser());
 | 
			
		||||
 *     writer.endObject();
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public void writeUser(JsonWriter writer, User user) throws IOException {
 | 
			
		||||
 *     writer.beginObject();
 | 
			
		||||
 *     writer.name("name").value(user.getName());
 | 
			
		||||
 *     writer.name("followers_count").value(user.getFollowersCount());
 | 
			
		||||
 *     writer.endObject();
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   public void writeDoublesArray(JsonWriter writer, List<Double> doubles) throws IOException {
 | 
			
		||||
 *     writer.beginArray();
 | 
			
		||||
 *     for (Double value : doubles) {
 | 
			
		||||
 *       writer.value(value);
 | 
			
		||||
 *     }
 | 
			
		||||
 *     writer.endArray();
 | 
			
		||||
 *   }}</pre>
 | 
			
		||||
 *
 | 
			
		||||
 * <p>Each {@code JsonWriter} may be used to write a single JSON stream.
 | 
			
		||||
 * Instances of this class are not thread safe. Calls that would result in a
 | 
			
		||||
 * malformed JSON string will fail with an {@link IllegalStateException}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Jesse Wilson
 | 
			
		||||
 * @since 1.6
 | 
			
		||||
 */
 | 
			
		||||
public final class JsonWriter implements Closeable {
 | 
			
		||||
 | 
			
		||||
  /** The output data, containing at most one top-level array or object. */
 | 
			
		||||
  private final Writer out;
 | 
			
		||||
 | 
			
		||||
  private final List<JsonScope> stack = new ArrayList<JsonScope>();
 | 
			
		||||
  {
 | 
			
		||||
    stack.add(JsonScope.EMPTY_DOCUMENT);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A string containing a full set of spaces for a single level of
 | 
			
		||||
   * indentation, or null for no pretty printing.
 | 
			
		||||
   */
 | 
			
		||||
  private String indent;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The name/value separator; either ":" or ": ".
 | 
			
		||||
   */
 | 
			
		||||
  private String separator = ":";
 | 
			
		||||
 | 
			
		||||
  private boolean lenient;
 | 
			
		||||
 | 
			
		||||
  private boolean htmlSafe;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a new instance that writes a JSON-encoded stream to {@code out}.
 | 
			
		||||
   * For best performance, ensure {@link Writer} is buffered; wrapping in
 | 
			
		||||
   * {@link java.io.BufferedWriter BufferedWriter} if necessary.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter(Writer out) {
 | 
			
		||||
    if (out == null) {
 | 
			
		||||
      throw new NullPointerException("out == null");
 | 
			
		||||
    }
 | 
			
		||||
    this.out = out;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the indentation string to be repeated for each level of indentation
 | 
			
		||||
   * in the encoded document. If {@code indent.isEmpty()} the encoded document
 | 
			
		||||
   * will be compact. Otherwise the encoded document will be more
 | 
			
		||||
   * human-readable.
 | 
			
		||||
   *
 | 
			
		||||
   * @param indent a string containing only whitespace.
 | 
			
		||||
   */
 | 
			
		||||
  public void setIndent(String indent) {
 | 
			
		||||
    if (indent.length() == 0) {
 | 
			
		||||
      this.indent = null;
 | 
			
		||||
      this.separator = ":";
 | 
			
		||||
    } else {
 | 
			
		||||
      this.indent = indent;
 | 
			
		||||
      this.separator = ": ";
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure this writer to relax its syntax rules. By default, this writer
 | 
			
		||||
   * only emits well-formed JSON as specified by <a
 | 
			
		||||
   * href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the writer
 | 
			
		||||
   * to lenient permits the following:
 | 
			
		||||
   * <ul>
 | 
			
		||||
   *   <li>Top-level values of any type. With strict writing, the top-level
 | 
			
		||||
   *       value must be an object or an array.
 | 
			
		||||
   *   <li>Numbers may be {@link Double#isNaN() NaNs} or {@link
 | 
			
		||||
   *       Double#isInfinite() infinities}.
 | 
			
		||||
   * </ul>
 | 
			
		||||
   */
 | 
			
		||||
  public void setLenient(boolean lenient) {
 | 
			
		||||
    this.lenient = lenient;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if this writer has relaxed syntax rules.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isLenient() {
 | 
			
		||||
    return lenient;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Configure this writer to emit JSON that's safe for direct inclusion in HTML
 | 
			
		||||
   * and XML documents. This escapes the HTML characters {@code <}, {@code >},
 | 
			
		||||
   * {@code &} and {@code =} before writing them to the stream. Without this
 | 
			
		||||
   * setting, your XML/HTML encoder should replace these characters with the
 | 
			
		||||
   * corresponding escape sequences.
 | 
			
		||||
   */
 | 
			
		||||
  public void setHtmlSafe(boolean htmlSafe) {
 | 
			
		||||
    this.htmlSafe = htmlSafe;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if this writer writes JSON that's safe for inclusion in HTML
 | 
			
		||||
   * and XML documents.
 | 
			
		||||
   */
 | 
			
		||||
  public boolean isHtmlSafe() {
 | 
			
		||||
    return htmlSafe;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Begins encoding a new array. Each call to this method must be paired with
 | 
			
		||||
   * a call to {@link #endArray}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter beginArray() throws IOException {
 | 
			
		||||
    return open(JsonScope.EMPTY_ARRAY, "[");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Ends encoding the current array.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter endArray() throws IOException {
 | 
			
		||||
    return close(JsonScope.EMPTY_ARRAY, JsonScope.NONEMPTY_ARRAY, "]");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Begins encoding a new object. Each call to this method must be paired
 | 
			
		||||
   * with a call to {@link #endObject}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter beginObject() throws IOException {
 | 
			
		||||
    return open(JsonScope.EMPTY_OBJECT, "{");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Ends encoding the current object.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter endObject() throws IOException {
 | 
			
		||||
    return close(JsonScope.EMPTY_OBJECT, JsonScope.NONEMPTY_OBJECT, "}");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Enters a new scope by appending any necessary whitespace and the given
 | 
			
		||||
   * bracket.
 | 
			
		||||
   */
 | 
			
		||||
  private JsonWriter open(JsonScope empty, String openBracket) throws IOException {
 | 
			
		||||
    beforeValue(true);
 | 
			
		||||
    stack.add(empty);
 | 
			
		||||
    out.write(openBracket);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Closes the current scope by appending any necessary whitespace and the
 | 
			
		||||
   * given bracket.
 | 
			
		||||
   */
 | 
			
		||||
  private JsonWriter close(JsonScope empty, JsonScope nonempty, String closeBracket)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
    JsonScope context = peek();
 | 
			
		||||
    if (context != nonempty && context != empty) {
 | 
			
		||||
      throw new IllegalStateException("Nesting problem: " + stack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stack.remove(stack.size() - 1);
 | 
			
		||||
    if (context == nonempty) {
 | 
			
		||||
      newline();
 | 
			
		||||
    }
 | 
			
		||||
    out.write(closeBracket);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the value on the top of the stack.
 | 
			
		||||
   */
 | 
			
		||||
  private JsonScope peek() {
 | 
			
		||||
    return stack.get(stack.size() - 1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Replace the value on the top of the stack with the given value.
 | 
			
		||||
   */
 | 
			
		||||
  private void replaceTop(JsonScope topOfStack) {
 | 
			
		||||
    stack.set(stack.size() - 1, topOfStack);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes the property name.
 | 
			
		||||
   *
 | 
			
		||||
   * @param name the name of the forthcoming value. May not be null.
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter name(String name) throws IOException {
 | 
			
		||||
    if (name == null) {
 | 
			
		||||
      throw new NullPointerException("name == null");
 | 
			
		||||
    }
 | 
			
		||||
    beforeName();
 | 
			
		||||
    string(name);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code value}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value the literal string value, or null to encode a null literal.
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter value(String value) throws IOException {
 | 
			
		||||
    if (value == null) {
 | 
			
		||||
      return nullValue();
 | 
			
		||||
    }
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    string(value);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code null}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter nullValue() throws IOException {
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    out.write("null");
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code value}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter value(boolean value) throws IOException {
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    out.write(value ? "true" : "false");
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code value}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
 | 
			
		||||
   *     {@link Double#isInfinite() infinities}.
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter value(double value) throws IOException {
 | 
			
		||||
    if (Double.isNaN(value) || Double.isInfinite(value)) {
 | 
			
		||||
      throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
 | 
			
		||||
    }
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    out.append(Double.toString(value));
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code value}.
 | 
			
		||||
   *
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter value(long value) throws IOException {
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    out.write(Long.toString(value));
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Encodes {@code value}.
 | 
			
		||||
   *
 | 
			
		||||
   * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
 | 
			
		||||
   *     {@link Double#isInfinite() infinities}.
 | 
			
		||||
   * @return this writer.
 | 
			
		||||
   */
 | 
			
		||||
  public JsonWriter value(Number value) throws IOException {
 | 
			
		||||
    if (value == null) {
 | 
			
		||||
      return nullValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String string = value.toString();
 | 
			
		||||
    if (!lenient
 | 
			
		||||
        && (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
 | 
			
		||||
      throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
 | 
			
		||||
    }
 | 
			
		||||
    beforeValue(false);
 | 
			
		||||
    out.append(string);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Ensures all buffered data is written to the underlying {@link Writer}
 | 
			
		||||
   * and flushes that writer.
 | 
			
		||||
   */
 | 
			
		||||
  public void flush() throws IOException {
 | 
			
		||||
    out.flush();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Flushes and closes this writer and the underlying {@link Writer}.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws IOException if the JSON document is incomplete.
 | 
			
		||||
   */
 | 
			
		||||
  public void close() throws IOException {
 | 
			
		||||
    out.close();
 | 
			
		||||
 | 
			
		||||
    if (peek() != JsonScope.NONEMPTY_DOCUMENT) {
 | 
			
		||||
      throw new IOException("Incomplete document");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void string(String value) throws IOException {
 | 
			
		||||
    out.write("\"");
 | 
			
		||||
    for (int i = 0, length = value.length(); i < length; i++) {
 | 
			
		||||
      char c = value.charAt(i);
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
       * From RFC 4627, "All Unicode characters may be placed within the
 | 
			
		||||
       * quotation marks except for the characters that must be escaped:
 | 
			
		||||
       * quotation mark, reverse solidus, and the control characters
 | 
			
		||||
       * (U+0000 through U+001F)."
 | 
			
		||||
       */
 | 
			
		||||
      switch (c) {
 | 
			
		||||
      case '"':
 | 
			
		||||
      case '\\':
 | 
			
		||||
        out.write('\\');
 | 
			
		||||
        out.write(c);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '\t':
 | 
			
		||||
        out.write("\\t");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '\b':
 | 
			
		||||
        out.write("\\b");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '\n':
 | 
			
		||||
        out.write("\\n");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '\r':
 | 
			
		||||
        out.write("\\r");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '\f':
 | 
			
		||||
        out.write("\\f");
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case '<':
 | 
			
		||||
      case '>':
 | 
			
		||||
      case '&':
 | 
			
		||||
      case '=':
 | 
			
		||||
      case '\'':
 | 
			
		||||
        if (htmlSafe) {
 | 
			
		||||
          out.write(String.format("\\u%04x", (int) c));
 | 
			
		||||
        } else {
 | 
			
		||||
          out.write(c);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        if (c <= 0x1F) {
 | 
			
		||||
          out.write(String.format("\\u%04x", (int) c));
 | 
			
		||||
        } else {
 | 
			
		||||
          out.write(c);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    out.write("\"");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void newline() throws IOException {
 | 
			
		||||
    if (indent == null) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    out.write("\n");
 | 
			
		||||
    for (int i = 1; i < stack.size(); i++) {
 | 
			
		||||
      out.write(indent);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Inserts any necessary separators and whitespace before a name. Also
 | 
			
		||||
   * adjusts the stack to expect the name's value.
 | 
			
		||||
   */
 | 
			
		||||
  private void beforeName() throws IOException {
 | 
			
		||||
    JsonScope context = peek();
 | 
			
		||||
    if (context == JsonScope.NONEMPTY_OBJECT) { // first in object
 | 
			
		||||
      out.write(',');
 | 
			
		||||
    } else if (context != JsonScope.EMPTY_OBJECT) { // not in an object!
 | 
			
		||||
      throw new IllegalStateException("Nesting problem: " + stack);
 | 
			
		||||
    }
 | 
			
		||||
    newline();
 | 
			
		||||
    replaceTop(JsonScope.DANGLING_NAME);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Inserts any necessary separators and whitespace before a literal value,
 | 
			
		||||
   * inline array, or inline object. Also adjusts the stack to expect either a
 | 
			
		||||
   * closing bracket or another element.
 | 
			
		||||
   *
 | 
			
		||||
   * @param root true if the value is a new array or object, the two values
 | 
			
		||||
   *     permitted as top-level elements.
 | 
			
		||||
   */
 | 
			
		||||
  private void beforeValue(boolean root) throws IOException {
 | 
			
		||||
    switch (peek()) {
 | 
			
		||||
    case EMPTY_DOCUMENT: // first in document
 | 
			
		||||
      if (!lenient && !root) {
 | 
			
		||||
        throw new IllegalStateException(
 | 
			
		||||
            "JSON must start with an array or an object.");
 | 
			
		||||
      }
 | 
			
		||||
      replaceTop(JsonScope.NONEMPTY_DOCUMENT);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case EMPTY_ARRAY: // first in array
 | 
			
		||||
      replaceTop(JsonScope.NONEMPTY_ARRAY);
 | 
			
		||||
      newline();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NONEMPTY_ARRAY: // another in array
 | 
			
		||||
      out.append(',');
 | 
			
		||||
      newline();
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case DANGLING_NAME: // value for name
 | 
			
		||||
      out.append(separator);
 | 
			
		||||
      replaceTop(JsonScope.NONEMPTY_OBJECT);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case NONEMPTY_DOCUMENT:
 | 
			
		||||
        throw new IllegalStateException(
 | 
			
		||||
            "JSON must have only one top-level value.");
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      throw new IllegalStateException("Nesting problem: " + stack);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Google Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package com.bukkit.mcteam.gson.stream;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Thrown when a reader encounters malformed JSON. Some syntax errors can be
 | 
			
		||||
 * ignored by calling {@link JsonReader#setLenient(boolean)}.
 | 
			
		||||
 */
 | 
			
		||||
public final class MalformedJsonException extends IOException {
 | 
			
		||||
  private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
  public MalformedJsonException(String msg) {
 | 
			
		||||
    super(msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public MalformedJsonException(String msg, Throwable throwable) {
 | 
			
		||||
    super(msg);
 | 
			
		||||
    // Using initCause() instead of calling super() because Java 1.5 didn't retrofit IOException
 | 
			
		||||
    // with a constructor with Throwable. This was done in Java 1.6
 | 
			
		||||
    initCause(throwable);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public MalformedJsonException(Throwable throwable) {
 | 
			
		||||
    // Using initCause() instead of calling super() because Java 1.5 didn't retrofit IOException
 | 
			
		||||
    // with a constructor with Throwable. This was done in Java 1.6
 | 
			
		||||
    initCause(throwable);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user