Soon to be used JarLoader.
This commit is contained in:
parent
71922b7be3
commit
6e9fd72612
@ -12,11 +12,11 @@ import java.util.TreeMap;
|
|||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.massivecraft.factions.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.massivecraft.factions.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.massivecraft.factions.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.massivecraft.factions.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.massivecraft.factions.util.AsciiCompass;
|
import com.massivecraft.factions.util.AsciiCompass;
|
||||||
import com.massivecraft.factions.util.DiscUtil;
|
import com.massivecraft.factions.util.DiscUtil;
|
||||||
import com.massivecraft.factions.util.TextUtil;
|
import com.massivecraft.factions.util.TextUtil;
|
||||||
@ -248,7 +248,7 @@ public class Board {
|
|||||||
//Factions.log("Saving board to disk");
|
//Factions.log("Saving board to disk");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiscUtil.write(file, Factions.gson.toJson(dumpAsSaveFormat()));
|
DiscUtil.write(file, Factions.instance.gson.toJson(dumpAsSaveFormat()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Factions.log("Failed to save the board to disk.");
|
Factions.log("Failed to save the board to disk.");
|
||||||
@ -270,7 +270,7 @@ public class Board {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Type type = new TypeToken<Map<String,Map<String,Integer>>>(){}.getType();
|
Type type = new TypeToken<Map<String,Map<String,Integer>>>(){}.getType();
|
||||||
Map<String,Map<String,Integer>> worldCoordIds = Factions.gson.fromJson(DiscUtil.read(file), type);
|
Map<String,Map<String,Integer>> worldCoordIds = Factions.instance.gson.fromJson(DiscUtil.read(file), type);
|
||||||
loadFromSaveFormat(worldCoordIds);
|
loadFromSaveFormat(worldCoordIds);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -180,7 +180,7 @@ public class Conf {
|
|||||||
//Factions.log("Saving config to disk.");
|
//Factions.log("Saving config to disk.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiscUtil.write(file, Factions.gson.toJson(new Conf()));
|
DiscUtil.write(file, Factions.instance.gson.toJson(new Conf()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Factions.log("Failed to save the config to disk.");
|
Factions.log("Failed to save the config to disk.");
|
||||||
@ -199,7 +199,7 @@ public class Conf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Factions.gson.fromJson(DiscUtil.read(file), Conf.class);
|
Factions.instance.gson.fromJson(DiscUtil.read(file), Conf.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Factions.log("Failed to load the config from disk.");
|
Factions.log("Failed to load the config from disk.");
|
||||||
|
@ -9,7 +9,7 @@ import java.util.Map.Entry;
|
|||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.massivecraft.factions.struct.Relation;
|
import com.massivecraft.factions.struct.Relation;
|
||||||
import com.massivecraft.factions.struct.Role;
|
import com.massivecraft.factions.struct.Role;
|
||||||
import com.massivecraft.factions.util.DiscUtil;
|
import com.massivecraft.factions.util.DiscUtil;
|
||||||
@ -623,7 +623,7 @@ public class FPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiscUtil.write(file, Factions.gson.toJson(playersToSave));
|
DiscUtil.write(file, Factions.instance.gson.toJson(playersToSave));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Factions.log("Failed to save the players to disk.");
|
Factions.log("Failed to save the players to disk.");
|
||||||
@ -643,7 +643,7 @@ public class FPlayer {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Type type = new TypeToken<Map<String, FPlayer>>(){}.getType();
|
Type type = new TypeToken<Map<String, FPlayer>>(){}.getType();
|
||||||
Map<String, FPlayer> instancesFromFile = Factions.gson.fromJson(DiscUtil.read(file), type);
|
Map<String, FPlayer> instancesFromFile = Factions.instance.gson.fromJson(DiscUtil.read(file), type);
|
||||||
instances.clear();
|
instances.clear();
|
||||||
instances.putAll(instancesFromFile);
|
instances.putAll(instancesFromFile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -707,7 +707,7 @@ public class FPlayer {
|
|||||||
String name = jsonFile.getName();
|
String name = jsonFile.getName();
|
||||||
name = name.substring(0, name.length() - ext.length());
|
name = name.substring(0, name.length() - ext.length());
|
||||||
try {
|
try {
|
||||||
FPlayer follower = Factions.gson.fromJson(DiscUtil.read(jsonFile), FPlayer.class);
|
FPlayer follower = Factions.instance.gson.fromJson(DiscUtil.read(jsonFile), FPlayer.class);
|
||||||
follower.playerName = name;
|
follower.playerName = name;
|
||||||
follower.lastLoginTime = System.currentTimeMillis();
|
follower.lastLoginTime = System.currentTimeMillis();
|
||||||
instances.put(follower.playerName, follower);
|
instances.put(follower.playerName, follower);
|
||||||
|
@ -10,7 +10,7 @@ import org.bukkit.ChatColor;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.massivecraft.factions.struct.Relation;
|
import com.massivecraft.factions.struct.Relation;
|
||||||
import com.massivecraft.factions.struct.Role;
|
import com.massivecraft.factions.struct.Role;
|
||||||
import com.massivecraft.factions.util.*;
|
import com.massivecraft.factions.util.*;
|
||||||
@ -407,7 +407,7 @@ public class Faction {
|
|||||||
//Factions.log("Saving factions to disk");
|
//Factions.log("Saving factions to disk");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiscUtil.write(file, Factions.gson.toJson(instances));
|
DiscUtil.write(file, Factions.instance.gson.toJson(instances));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Factions.log("Failed to save the factions to disk due to I/O exception.");
|
Factions.log("Failed to save the factions to disk due to I/O exception.");
|
||||||
@ -432,7 +432,7 @@ public class Faction {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Type type = new TypeToken<Map<Integer, Faction>>(){}.getType();
|
Type type = new TypeToken<Map<Integer, Faction>>(){}.getType();
|
||||||
Map<Integer, Faction> instancesFromFile = Factions.gson.fromJson(DiscUtil.read(file), type);
|
Map<Integer, Faction> instancesFromFile = Factions.instance.gson.fromJson(DiscUtil.read(file), type);
|
||||||
instances.clear();
|
instances.clear();
|
||||||
instances.putAll(instancesFromFile);
|
instances.putAll(instancesFromFile);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -560,7 +560,7 @@ public class Faction {
|
|||||||
int id = Integer.parseInt(name);
|
int id = Integer.parseInt(name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Faction faction = Factions.gson.fromJson(DiscUtil.read(jsonFile), Faction.class);
|
Faction faction = Factions.instance.gson.fromJson(DiscUtil.read(jsonFile), Faction.class);
|
||||||
faction.id = id;
|
faction.id = id;
|
||||||
instances.put(faction.id, faction);
|
instances.put(faction.id, faction);
|
||||||
Factions.log("loaded pre-1.1 faction "+id);
|
Factions.log("loaded pre-1.1 faction "+id);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.massivecraft.factions;
|
package com.massivecraft.factions;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -19,17 +20,18 @@ import org.bukkit.plugin.PluginManager;
|
|||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import com.massivecraft.factions.commands.*;
|
import com.massivecraft.factions.commands.*;
|
||||||
import com.massivecraft.factions.gson.Gson;
|
|
||||||
import com.massivecraft.factions.gson.GsonBuilder;
|
|
||||||
import com.massivecraft.factions.listeners.FactionsBlockListener;
|
import com.massivecraft.factions.listeners.FactionsBlockListener;
|
||||||
import com.massivecraft.factions.listeners.FactionsChatEarlyListener;
|
import com.massivecraft.factions.listeners.FactionsChatEarlyListener;
|
||||||
import com.massivecraft.factions.listeners.FactionsEntityListener;
|
import com.massivecraft.factions.listeners.FactionsEntityListener;
|
||||||
import com.massivecraft.factions.listeners.FactionsPlayerListener;
|
import com.massivecraft.factions.listeners.FactionsPlayerListener;
|
||||||
|
import com.massivecraft.factions.util.JarLoader;
|
||||||
|
|
||||||
import com.nijiko.permissions.PermissionHandler;
|
import com.nijiko.permissions.PermissionHandler;
|
||||||
import com.nijikokun.bukkit.Permissions.Permissions;
|
import com.nijikokun.bukkit.Permissions.Permissions;
|
||||||
import com.earth2me.essentials.chat.EssentialsChat;
|
import com.earth2me.essentials.chat.EssentialsChat;
|
||||||
import com.earth2me.essentials.chat.IEssentialsChatListener;
|
import com.earth2me.essentials.chat.IEssentialsChatListener;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data is saved to disk every 30min and on plugin disable.
|
* The data is saved to disk every 30min and on plugin disable.
|
||||||
@ -41,11 +43,7 @@ public class Factions extends JavaPlugin {
|
|||||||
public static Factions instance;
|
public static Factions instance;
|
||||||
private Integer saveTask = null;
|
private Integer saveTask = null;
|
||||||
|
|
||||||
public final static Gson gson = new GsonBuilder()
|
public Gson gson;
|
||||||
.setPrettyPrinting()
|
|
||||||
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
|
|
||||||
.registerTypeAdapter(Location.class, new MyLocationTypeAdapter())
|
|
||||||
.create();
|
|
||||||
|
|
||||||
private final FactionsPlayerListener playerListener = new FactionsPlayerListener();
|
private final FactionsPlayerListener playerListener = new FactionsPlayerListener();
|
||||||
private final FactionsChatEarlyListener chatEarlyListener = new FactionsChatEarlyListener();
|
private final FactionsChatEarlyListener chatEarlyListener = new FactionsChatEarlyListener();
|
||||||
@ -67,9 +65,23 @@ public class Factions extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
log("=== INIT START ===");
|
log("=== ENABLE START ===");
|
||||||
long timeInitStart = System.currentTimeMillis();
|
long timeInitStart = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// Load the gson library we require
|
||||||
|
File gsonfile = new File("./lib/gson.jar");
|
||||||
|
if ( ! JarLoader.load(gsonfile)) {
|
||||||
|
log(Level.SEVERE, "Disabling myself as "+gsonfile+" is missing.");
|
||||||
|
this.getServer().getPluginManager().disablePlugin(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gson = new GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
|
||||||
|
.registerTypeAdapter(Location.class, new MyLocationTypeAdapter())
|
||||||
|
.create();
|
||||||
|
|
||||||
// Add the commands
|
// Add the commands
|
||||||
commands.add(new FCommandHelp());
|
commands.add(new FCommandHelp());
|
||||||
commands.add(new FCommandAdmin());
|
commands.add(new FCommandAdmin());
|
||||||
@ -156,7 +168,7 @@ public class Factions extends JavaPlugin {
|
|||||||
if (saveTask == null)
|
if (saveTask == null)
|
||||||
saveTask = this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveTask(), saveTicks, saveTicks);
|
saveTask = this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveTask(), saveTicks, saveTicks);
|
||||||
|
|
||||||
log("=== INIT DONE (Took "+(System.currentTimeMillis()-timeInitStart)+"ms) ===");
|
log("=== ENABLE DONE (Took "+(System.currentTimeMillis()-timeInitStart)+"ms) ===");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -167,7 +179,6 @@ public class Factions extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
saveAll();
|
saveAll();
|
||||||
unhookEssentialsChat();
|
unhookEssentialsChat();
|
||||||
log("Disabled");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
@ -6,13 +6,13 @@ import java.util.logging.Level;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.massivecraft.factions.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
import com.massivecraft.factions.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.massivecraft.factions.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.massivecraft.factions.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.massivecraft.factions.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import com.massivecraft.factions.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
|
||||||
public class MyLocationTypeAdapter implements JsonDeserializer<Location>, JsonSerializer<Location> {
|
public class MyLocationTypeAdapter implements JsonDeserializer<Location>, JsonSerializer<Location> {
|
||||||
|
@ -156,6 +156,7 @@ public class FCommandConfig extends FBaseCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
Set<Material> matSet = (Set<Material>)target.get(null);
|
Set<Material> matSet = (Set<Material>)target.get(null);
|
||||||
|
|
||||||
// Material already present, so remove it
|
// Material already present, so remove it
|
||||||
@ -174,6 +175,7 @@ public class FCommandConfig extends FBaseCommand {
|
|||||||
|
|
||||||
// Set<String>
|
// Set<String>
|
||||||
else if (innerType == String.class) {
|
else if (innerType == String.class) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
Set<String> stringSet = (Set<String>)target.get(null);
|
Set<String> stringSet = (Set<String>)target.get(null);
|
||||||
|
|
||||||
// String already present, so remove it
|
// String already present, so remove it
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Captures all the common/shared logic between the old, ({@link MapTypeAdapter}, and
|
|
||||||
* the new, {@link MapAsArrayTypeAdapter}, map type adapters.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
abstract class BaseMapTypeAdapter
|
|
||||||
implements JsonSerializer<Map<?, ?>>, JsonDeserializer<Map<?, ?>> {
|
|
||||||
|
|
||||||
protected static final JsonElement serialize(JsonSerializationContext context,
|
|
||||||
Object src, Type srcType) {
|
|
||||||
JsonSerializationContextDefault contextImpl = (JsonSerializationContextDefault) context;
|
|
||||||
return contextImpl.serialize(src, srcType, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected static final Map<Object, Object> constructMapType(
|
|
||||||
Type mapType, JsonDeserializationContext context) {
|
|
||||||
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
|
|
||||||
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
|
|
||||||
return (Map<Object, Object>) objectConstructor.construct(mapType);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
$Gson$Preconditions.checkNotNull(separatorString);
|
|
||||||
$Gson$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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the default constructor on the class to instantiate an object.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
final class DefaultConstructorAllocator {
|
|
||||||
private static final Constructor<Null> NULL_CONSTRUCTOR = createNullConstructor();
|
|
||||||
|
|
||||||
private final Cache<Class<?>, Constructor<?>> constructorCache;
|
|
||||||
|
|
||||||
public DefaultConstructorAllocator() {
|
|
||||||
this(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultConstructorAllocator(int cacheSize) {
|
|
||||||
constructorCache = new LruCache<Class<?>, Constructor<?>>(cacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for testing purpose
|
|
||||||
final boolean isInCache(Class<?> cacheKey) {
|
|
||||||
return constructorCache.getElement(cacheKey) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Constructor<Null> createNullConstructor() {
|
|
||||||
try {
|
|
||||||
return getNoArgsConstructor(Null.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T newInstance(Class<T> c) throws Exception {
|
|
||||||
Constructor<T> constructor = findConstructor(c);
|
|
||||||
return (constructor != null) ? constructor.newInstance() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T> Constructor<T> findConstructor(Class<T> c) {
|
|
||||||
Constructor<T> cachedElement = (Constructor<T>) constructorCache.getElement(c);
|
|
||||||
if (cachedElement != null) {
|
|
||||||
if (cachedElement == NULL_CONSTRUCTOR) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return cachedElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Constructor<T> noArgsConstructor = getNoArgsConstructor(c);
|
|
||||||
if (noArgsConstructor != null) {
|
|
||||||
constructorCache.addElement(c, noArgsConstructor);
|
|
||||||
} else {
|
|
||||||
constructorCache.addElement(c, NULL_CONSTRUCTOR);
|
|
||||||
}
|
|
||||||
return noArgsConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> Constructor<T> getNoArgsConstructor(Class<T> c) {
|
|
||||||
try {
|
|
||||||
Constructor<T> declaredConstructor = c.getDeclaredConstructor();
|
|
||||||
declaredConstructor.setAccessible(true);
|
|
||||||
return declaredConstructor;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// placeholder class for Null constructor
|
|
||||||
private static final class Null {
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
final class DelegatingJsonElementVisitor implements JsonElementVisitor {
|
|
||||||
private final JsonElementVisitor delegate;
|
|
||||||
|
|
||||||
protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) {
|
|
||||||
this.delegate = $Gson$Preconditions.checkNotNull(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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
DisjunctionExclusionStrategy(Collection<ExclusionStrategy> strategies) {
|
|
||||||
this.strategies = $Gson$Preconditions.checkNotNull(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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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) {
|
|
||||||
StringBuilder escapedString = new StringBuilder(plainText.length() + 20);
|
|
||||||
try {
|
|
||||||
escapeJsonString(plainText, escapedString);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return escapedString.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void escapeJsonString(CharSequence plainText, StringBuilder out) throws IOException {
|
|
||||||
int pos = 0; // Index just past the last char in plainText written to out.
|
|
||||||
int len = plainText.length();
|
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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>
|
|
||||||
*
|
|
||||||
* <p>For certain model classes, you may only want to serialize a field, but exclude it for
|
|
||||||
* deserialization. To do that, you can write an {@code ExclusionStrategy} as per normal;
|
|
||||||
* however, you would register it with the
|
|
||||||
* {@link GsonBuilder#addDeserializationExclusionStrategy(ExclusionStrategy)} method.
|
|
||||||
* For example:
|
|
||||||
* <pre class="code">
|
|
||||||
* ExclusionStrategy excludeStrings = new UserDefinedExclusionStrategy(String.class);
|
|
||||||
* Gson gson = new GsonBuilder()
|
|
||||||
* .addDeserializationExclusionStrategy(excludeStrings)
|
|
||||||
* .create();
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
* @author Joel Leitch
|
|
||||||
*
|
|
||||||
* @see GsonBuilder#setExclusionStrategies(ExclusionStrategy...)
|
|
||||||
* @see GsonBuilder#addDeserializationExclusionStrategy(ExclusionStrategy)
|
|
||||||
* @see GsonBuilder#addSerializationExclusionStrategy(ExclusionStrategy)
|
|
||||||
*
|
|
||||||
* @since 1.4
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.annotations.Expose;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Excludes fields that do not have the {@link Expose} annotation
|
|
||||||
*
|
|
||||||
* @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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.annotations.Expose;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Excludes fields that do not have the {@link Expose} annotation
|
|
||||||
*
|
|
||||||
* @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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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.google.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;
|
|
||||||
private final Type resolvedType;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
* @param declaringType The type in which the field is declared
|
|
||||||
*/
|
|
||||||
FieldAttributes(Class<?> declaringClazz, Field f, Type declaringType) {
|
|
||||||
this.declaringClazz = $Gson$Preconditions.checkNotNull(declaringClazz);
|
|
||||||
this.name = f.getName();
|
|
||||||
this.declaredType = f.getType();
|
|
||||||
this.isSynthetic = f.isSynthetic();
|
|
||||||
this.modifiers = f.getModifiers();
|
|
||||||
this.field = f;
|
|
||||||
this.resolvedType = getTypeInfoForField(f, declaringType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMaxCacheSize() {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type getResolvedType() {
|
|
||||||
return resolvedType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Evaluates the "actual" type for the field. If the field is a "TypeVariable" or has a
|
|
||||||
* "TypeVariable" in a parameterized type then it evaluates the real type.
|
|
||||||
*
|
|
||||||
* @param f the actual field object to retrieve the type from
|
|
||||||
* @param typeDefiningF the type that contains the field {@code f}
|
|
||||||
* @return the type information for the field
|
|
||||||
*/
|
|
||||||
static Type getTypeInfoForField(Field f, Type typeDefiningF) {
|
|
||||||
Class<?> rawType = $Gson$Types.getRawType(typeDefiningF);
|
|
||||||
if (!f.getDeclaringClass().isAssignableFrom(rawType)) {
|
|
||||||
// this field is unrelated to the type; the user probably omitted type information
|
|
||||||
return f.getGenericType();
|
|
||||||
}
|
|
||||||
return $Gson$Types.resolve(typeDefiningF, rawType, f.getGenericType());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An enumeration that defines a few standard naming conventions for JSON field names.
|
|
||||||
* This enumeration should be used in conjunction with {@link com.massivecraft.factions.gson.GsonBuilder}
|
|
||||||
* to configure a {@link com.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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.
|
|
||||||
*/
|
|
||||||
public String translateName(FieldAttributes f);
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapts the old FieldNamingStrategy to the new {@link FieldNamingStrategy2}
|
|
||||||
* type.
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
final class FieldNamingStrategy2Adapter implements FieldNamingStrategy2 {
|
|
||||||
private final FieldNamingStrategy adaptee;
|
|
||||||
|
|
||||||
FieldNamingStrategy2Adapter(FieldNamingStrategy adaptee) {
|
|
||||||
this.adaptee = $Gson$Preconditions.checkNotNull(adaptee);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String translateName(FieldAttributes f) {
|
|
||||||
return adaptee.translateName(f.getFieldObject());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,570 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonReader;
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonToken;
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonWriter;
|
|
||||||
import com.massivecraft.factions.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.massivecraft.factions.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.
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
|
|
||||||
|
|
||||||
private final ExclusionStrategy deserializationExclusionStrategy;
|
|
||||||
private final ExclusionStrategy serializationExclusionStrategy;
|
|
||||||
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.massivecraft.factions.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.massivecraft.factions.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.getAllDefaultSerializers(),
|
|
||||||
DefaultTypeAdapters.getAllDefaultDeserializers(), DEFAULT_JSON_NON_EXECUTABLE, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gson(ExclusionStrategy deserializationExclusionStrategy,
|
|
||||||
ExclusionStrategy serializationExclusionStrategy, FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
MappedObjectConstructor objectConstructor, boolean serializeNulls,
|
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
||||||
boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting) {
|
|
||||||
this.deserializationExclusionStrategy = deserializationExclusionStrategy;
|
|
||||||
this.serializationExclusionStrategy = serializationExclusionStrategy;
|
|
||||||
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 static ExclusionStrategy createExclusionStrategy() {
|
|
||||||
List<ExclusionStrategy> strategies = new LinkedList<ExclusionStrategy>();
|
|
||||||
strategies.add(DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
|
||||||
strategies.add(DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
|
||||||
strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY);
|
|
||||||
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.massivecraft.factions.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) {
|
|
||||||
JsonSerializationContextDefault context = new JsonSerializationContextDefault(
|
|
||||||
new ObjectNavigator(serializationExclusionStrategy), fieldNamingPolicy,
|
|
||||||
serializeNulls, serializers);
|
|
||||||
return context.serialize(src, typeOfSrc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 toJson(JsonNull.createJsonNull());
|
|
||||||
}
|
|
||||||
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.massivecraft.factions.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 {
|
|
||||||
if (src != null) {
|
|
||||||
toJson(src, src.getClass(), writer);
|
|
||||||
} else {
|
|
||||||
toJson(JsonNull.createJsonNull(), writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.massivecraft.factions.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.massivecraft.factions.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.massivecraft.factions.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.massivecraft.factions.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(
|
|
||||||
new ObjectNavigator(deserializationExclusionStrategy), fieldNamingPolicy,
|
|
||||||
deserializers, objectConstructor);
|
|
||||||
T target = (T) context.deserialize(json, typeOfT);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,715 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <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())
|
|
||||||
* .enableComplexMapKeySerialization()
|
|
||||||
* .serializeNulls()
|
|
||||||
* .setDateFormat(DateFormat.LONG)
|
|
||||||
* .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
|
|
||||||
* .setPrettyPrinting()
|
|
||||||
* .setVersion(1.0)
|
|
||||||
* .create();
|
|
||||||
* </pre></p>
|
|
||||||
*
|
|
||||||
* <p>NOTES:
|
|
||||||
* <ul>
|
|
||||||
* <li> the order of invocation of configuration methods does not matter.</li>
|
|
||||||
* <li> The default serialization of {@link Date} and its subclasses in Gson does
|
|
||||||
* not contain time-zone information. So, if you are using date/time instances,
|
|
||||||
* use {@code GsonBuilder} and its {@code setDateFormat} methods.</li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
public final class GsonBuilder {
|
|
||||||
private static final MapAsArrayTypeAdapter COMPLEX_KEY_MAP_TYPE_ADAPTER =
|
|
||||||
new MapAsArrayTypeAdapter();
|
|
||||||
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
|
|
||||||
new InnerClassExclusionStrategy();
|
|
||||||
private static final ExposeAnnotationDeserializationExclusionStrategy
|
|
||||||
exposeAnnotationDeserializationExclusionStrategy =
|
|
||||||
new ExposeAnnotationDeserializationExclusionStrategy();
|
|
||||||
private static final ExposeAnnotationSerializationExclusionStrategy
|
|
||||||
exposeAnnotationSerializationExclusionStrategy =
|
|
||||||
new ExposeAnnotationSerializationExclusionStrategy();
|
|
||||||
|
|
||||||
private final Set<ExclusionStrategy> serializeExclusionStrategies =
|
|
||||||
new HashSet<ExclusionStrategy>();
|
|
||||||
private final Set<ExclusionStrategy> deserializeExclusionStrategies =
|
|
||||||
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
|
|
||||||
deserializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
|
||||||
deserializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
|
||||||
serializeExclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
|
||||||
serializeExclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
|
||||||
|
|
||||||
// setup default values
|
|
||||||
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
|
||||||
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.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enabling this feature will only change the serialized form if the map key is
|
|
||||||
* a complex type (i.e. non-primitive) in its <strong>serialized</strong> JSON
|
|
||||||
* form. The default implementation of map serialization uses {@code toString()}
|
|
||||||
* on the key; however, when this is called then one of the following cases
|
|
||||||
* apply:
|
|
||||||
*
|
|
||||||
* <h3>Maps as JSON objects</h3>
|
|
||||||
* For this case, assume that a type adapter is registered to serialize and
|
|
||||||
* deserialize some {@code Point} class, which contains an x and y coordinate,
|
|
||||||
* to/from the JSON Primitive string value {@code "(x,y)"}. The Java map would
|
|
||||||
* then be serialized as a {@link JsonObject}.
|
|
||||||
*
|
|
||||||
* <p>Below is an example:
|
|
||||||
* <pre> {@code
|
|
||||||
* Gson gson = new GsonBuilder()
|
|
||||||
* .register(Point.class, new MyPointTypeAdapter())
|
|
||||||
* .enableComplexMapKeySerialization()
|
|
||||||
* .create();
|
|
||||||
*
|
|
||||||
* Map<Point, String> original = new LinkedHashMap<Point, String>();
|
|
||||||
* original.put(new Point(5, 6), "a");
|
|
||||||
* original.put(new Point(8, 8), "b");
|
|
||||||
* System.out.println(gson.toJson(original, type));
|
|
||||||
* }</pre>
|
|
||||||
* The above code prints this JSON object:<pre> {@code
|
|
||||||
* {
|
|
||||||
* "(5,6)": "a",
|
|
||||||
* "(8,8)": "b"
|
|
||||||
* }
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* <h3>Maps as JSON arrays</h3>
|
|
||||||
* For this case, assume that a type adapter was NOT registered for some
|
|
||||||
* {@code Point} class, but rather the default Gson serialization is applied.
|
|
||||||
* In this case, some {@code new Point(2,3)} would serialize as {@code
|
|
||||||
* {"x":2,"y":5}}.
|
|
||||||
*
|
|
||||||
* <p>Given the assumption above, a {@code Map<Point, String>} will be
|
|
||||||
* serialize as an array of arrays (can be viewed as an entry set of pairs).
|
|
||||||
*
|
|
||||||
* <p>Below is an example of serializing complex types as JSON arrays:
|
|
||||||
* <pre> {@code
|
|
||||||
* Gson gson = new GsonBuilder()
|
|
||||||
* .enableComplexMapKeySerialization()
|
|
||||||
* .create();
|
|
||||||
*
|
|
||||||
* Map<Point, String> original = new LinkedHashMap<Point, String>();
|
|
||||||
* original.put(new Point(5, 6), "a");
|
|
||||||
* original.put(new Point(8, 8), "b");
|
|
||||||
* System.out.println(gson.toJson(original, type));
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* The JSON output would look as follows:
|
|
||||||
* <pre> {@code
|
|
||||||
* [
|
|
||||||
* [
|
|
||||||
* {
|
|
||||||
* "x": 5,
|
|
||||||
* "y": 6
|
|
||||||
* },
|
|
||||||
* "a"
|
|
||||||
* ],
|
|
||||||
* [
|
|
||||||
* {
|
|
||||||
* "x": 8,
|
|
||||||
* "y": 8
|
|
||||||
* },
|
|
||||||
* "b"
|
|
||||||
* ]
|
|
||||||
* ]
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public GsonBuilder enableComplexMapKeySerialization() {
|
|
||||||
registerTypeHierarchyAdapter(Map.class, COMPLEX_KEY_MAP_TYPE_ADAPTER);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures Gson to exclude inner classes during serialization.
|
|
||||||
*
|
|
||||||
* @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) {
|
|
||||||
List<ExclusionStrategy> strategyList = Arrays.asList(strategies);
|
|
||||||
serializeExclusionStrategies.addAll(strategyList);
|
|
||||||
deserializeExclusionStrategies.addAll(strategyList);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures Gson to apply the passed in exclusion strategy during serialization.
|
|
||||||
* If this method is invoked numerous times with different exclusion strategy objects
|
|
||||||
* then the exclusion strategies that were added will be applied as a disjunction rule.
|
|
||||||
* This means that if one of the added exclusion strategies suggests that a field (or
|
|
||||||
* class) should be skipped then that field (or object) is skipped during its
|
|
||||||
* serialization.
|
|
||||||
*
|
|
||||||
* @param strategy an exclusion strategy to apply during serialization.
|
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
|
|
||||||
serializeExclusionStrategies.add(strategy);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures Gson to apply the passed in exclusion strategy during deserialization.
|
|
||||||
* If this method is invoked numerous times with different exclusion strategy objects
|
|
||||||
* then the exclusion strategies that were added will be applied as a disjunction rule.
|
|
||||||
* This means that if one of the added exclusion strategies suggests that a field (or
|
|
||||||
* class) should be skipped then that field (or object) is skipped during its
|
|
||||||
* deserialization.
|
|
||||||
*
|
|
||||||
* @param strategy an exclusion strategy to apply during deserialization.
|
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
|
|
||||||
deserializeExclusionStrategies.add(strategy);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Configures Gson to output Json that fits in a page for pretty printing. This option only
|
|
||||||
* affects Json serialization.
|
|
||||||
*
|
|
||||||
* @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>The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
|
|
||||||
* java.sql.Timestamp} and {@link java.sql.Date}.
|
|
||||||
*
|
|
||||||
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
|
|
||||||
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
|
|
||||||
* valid date and time patterns.</p>
|
|
||||||
*
|
|
||||||
* @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) {
|
|
||||||
$Gson$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
|
|
||||||
*/
|
|
||||||
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
|
||||||
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
|
||||||
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
|
||||||
if (typeAdapter instanceof InstanceCreator<?>) {
|
|
||||||
registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter);
|
|
||||||
}
|
|
||||||
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> deserializationStrategies =
|
|
||||||
new LinkedList<ExclusionStrategy>(deserializeExclusionStrategies);
|
|
||||||
List<ExclusionStrategy> serializationStrategies =
|
|
||||||
new LinkedList<ExclusionStrategy>(serializeExclusionStrategies);
|
|
||||||
deserializationStrategies.add(modifierBasedExclusionStrategy);
|
|
||||||
serializationStrategies.add(modifierBasedExclusionStrategy);
|
|
||||||
|
|
||||||
if (!serializeInnerClasses) {
|
|
||||||
deserializationStrategies.add(innerClassExclusionStrategy);
|
|
||||||
serializationStrategies.add(innerClassExclusionStrategy);
|
|
||||||
}
|
|
||||||
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
|
||||||
VersionExclusionStrategy versionExclusionStrategy =
|
|
||||||
new VersionExclusionStrategy(ignoreVersionsAfter);
|
|
||||||
deserializationStrategies.add(versionExclusionStrategy);
|
|
||||||
serializationStrategies.add(versionExclusionStrategy);
|
|
||||||
}
|
|
||||||
if (excludeFieldsWithoutExposeAnnotation) {
|
|
||||||
deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
|
|
||||||
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers =
|
|
||||||
DefaultTypeAdapters.DEFAULT_HIERARCHY_SERIALIZERS.copyOf();
|
|
||||||
customSerializers.register(serializers.copyOf());
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers =
|
|
||||||
DefaultTypeAdapters.DEFAULT_HIERARCHY_DESERIALIZERS.copyOf();
|
|
||||||
customDeserializers.register(deserializers.copyOf());
|
|
||||||
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
|
|
||||||
customDeserializers);
|
|
||||||
|
|
||||||
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(new DisjunctionExclusionStrategy(deserializationStrategies),
|
|
||||||
new DisjunctionExclusionStrategy(serializationStrategies),
|
|
||||||
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) {
|
|
||||||
registerIfAbsent(Date.class, serializers, dateTypeAdapter);
|
|
||||||
registerIfAbsent(Date.class, deserializers, dateTypeAdapter);
|
|
||||||
registerIfAbsent(Timestamp.class, serializers, dateTypeAdapter);
|
|
||||||
registerIfAbsent(Timestamp.class, deserializers, dateTypeAdapter);
|
|
||||||
registerIfAbsent(java.sql.Date.class, serializers, dateTypeAdapter);
|
|
||||||
registerIfAbsent(java.sql.Date.class, deserializers, dateTypeAdapter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> void registerIfAbsent(Class<?> type,
|
|
||||||
ParameterizedTypeHandlerMap<T> adapters, T adapter) {
|
|
||||||
if (!adapters.hasSpecificHandlerFor(type)) {
|
|
||||||
adapters.register(type, adapter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strategy for excluding inner classes.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
final 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,322 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return (o == this) || (o instanceof JsonArray && ((JsonArray) o).elements.equals(elements));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return elements.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void toString(Appendable sb, Escaper escaper) throws IOException {
|
|
||||||
sb.append('[');
|
|
||||||
boolean first = true;
|
|
||||||
for (JsonElement element : elements) {
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
sb.append(',');
|
|
||||||
}
|
|
||||||
element.toString(sb, escaper);
|
|
||||||
}
|
|
||||||
sb.append(']');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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,
|
|
||||||
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
ObjectConstructor objectConstructor,
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
||||||
JsonDeserializationContext context) {
|
|
||||||
super(jsonArray, arrayType, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected T constructTarget() {
|
|
||||||
if (!json.isJsonArray()) {
|
|
||||||
throw new JsonParseException("Expecting array found: " + json);
|
|
||||||
}
|
|
||||||
JsonArray jsonArray = json.getAsJsonArray();
|
|
||||||
if ($Gson$Types.isArray(targetType)) {
|
|
||||||
// We know that we are getting back an array of the required type, so
|
|
||||||
// this typecasting is safe.
|
|
||||||
return (T) objectConstructor.constructArray($Gson$Types.getArrayComponentType(targetType),
|
|
||||||
jsonArray.size());
|
|
||||||
}
|
|
||||||
// is a collection
|
|
||||||
return (T) objectConstructor.construct($Gson$Types.getRawType(targetType));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void visitArray(Object array, Type arrayType) {
|
|
||||||
if (!json.isJsonArray()) {
|
|
||||||
throw new JsonParseException("Expecting array found: " + json);
|
|
||||||
}
|
|
||||||
JsonArray jsonArray = json.getAsJsonArray();
|
|
||||||
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($Gson$Types.getArrayComponentType(arrayType), jsonChild);
|
|
||||||
} else if (jsonChild instanceof JsonArray) {
|
|
||||||
child = visitChildAsArray($Gson$Types.getArrayComponentType(arrayType),
|
|
||||||
jsonChild.getAsJsonArray());
|
|
||||||
} else if (jsonChild instanceof JsonPrimitive) {
|
|
||||||
child = visitChildAsObject($Gson$Types.getArrayComponentType(arrayType),
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* implementation of a deserialization context for Gson
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
*/
|
|
||||||
final class JsonDeserializationContextDefault implements JsonDeserializationContext {
|
|
||||||
|
|
||||||
private final ObjectNavigator objectNavigator;
|
|
||||||
private final FieldNamingStrategy2 fieldNamingPolicy;
|
|
||||||
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
|
|
||||||
private final MappedObjectConstructor objectConstructor;
|
|
||||||
|
|
||||||
JsonDeserializationContextDefault(ObjectNavigator objectNavigator,
|
|
||||||
FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
||||||
MappedObjectConstructor objectConstructor) {
|
|
||||||
this.objectNavigator = objectNavigator;
|
|
||||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
|
||||||
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, objectNavigator, fieldNamingPolicy,
|
|
||||||
objectConstructor, deserializers, context);
|
|
||||||
objectNavigator.accept(new ObjectTypePair(null, arrayType, true), visitor);
|
|
||||||
return visitor.getTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T fromJsonObject(Type typeOfT, JsonObject jsonObject,
|
|
||||||
JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
JsonObjectDeserializationVisitor<T> visitor = new JsonObjectDeserializationVisitor<T>(
|
|
||||||
jsonObject, typeOfT, objectNavigator, fieldNamingPolicy,
|
|
||||||
objectConstructor, deserializers, context);
|
|
||||||
objectNavigator.accept(new ObjectTypePair(null, typeOfT, true), 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, objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
|
|
||||||
objectNavigator.accept(new ObjectTypePair(json.getAsObject(), typeOfT, true), visitor);
|
|
||||||
Object target = visitor.getTarget();
|
|
||||||
return (T) target;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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 ObjectNavigator objectNavigator;
|
|
||||||
protected final FieldNamingStrategy2 fieldNamingPolicy;
|
|
||||||
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;
|
|
||||||
|
|
||||||
JsonDeserializationVisitor(JsonElement json, Type targetType,
|
|
||||||
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
ObjectConstructor objectConstructor,
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
||||||
JsonDeserializationContext context) {
|
|
||||||
this.targetType = targetType;
|
|
||||||
this.objectNavigator = objectNavigator;
|
|
||||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
|
||||||
this.objectConstructor = objectConstructor;
|
|
||||||
this.deserializers = deserializers;
|
|
||||||
this.json = $Gson$Preconditions.checkNotNull(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,
|
|
||||||
objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
|
|
||||||
return visitChild(childType, childVisitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Object visitChildAsArray(Type childType, JsonArray jsonChild) {
|
|
||||||
JsonDeserializationVisitor<?> childVisitor =
|
|
||||||
new JsonArrayDeserializationVisitor<Object>(jsonChild.getAsJsonArray(), childType,
|
|
||||||
objectNavigator, fieldNamingPolicy, objectConstructor, deserializers, context);
|
|
||||||
return visitChild(childType, childVisitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object visitChild(Type type, JsonDeserializationVisitor<?> childVisitor) {
|
|
||||||
objectNavigator.accept(new ObjectTypePair(null, type, false), childVisitor);
|
|
||||||
// the underlying object may have changed during the construction phase
|
|
||||||
// This happens primarily because of custom deserializers
|
|
||||||
return childVisitor.getTarget();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
final 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) {
|
|
||||||
this.delegate = $Gson$Preconditions.checkNotNull(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 deserialize json object ")
|
|
||||||
.append(json)
|
|
||||||
.append(" given the type ")
|
|
||||||
.append(typeOfT);
|
|
||||||
throw new JsonParseException(errorMsg.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return delegate.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,338 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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 this == other || 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
if (value == null) {
|
|
||||||
value = JsonNull.createJsonNull();
|
|
||||||
}
|
|
||||||
members.put($Gson$Preconditions.checkNotNull(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
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return (o == this) || (o instanceof JsonObject
|
|
||||||
&& ((JsonObject) o).members.equals(members));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return members.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void toString(Appendable sb, Escaper escaper) throws IOException {
|
|
||||||
sb.append('{');
|
|
||||||
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('}');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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,
|
|
||||||
ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
ObjectConstructor objectConstructor,
|
|
||||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers,
|
|
||||||
JsonDeserializationContext context) {
|
|
||||||
super(json, type, objectNavigator, fieldNamingPolicy, 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) {
|
|
||||||
return fieldNamingPolicy.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);
|
|
||||||
boolean isPrimitive = Primitives.isPrimitive(declaredTypeOfField);
|
|
||||||
if (child == null) { // Child will be null if the field wasn't present in Json
|
|
||||||
return true;
|
|
||||||
} else if (child.isJsonNull()) {
|
|
||||||
if (!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 || !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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonReader;
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonToken;
|
|
||||||
import com.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,390 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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 {
|
|
||||||
$Gson$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}.
|
|
||||||
*/
|
|
||||||
@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.
|
|
||||||
*/
|
|
||||||
@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 NumberFormatException 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.
|
|
||||||
*/
|
|
||||||
@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 NumberFormatException 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 NumberFormatException 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 NumberFormatException 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 NumberFormatException 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 NumberFormatException 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)) {
|
|
||||||
double a = getAsNumber().doubleValue();
|
|
||||||
// Java standard types other than double return true for two NaN. So, need
|
|
||||||
// special handling for double.
|
|
||||||
double b = other.getAsNumber().doubleValue();
|
|
||||||
return a == b || (Double.isNaN(a) && Double.isNaN(b));
|
|
||||||
}
|
|
||||||
return value.equals(other.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An implementation of serialization context for Gson.
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
*/
|
|
||||||
final class JsonSerializationContextDefault implements JsonSerializationContext {
|
|
||||||
|
|
||||||
private final ObjectNavigator objectNavigator;
|
|
||||||
private final FieldNamingStrategy2 fieldNamingPolicy;
|
|
||||||
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
|
||||||
private final boolean serializeNulls;
|
|
||||||
private final MemoryRefStack ancestors;
|
|
||||||
|
|
||||||
JsonSerializationContextDefault(ObjectNavigator objectNavigator,
|
|
||||||
FieldNamingStrategy2 fieldNamingPolicy, boolean serializeNulls,
|
|
||||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers) {
|
|
||||||
this.objectNavigator = objectNavigator;
|
|
||||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
|
||||||
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(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonElement serialize(Object src, Type typeOfSrc) {
|
|
||||||
return serialize(src, typeOfSrc, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonElement serialize(Object src, Type typeOfSrc, boolean preserveType) {
|
|
||||||
if (src == null) {
|
|
||||||
return JsonNull.createJsonNull();
|
|
||||||
}
|
|
||||||
JsonSerializationVisitor visitor = new JsonSerializationVisitor(
|
|
||||||
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, this, ancestors);
|
|
||||||
objectNavigator.accept(new ObjectTypePair(src, typeOfSrc, preserveType), visitor);
|
|
||||||
return visitor.getJsonElement();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,236 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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 ObjectNavigator objectNavigator;
|
|
||||||
private final FieldNamingStrategy2 fieldNamingPolicy;
|
|
||||||
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
|
||||||
private final boolean serializeNulls;
|
|
||||||
private final JsonSerializationContext context;
|
|
||||||
private final MemoryRefStack ancestors;
|
|
||||||
private JsonElement root;
|
|
||||||
|
|
||||||
JsonSerializationVisitor(ObjectNavigator objectNavigator, FieldNamingStrategy2 fieldNamingPolicy,
|
|
||||||
boolean serializeNulls, ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
|
||||||
JsonSerializationContext context, MemoryRefStack ancestors) {
|
|
||||||
this.objectNavigator = objectNavigator;
|
|
||||||
this.fieldNamingPolicy = fieldNamingPolicy;
|
|
||||||
this.serializeNulls = serializeNulls;
|
|
||||||
this.serializers = serializers;
|
|
||||||
this.context = context;
|
|
||||||
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);
|
|
||||||
Type componentType = $Gson$Types.getArrayComponentType(arrayType);
|
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
Object child = Array.get(array, i);
|
|
||||||
// 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, componentType, 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) {
|
|
||||||
root.getAsJsonObject().add(fieldNamingPolicy.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) {
|
|
||||||
JsonSerializationVisitor childVisitor = new JsonSerializationVisitor(
|
|
||||||
objectNavigator, fieldNamingPolicy, serializeNulls, serializers, context, ancestors);
|
|
||||||
objectNavigator.accept(fieldValueTypePair, 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")
|
|
||||||
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 {
|
|
||||||
$Gson$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) {
|
|
||||||
root = $Gson$Preconditions.checkNotNull(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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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.massivecraft.factions.gson.stream.JsonReader;
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonToken;
|
|
||||||
import com.massivecraft.factions.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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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;
|
|
||||||
|
|
||||||
public LruCache(int maxCapacity) {
|
|
||||||
super(maxCapacity, 0.7F, true);
|
|
||||||
this.maxCapacity = maxCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void addElement(K key, V value) {
|
|
||||||
put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized V getElement(K key) {
|
|
||||||
return get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized V removeElement(K key) {
|
|
||||||
return remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean removeEldestEntry(Map.Entry<K, V> entry) {
|
|
||||||
return size() > maxCapacity;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
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.google.gson.JsonParseException: Expecting object found: "(5,6)"
|
|
||||||
* at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler
|
|
||||||
* at com.google.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.
|
|
||||||
*/
|
|
||||||
final class MapAsArrayTypeAdapter
|
|
||||||
extends BaseMapTypeAdapter
|
|
||||||
implements JsonSerializer<Map<?, ?>>, JsonDeserializer<Map<?, ?>> {
|
|
||||||
|
|
||||||
public Map<?, ?> deserialize(JsonElement json, Type typeOfT,
|
|
||||||
JsonDeserializationContext context) throws JsonParseException {
|
|
||||||
Map<Object, Object> result = constructMapType(typeOfT, context);
|
|
||||||
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 = serialize(context, entry.getKey(), keyAndValueType[0]);
|
|
||||||
serializeAsArray |= key.isJsonObject() || key.isJsonArray();
|
|
||||||
keysAndValues.add(key);
|
|
||||||
keysAndValues.add(serialize(context, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default serialization and deserialization of a map type. This implementation really only works
|
|
||||||
* well with simple primitive types as the map key. If the key is not a simple primitive then the
|
|
||||||
* object is {@code toString}ed and that value is used as its key.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final class MapTypeAdapter extends BaseMapTypeAdapter {
|
|
||||||
|
|
||||||
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
|
|
||||||
JsonObject map = new JsonObject();
|
|
||||||
Type childGenericType = null;
|
|
||||||
if (typeOfSrc instanceof ParameterizedType) {
|
|
||||||
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc);
|
|
||||||
childGenericType = $Gson$Types.getMapKeyAndValueTypes(typeOfSrc, rawTypeOfSrc)[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) {
|
|
||||||
Object value = entry.getValue();
|
|
||||||
|
|
||||||
JsonElement valueElement;
|
|
||||||
if (value == null) {
|
|
||||||
valueElement = JsonNull.createJsonNull();
|
|
||||||
} else {
|
|
||||||
Type childType = (childGenericType == null)
|
|
||||||
? value.getClass() : childGenericType;
|
|
||||||
valueElement = serialize(context, value, childType);
|
|
||||||
}
|
|
||||||
map.add(String.valueOf(entry.getKey()), valueElement);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
|
||||||
throws JsonParseException {
|
|
||||||
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
|
||||||
// This handles cases where users are using their own subclass of Map.
|
|
||||||
Map<Object, Object> map = constructMapType(typeOfT, context);
|
|
||||||
Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(typeOfT, $Gson$Types.getRawType(typeOfT));
|
|
||||||
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
|
||||||
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueTypes[0]);
|
|
||||||
Object value = context.deserialize(entry.getValue(), keyAndValueTypes[1]);
|
|
||||||
map.put(key, value);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return MapTypeAdapter.class.getSimpleName();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 UnsafeAllocator unsafeAllocator = UnsafeAllocator.create();
|
|
||||||
private static final DefaultConstructorAllocator defaultConstructorAllocator =
|
|
||||||
new DefaultConstructorAllocator(500);
|
|
||||||
|
|
||||||
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) constructWithAllocators(typeOfT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object constructArray(Type type, int length) {
|
|
||||||
return Array.newInstance($Gson$Types.getRawType(type), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "cast"})
|
|
||||||
private <T> T constructWithAllocators(Type typeOfT) {
|
|
||||||
try {
|
|
||||||
Class<T> clazz = (Class<T>) $Gson$Types.getRawType(typeOfT);
|
|
||||||
T obj = defaultConstructorAllocator.newInstance(clazz);
|
|
||||||
return (obj == null)
|
|
||||||
? unsafeAllocator.newInstance(clazz)
|
|
||||||
: obj;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". "
|
|
||||||
+ "Register an InstanceCreator with Gson for this type may fix this problem."), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return instanceCreatorMap.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
$Gson$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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
ModifyFirstLetterNamingPolicy(LetterModifier modifier) {
|
|
||||||
this.letterModifier = $Gson$Preconditions.checkNotNull(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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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);
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
void visitPrimitive(Object primitive);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the current target
|
|
||||||
*/
|
|
||||||
Object getTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ExclusionStrategy exclusionStrategy;
|
|
||||||
private final ReflectingFieldNavigator reflectingFieldNavigator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param strategy the concrete exclusion strategy object to be used to filter out fields of an
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
ObjectNavigator(ExclusionStrategy strategy) {
|
|
||||||
this.exclusionStrategy = strategy == null ? new NullExclusionStrategy() : strategy;
|
|
||||||
this.reflectingFieldNavigator = new ReflectingFieldNavigator(exclusionStrategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Navigate all the fields of the specified object. If a field is null, it
|
|
||||||
* does not get visited.
|
|
||||||
* @param objTypePair The object,type (fully genericized) being navigated
|
|
||||||
*/
|
|
||||||
public void accept(ObjectTypePair objTypePair, Visitor visitor) {
|
|
||||||
if (exclusionStrategy.shouldSkipClass($Gson$Types.getRawType(objTypePair.type))) {
|
|
||||||
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 ($Gson$Types.isArray(objTypePair.type)) {
|
|
||||||
visitor.visitArray(objectToVisit, objTypePair.type);
|
|
||||||
} else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) {
|
|
||||||
// TODO(Joel): this is only used for deserialization of "primitives"
|
|
||||||
// we should rethink this!!!
|
|
||||||
visitor.visitPrimitive(objectToVisit);
|
|
||||||
visitor.getTarget();
|
|
||||||
} else {
|
|
||||||
visitor.startVisitingObject(objectToVisit);
|
|
||||||
reflectingFieldNavigator.visitFieldsReflectively(objTypePair, visitor);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
visitor.end(objTypePair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isPrimitiveOrString(Object objectToVisit) {
|
|
||||||
Class<?> realClazz = objectToVisit.getClass();
|
|
||||||
return realClazz == Object.class || realClazz == String.class
|
|
||||||
|| Primitives.unwrap(realClazz).isPrimitive();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type getMoreSpecificType() {
|
|
||||||
if (preserveType || obj == null) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
return getActualTypeIfMoreSpecific(type, obj.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
// This takes care of situations where the field was declared as an Object, but the
|
|
||||||
// actual value contains something more specific. See Issue 54.
|
|
||||||
// TODO (inder): This solution will not work if the field is of a generic type, but
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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> {
|
|
||||||
public final FIRST first;
|
|
||||||
public final SECOND second;
|
|
||||||
|
|
||||||
public 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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 register(ParameterizedTypeHandlerMap<T> other) {
|
|
||||||
if (!modifiable) {
|
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
|
||||||
}
|
|
||||||
for (Map.Entry<Type, T> entry : other.map.entrySet()) {
|
|
||||||
register(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
// Quite important to traverse the typeHierarchyList from stack bottom first since
|
|
||||||
// we want to register the handlers in the same order to preserve priority order
|
|
||||||
for (int i = other.typeHierarchyList.size()-1; i >= 0; --i) {
|
|
||||||
Pair<Class<?>, T> entry = other.typeHierarchyList.get(i);
|
|
||||||
registerForTypeHierarchy(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void registerIfAbsent(Type typeOfT, T value) {
|
|
||||||
if (!modifiable) {
|
|
||||||
throw new IllegalStateException("Attempted to modify an unmodifiable map.");
|
|
||||||
}
|
|
||||||
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 = $Gson$Types.getRawType(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>();
|
|
||||||
// Instead of individually registering entries in the map, make an efficient copy
|
|
||||||
// of the list and map
|
|
||||||
copy.map.putAll(map);
|
|
||||||
copy.typeHierarchyList.addAll(typeHierarchyList);
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 $Gson$Types.getRawType(type).getSimpleName();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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. */
|
|
||||||
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
|
|
||||||
|
|
||||||
/** A map from wrapper types to their corresponding primitive types. */
|
|
||||||
private 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 true if this type is a primitive.
|
|
||||||
*/
|
|
||||||
public static boolean isPrimitive(Type type) {
|
|
||||||
return PRIMITIVE_TO_WRAPPER_TYPE.containsKey(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if {@code type} is one of the nine
|
|
||||||
* primitive-wrapper types, such as {@link Integer}.
|
|
||||||
*
|
|
||||||
* @see Class#isPrimitive
|
|
||||||
*/
|
|
||||||
public static boolean isWrapperType(Class<?> type) {
|
|
||||||
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(
|
|
||||||
$Gson$Preconditions.checkNotNull(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) {
|
|
||||||
// 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(
|
|
||||||
$Gson$Preconditions.checkNotNull(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) {
|
|
||||||
// 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(
|
|
||||||
$Gson$Preconditions.checkNotNull(type));
|
|
||||||
return (unwrapped == null) ? type : unwrapped;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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) {
|
|
||||||
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);
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.lang.reflect.AccessibleObject;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.ObjectNavigator.Visitor;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Visits each of the fields of the specified class using reflection
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh
|
|
||||||
* @author Joel Leitch
|
|
||||||
* @author Jesse Wilson
|
|
||||||
*/
|
|
||||||
final class ReflectingFieldNavigator {
|
|
||||||
|
|
||||||
private static final Cache<Type, List<FieldAttributes>> fieldsCache =
|
|
||||||
new LruCache<Type, List<FieldAttributes>>(500);
|
|
||||||
|
|
||||||
private final ExclusionStrategy exclusionStrategy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param exclusionStrategy the concrete strategy object to be used to filter out fields of an
|
|
||||||
* object.
|
|
||||||
*/
|
|
||||||
ReflectingFieldNavigator(ExclusionStrategy exclusionStrategy) {
|
|
||||||
this.exclusionStrategy = $Gson$Preconditions.checkNotNull(exclusionStrategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param objTypePair The object,type (fully genericized) being navigated
|
|
||||||
* @param visitor the visitor to visit each field with
|
|
||||||
*/
|
|
||||||
void visitFieldsReflectively(ObjectTypePair objTypePair, Visitor visitor) {
|
|
||||||
Type moreSpecificType = objTypePair.getMoreSpecificType();
|
|
||||||
Object obj = objTypePair.getObject();
|
|
||||||
for (FieldAttributes fieldAttributes : getAllFields(moreSpecificType, objTypePair.getType())) {
|
|
||||||
if (exclusionStrategy.shouldSkipField(fieldAttributes)
|
|
||||||
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) {
|
|
||||||
continue; // skip
|
|
||||||
}
|
|
||||||
Type resolvedTypeOfField = fieldAttributes.getResolvedType();
|
|
||||||
boolean visitedWithCustomHandler =
|
|
||||||
visitor.visitFieldUsingCustomHandler(fieldAttributes, resolvedTypeOfField, obj);
|
|
||||||
if (!visitedWithCustomHandler) {
|
|
||||||
if ($Gson$Types.isArray(resolvedTypeOfField)) {
|
|
||||||
visitor.visitArrayField(fieldAttributes, resolvedTypeOfField, obj);
|
|
||||||
} else {
|
|
||||||
visitor.visitObjectField(fieldAttributes, resolvedTypeOfField, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<FieldAttributes> getAllFields(Type type, Type declaredType) {
|
|
||||||
List<FieldAttributes> fields = fieldsCache.getElement(type);
|
|
||||||
if (fields == null) {
|
|
||||||
fields = new ArrayList<FieldAttributes>();
|
|
||||||
for (Class<?> curr : getInheritanceHierarchy(type)) {
|
|
||||||
Field[] currentClazzFields = curr.getDeclaredFields();
|
|
||||||
AccessibleObject.setAccessible(currentClazzFields, true);
|
|
||||||
Field[] classFields = currentClazzFields;
|
|
||||||
for (Field f : classFields) {
|
|
||||||
fields.add(new FieldAttributes(curr, f, declaredType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fieldsCache.addElement(type, fields);
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of classes corresponding to the inheritance of specified type
|
|
||||||
*/
|
|
||||||
private List<Class<?>> getInheritanceHierarchy(Type type) {
|
|
||||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
|
||||||
Class<?> topLevelClass = $Gson$Types.getRawType(type);
|
|
||||||
for (Class<?> curr = topLevelClass; curr != null && !curr.equals(Object.class); curr =
|
|
||||||
curr.getSuperclass()) {
|
|
||||||
if (!curr.isSynthetic()) {
|
|
||||||
classes.add(curr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return classes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link FieldNamingStrategy2} that acts as a chain of responsibility. If the
|
|
||||||
* {@link com.massivecraft.factions.gson.annotations.SerializedName} annotation is applied to a
|
|
||||||
* field then this strategy will translate the name to the {@code
|
|
||||||
* serializedName.value()}; otherwise it delegates to the wrapped
|
|
||||||
* {@link FieldNamingStrategy2}.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* NOTE: this class performs JSON field name validation for any of the fields
|
|
||||||
* marked with an {@code @SerializedName} annotation.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @see SerializedName
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
final class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy2 {
|
|
||||||
private final FieldNamingStrategy2 delegate;
|
|
||||||
|
|
||||||
SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy2 delegate) {
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String translateName(FieldAttributes f) {
|
|
||||||
SerializedName serializedName = f.getAnnotation(SerializedName.class);
|
|
||||||
return serializedName == null ? delegate.translateName(f) : serializedName.value();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonReader;
|
|
||||||
import com.massivecraft.factions.gson.stream.JsonWriter;
|
|
||||||
import com.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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
|
|
||||||
*/
|
|
||||||
final 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2011 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectStreamClass;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do sneaky things to allocate objects without invoking their constructors.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
* @author Jesse Wilson
|
|
||||||
*/
|
|
||||||
abstract class UnsafeAllocator {
|
|
||||||
public abstract <T> T newInstance(Class<T> c) throws Exception;
|
|
||||||
|
|
||||||
public static UnsafeAllocator create() {
|
|
||||||
// try JVM
|
|
||||||
// public class Unsafe {
|
|
||||||
// public Object allocateInstance(Class<?> type);
|
|
||||||
// }
|
|
||||||
try {
|
|
||||||
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
|
|
||||||
Field f = unsafeClass.getDeclaredField("theUnsafe");
|
|
||||||
f.setAccessible(true);
|
|
||||||
final Object unsafe = f.get(null);
|
|
||||||
final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);
|
|
||||||
return new UnsafeAllocator() {
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> T newInstance(Class<T> c) throws Exception {
|
|
||||||
return (T) allocateInstance.invoke(unsafe, c);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// try dalvikvm, pre-gingerbread
|
|
||||||
// public class ObjectInputStream {
|
|
||||||
// private static native Object newInstance(
|
|
||||||
// Class<?> instantiationClass, Class<?> constructorClass);
|
|
||||||
// }
|
|
||||||
try {
|
|
||||||
final Method newInstance = ObjectInputStream.class
|
|
||||||
.getDeclaredMethod("newInstance", Class.class, Class.class);
|
|
||||||
newInstance.setAccessible(true);
|
|
||||||
return new UnsafeAllocator() {
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> T newInstance(Class<T> c) throws Exception {
|
|
||||||
return (T) newInstance.invoke(null, c, Object.class);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// try dalvivkm, post-gingerbread
|
|
||||||
// public class ObjectStreamClass {
|
|
||||||
// private static native int getConstructorId(Class<?> c);
|
|
||||||
// private static native Object newInstance(Class<?> instantiationClass, int methodId);
|
|
||||||
// }
|
|
||||||
try {
|
|
||||||
Method getConstructorId = ObjectStreamClass.class
|
|
||||||
.getDeclaredMethod("getConstructorId", Class.class);
|
|
||||||
getConstructorId.setAccessible(true);
|
|
||||||
final int constructorId = (Integer) getConstructorId.invoke(null, Object.class);
|
|
||||||
final Method newInstance = ObjectStreamClass.class
|
|
||||||
.getDeclaredMethod("newInstance", Class.class, int.class);
|
|
||||||
newInstance.setAccessible(true);
|
|
||||||
return new UnsafeAllocator() {
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> T newInstance(Class<T> c) throws Exception {
|
|
||||||
return (T) newInstance.invoke(null, c, constructorId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// give up
|
|
||||||
return new UnsafeAllocator() {
|
|
||||||
@Override
|
|
||||||
public <T> T newInstance(Class<T> c) {
|
|
||||||
throw new UnsupportedOperationException("Cannot allocate " + c);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class contain all constants for versioning support.
|
|
||||||
*
|
|
||||||
* @author Joel Leitch
|
|
||||||
*/
|
|
||||||
final class VersionConstants {
|
|
||||||
// Prevent instantiation
|
|
||||||
private VersionConstants() { }
|
|
||||||
|
|
||||||
static final double IGNORE_VERSIONS = -1D;
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.annotations.Since;
|
|
||||||
import com.massivecraft.factions.gson.annotations.Until;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
VersionExclusionStrategy(double version) {
|
|
||||||
$Gson$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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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.massivecraft.factions.gson.Gson}
|
|
||||||
* with a {@link com.massivecraft.factions.gson.GsonBuilder} and invoke
|
|
||||||
* {@link com.massivecraft.factions.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;
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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.massivecraft.factions.gson.FieldNamingPolicy}, including
|
|
||||||
* the default field naming policy, that may have been set on the {@link com.massivecraft.factions.gson.Gson}
|
|
||||||
* instance. A different naming policy can set using the {@code GsonBuilder} class. See
|
|
||||||
* {@link com.massivecraft.factions.gson.GsonBuilder#setFieldNamingPolicy(com.massivecraft.factions.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.massivecraft.factions.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();
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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.massivecraft.factions.gson.Gson} with a
|
|
||||||
* {@link com.massivecraft.factions.gson.GsonBuilder} and invoke
|
|
||||||
* {@link com.massivecraft.factions.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();
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.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.massivecraft.factions.gson.Gson} with a
|
|
||||||
* {@link com.massivecraft.factions.gson.GsonBuilder} and invoke
|
|
||||||
* {@link com.massivecraft.factions.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();
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* This package provides annotations that can be used with {@link com.massivecraft.factions.gson.Gson}.
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh, Joel Leitch
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.gson.annotations;
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson.internal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public final class $Gson$Preconditions {
|
|
||||||
public static <T> T checkNotNull(T obj) {
|
|
||||||
if (obj == null) {
|
|
||||||
throw new NullPointerException();
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkArgument(boolean condition) {
|
|
||||||
if (!condition) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkState(boolean condition) {
|
|
||||||
if (!condition) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,590 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson.internal;
|
|
||||||
|
|
||||||
import static com.massivecraft.factions.gson.internal.$Gson$Preconditions.checkArgument;
|
|
||||||
import static com.massivecraft.factions.gson.internal.$Gson$Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.lang.reflect.GenericArrayType;
|
|
||||||
import java.lang.reflect.GenericDeclaration;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.lang.reflect.TypeVariable;
|
|
||||||
import java.lang.reflect.WildcardType;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static methods for working with types.
|
|
||||||
*
|
|
||||||
* @author Bob Lee
|
|
||||||
* @author Jesse Wilson
|
|
||||||
*/
|
|
||||||
public final class $Gson$Types {
|
|
||||||
static final Type[] EMPTY_TYPE_ARRAY = new Type[] {};
|
|
||||||
|
|
||||||
private $Gson$Types() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new parameterized type, applying {@code typeArguments} to
|
|
||||||
* {@code rawType} and enclosed by {@code ownerType}.
|
|
||||||
*
|
|
||||||
* @return a {@link java.io.Serializable serializable} parameterized type.
|
|
||||||
*/
|
|
||||||
public static ParameterizedType newParameterizedTypeWithOwner(
|
|
||||||
Type ownerType, Type rawType, Type... typeArguments) {
|
|
||||||
return new ParameterizedTypeImpl(ownerType, rawType, typeArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array type whose elements are all instances of
|
|
||||||
* {@code componentType}.
|
|
||||||
*
|
|
||||||
* @return a {@link java.io.Serializable serializable} generic array type.
|
|
||||||
*/
|
|
||||||
public static GenericArrayType arrayOf(Type componentType) {
|
|
||||||
return new GenericArrayTypeImpl(componentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a type that represents an unknown type that extends {@code bound}.
|
|
||||||
* For example, if {@code bound} is {@code CharSequence.class}, this returns
|
|
||||||
* {@code ? extends CharSequence}. If {@code bound} is {@code Object.class},
|
|
||||||
* this returns {@code ?}, which is shorthand for {@code ? extends Object}.
|
|
||||||
*/
|
|
||||||
public static WildcardType subtypeOf(Type bound) {
|
|
||||||
return new WildcardTypeImpl(new Type[] { bound }, EMPTY_TYPE_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a type that represents an unknown supertype of {@code bound}. For
|
|
||||||
* example, if {@code bound} is {@code String.class}, this returns {@code ?
|
|
||||||
* super String}.
|
|
||||||
*/
|
|
||||||
public static WildcardType supertypeOf(Type bound) {
|
|
||||||
return new WildcardTypeImpl(new Type[] { Object.class }, new Type[] { bound });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a type that is functionally equal but not necessarily equal
|
|
||||||
* according to {@link Object#equals(Object) Object.equals()}. The returned
|
|
||||||
* type is {@link java.io.Serializable}.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Type canonicalize(Type type) {
|
|
||||||
if (type instanceof Class) {
|
|
||||||
Class<?> c = (Class<?>) type;
|
|
||||||
return c.isArray() ? new GenericArrayTypeImpl(canonicalize(c.getComponentType())) : c;
|
|
||||||
|
|
||||||
} else if (type instanceof ParameterizedType) {
|
|
||||||
ParameterizedType p = (ParameterizedType) type;
|
|
||||||
return new ParameterizedTypeImpl(p.getOwnerType(),
|
|
||||||
p.getRawType(), p.getActualTypeArguments());
|
|
||||||
|
|
||||||
} else if (type instanceof GenericArrayType) {
|
|
||||||
GenericArrayType g = (GenericArrayType) type;
|
|
||||||
return new GenericArrayTypeImpl(g.getGenericComponentType());
|
|
||||||
|
|
||||||
} else if (type instanceof WildcardType) {
|
|
||||||
WildcardType w = (WildcardType) type;
|
|
||||||
return new WildcardTypeImpl(w.getUpperBounds(), w.getLowerBounds());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// type is either serializable as-is or unsupported
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Class<?> getRawType(Type type) {
|
|
||||||
if (type instanceof Class<?>) {
|
|
||||||
// type is a normal class.
|
|
||||||
return (Class<?>) type;
|
|
||||||
|
|
||||||
} else if (type instanceof ParameterizedType) {
|
|
||||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
|
||||||
|
|
||||||
// I'm not exactly sure why getRawType() returns Type instead of Class.
|
|
||||||
// Neal isn't either but suspects some pathological case related
|
|
||||||
// to nested classes exists.
|
|
||||||
Type rawType = parameterizedType.getRawType();
|
|
||||||
checkArgument(rawType instanceof Class);
|
|
||||||
return (Class<?>) rawType;
|
|
||||||
|
|
||||||
} else if (type instanceof GenericArrayType) {
|
|
||||||
Type componentType = ((GenericArrayType)type).getGenericComponentType();
|
|
||||||
return Array.newInstance(getRawType(componentType), 0).getClass();
|
|
||||||
|
|
||||||
} else if (type instanceof TypeVariable) {
|
|
||||||
// we could use the variable's bounds, but that won't work if there are multiple.
|
|
||||||
// having a raw type that's more general than necessary is okay
|
|
||||||
return Object.class;
|
|
||||||
|
|
||||||
} else if (type instanceof WildcardType) {
|
|
||||||
return getRawType(((WildcardType) type).getUpperBounds()[0]);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
String className = type == null ? "null" : type.getClass().getName();
|
|
||||||
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
|
|
||||||
+ "GenericArrayType, but <" + type + "> is of type " + className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean equal(Object a, Object b) {
|
|
||||||
return a == b || (a != null && a.equals(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if {@code a} and {@code b} are equal.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static boolean equals(Type a, Type b) {
|
|
||||||
if (a == b) {
|
|
||||||
// also handles (a == null && b == null)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (a instanceof Class) {
|
|
||||||
// Class already specifies equals().
|
|
||||||
return a.equals(b);
|
|
||||||
|
|
||||||
} else if (a instanceof ParameterizedType) {
|
|
||||||
if (!(b instanceof ParameterizedType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: save a .clone() call
|
|
||||||
ParameterizedType pa = (ParameterizedType) a;
|
|
||||||
ParameterizedType pb = (ParameterizedType) b;
|
|
||||||
return equal(pa.getOwnerType(), pb.getOwnerType())
|
|
||||||
&& pa.getRawType().equals(pb.getRawType())
|
|
||||||
&& Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments());
|
|
||||||
|
|
||||||
} else if (a instanceof GenericArrayType) {
|
|
||||||
if (!(b instanceof GenericArrayType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericArrayType ga = (GenericArrayType) a;
|
|
||||||
GenericArrayType gb = (GenericArrayType) b;
|
|
||||||
return equals(ga.getGenericComponentType(), gb.getGenericComponentType());
|
|
||||||
|
|
||||||
} else if (a instanceof WildcardType) {
|
|
||||||
if (!(b instanceof WildcardType)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WildcardType wa = (WildcardType) a;
|
|
||||||
WildcardType wb = (WildcardType) b;
|
|
||||||
return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds())
|
|
||||||
&& Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds());
|
|
||||||
|
|
||||||
} else if (a instanceof TypeVariable) {
|
|
||||||
if (!(b instanceof TypeVariable)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TypeVariable<?> va = (TypeVariable<?>) a;
|
|
||||||
TypeVariable<?> vb = (TypeVariable<?>) b;
|
|
||||||
return va.getGenericDeclaration() == vb.getGenericDeclaration()
|
|
||||||
&& va.getName().equals(vb.getName());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// This isn't a type we support. Could be a generic array type, wildcard type, etc.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int hashCodeOrZero(Object o) {
|
|
||||||
return o != null ? o.hashCode() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static String typeToString(Type type) {
|
|
||||||
return type instanceof Class ? ((Class<?>) type).getName() : type.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the generic supertype for {@code supertype}. For example, given a class {@code
|
|
||||||
* IntegerSet}, the result for when supertype is {@code Set.class} is {@code Set<Integer>} and the
|
|
||||||
* result when the supertype is {@code Collection.class} is {@code Collection<Integer>}.
|
|
||||||
*/
|
|
||||||
static Type getGenericSupertype(Type context, Class<?> rawType, Class<?> toResolve) {
|
|
||||||
if (toResolve == rawType) {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we skip searching through interfaces if unknown is an interface
|
|
||||||
if (toResolve.isInterface()) {
|
|
||||||
Class<?>[] interfaces = rawType.getInterfaces();
|
|
||||||
for (int i = 0, length = interfaces.length; i < length; i++) {
|
|
||||||
if (interfaces[i] == toResolve) {
|
|
||||||
return rawType.getGenericInterfaces()[i];
|
|
||||||
} else if (toResolve.isAssignableFrom(interfaces[i])) {
|
|
||||||
return getGenericSupertype(rawType.getGenericInterfaces()[i], interfaces[i], toResolve);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check our supertypes
|
|
||||||
if (!rawType.isInterface()) {
|
|
||||||
while (rawType != Object.class) {
|
|
||||||
Class<?> rawSupertype = rawType.getSuperclass();
|
|
||||||
if (rawSupertype == toResolve) {
|
|
||||||
return rawType.getGenericSuperclass();
|
|
||||||
} else if (toResolve.isAssignableFrom(rawSupertype)) {
|
|
||||||
return getGenericSupertype(rawType.getGenericSuperclass(), rawSupertype, toResolve);
|
|
||||||
}
|
|
||||||
rawType = rawSupertype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we can't resolve this further
|
|
||||||
return toResolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the generic form of {@code supertype}. For example, if this is {@code
|
|
||||||
* ArrayList<String>}, this returns {@code Iterable<String>} given the input {@code
|
|
||||||
* Iterable.class}.
|
|
||||||
*
|
|
||||||
* @param supertype a superclass of, or interface implemented by, this.
|
|
||||||
*/
|
|
||||||
static Type getSupertype(Type context, Class<?> contextRawType, Class<?> supertype) {
|
|
||||||
checkArgument(supertype.isAssignableFrom(contextRawType));
|
|
||||||
return resolve(context, contextRawType,
|
|
||||||
$Gson$Types.getGenericSupertype(context, contextRawType, supertype));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this type is an array.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static boolean isArray(Type type) {
|
|
||||||
return type instanceof GenericArrayType
|
|
||||||
|| (type instanceof Class && ((Class<?>) type).isArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the component type of this array type.
|
|
||||||
* @throws ClassCastException if this type is not an array.
|
|
||||||
*/
|
|
||||||
public static Type getArrayComponentType(Type array) {
|
|
||||||
return array instanceof GenericArrayType
|
|
||||||
? ((GenericArrayType) array).getGenericComponentType()
|
|
||||||
: ((Class<?>) array).getComponentType();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the element type of this collection type.
|
|
||||||
* @throws IllegalArgumentException if this type is not a collection.
|
|
||||||
*/
|
|
||||||
public static Type getCollectionElementType(Type context, Class<?> contextRawType) {
|
|
||||||
Type collectionType = getSupertype(context, contextRawType, Collection.class);
|
|
||||||
return ((ParameterizedType) collectionType).getActualTypeArguments()[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a two element array containing this map's key and value types in
|
|
||||||
* positions 0 and 1 respectively.
|
|
||||||
*/
|
|
||||||
public static Type[] getMapKeyAndValueTypes(Type context, Class<?> contextRawType) {
|
|
||||||
/*
|
|
||||||
* Work around a problem with the declaration of java.util.Properties. That
|
|
||||||
* class should extend Hashtable<String, String>, but it's declared to
|
|
||||||
* extend Hashtable<Object, Object>.
|
|
||||||
*/
|
|
||||||
if (context == Properties.class) {
|
|
||||||
return new Type[] { String.class, String.class }; // TODO: test subclasses of Properties!
|
|
||||||
}
|
|
||||||
|
|
||||||
Type mapType = getSupertype(context, contextRawType, Map.class);
|
|
||||||
ParameterizedType mapParameterizedType = (ParameterizedType) mapType;
|
|
||||||
return mapParameterizedType.getActualTypeArguments();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Type resolve(Type context, Class<?> contextRawType, Type toResolve) {
|
|
||||||
// this implementation is made a little more complicated in an attempt to avoid object-creation
|
|
||||||
while (true) {
|
|
||||||
if (toResolve instanceof TypeVariable) {
|
|
||||||
TypeVariable<?> typeVariable = (TypeVariable<?>) toResolve;
|
|
||||||
toResolve = resolveTypeVariable(context, contextRawType, typeVariable);
|
|
||||||
if (toResolve == typeVariable) {
|
|
||||||
return toResolve;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (toResolve instanceof Class && ((Class<?>) toResolve).isArray()) {
|
|
||||||
Class<?> original = (Class<?>) toResolve;
|
|
||||||
Type componentType = original.getComponentType();
|
|
||||||
Type newComponentType = resolve(context, contextRawType, componentType);
|
|
||||||
return componentType == newComponentType
|
|
||||||
? original
|
|
||||||
: arrayOf(newComponentType);
|
|
||||||
|
|
||||||
} else if (toResolve instanceof GenericArrayType) {
|
|
||||||
GenericArrayType original = (GenericArrayType) toResolve;
|
|
||||||
Type componentType = original.getGenericComponentType();
|
|
||||||
Type newComponentType = resolve(context, contextRawType, componentType);
|
|
||||||
return componentType == newComponentType
|
|
||||||
? original
|
|
||||||
: arrayOf(newComponentType);
|
|
||||||
|
|
||||||
} else if (toResolve instanceof ParameterizedType) {
|
|
||||||
ParameterizedType original = (ParameterizedType) toResolve;
|
|
||||||
Type ownerType = original.getOwnerType();
|
|
||||||
Type newOwnerType = resolve(context, contextRawType, ownerType);
|
|
||||||
boolean changed = newOwnerType != ownerType;
|
|
||||||
|
|
||||||
Type[] args = original.getActualTypeArguments();
|
|
||||||
for (int t = 0, length = args.length; t < length; t++) {
|
|
||||||
Type resolvedTypeArgument = resolve(context, contextRawType, args[t]);
|
|
||||||
if (resolvedTypeArgument != args[t]) {
|
|
||||||
if (!changed) {
|
|
||||||
args = args.clone();
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
args[t] = resolvedTypeArgument;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed
|
|
||||||
? newParameterizedTypeWithOwner(newOwnerType, original.getRawType(), args)
|
|
||||||
: original;
|
|
||||||
|
|
||||||
} else if (toResolve instanceof WildcardType) {
|
|
||||||
WildcardType original = (WildcardType) toResolve;
|
|
||||||
Type[] originalLowerBound = original.getLowerBounds();
|
|
||||||
Type[] originalUpperBound = original.getUpperBounds();
|
|
||||||
|
|
||||||
if (originalLowerBound.length == 1) {
|
|
||||||
Type lowerBound = resolve(context, contextRawType, originalLowerBound[0]);
|
|
||||||
if (lowerBound != originalLowerBound[0]) {
|
|
||||||
return supertypeOf(lowerBound);
|
|
||||||
}
|
|
||||||
} else if (originalUpperBound.length == 1) {
|
|
||||||
Type upperBound = resolve(context, contextRawType, originalUpperBound[0]);
|
|
||||||
if (upperBound != originalUpperBound[0]) {
|
|
||||||
return subtypeOf(upperBound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return toResolve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
static Type resolveTypeVariable(Type context, Class<?> contextRawType, TypeVariable unknown) {
|
|
||||||
Class<?> declaredByRaw = declaringClassOf(unknown);
|
|
||||||
|
|
||||||
// we can't reduce this further
|
|
||||||
if (declaredByRaw == null) {
|
|
||||||
return unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type declaredBy = getGenericSupertype(context, contextRawType, declaredByRaw);
|
|
||||||
if (declaredBy instanceof ParameterizedType) {
|
|
||||||
int index = indexOf(declaredByRaw.getTypeParameters(), unknown);
|
|
||||||
return ((ParameterizedType) declaredBy).getActualTypeArguments()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int indexOf(Object[] array, Object toFind) {
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
if (toFind.equals(array[i])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchElementException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the declaring class of {@code typeVariable}, or {@code null} if it was not declared by
|
|
||||||
* a class.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static Class<?> declaringClassOf(TypeVariable typeVariable) {
|
|
||||||
GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
|
|
||||||
return genericDeclaration instanceof Class
|
|
||||||
? (Class<?>) genericDeclaration
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkNotPrimitive(Type type) {
|
|
||||||
checkArgument(!(type instanceof Class<?>) || !((Class<?>) type).isPrimitive());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class ParameterizedTypeImpl implements ParameterizedType, Serializable {
|
|
||||||
private final Type ownerType;
|
|
||||||
private final Type rawType;
|
|
||||||
private final Type[] typeArguments;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public ParameterizedTypeImpl(Type ownerType, Type rawType, Type... typeArguments) {
|
|
||||||
// require an owner type if the raw type needs it
|
|
||||||
if (rawType instanceof Class<?>) {
|
|
||||||
Class rawTypeAsClass = (Class) rawType;
|
|
||||||
checkArgument(ownerType != null || rawTypeAsClass.getEnclosingClass() == null);
|
|
||||||
checkArgument(ownerType == null || rawTypeAsClass.getEnclosingClass() != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.ownerType = ownerType == null ? null : canonicalize(ownerType);
|
|
||||||
this.rawType = canonicalize(rawType);
|
|
||||||
this.typeArguments = typeArguments.clone();
|
|
||||||
for (int t = 0; t < this.typeArguments.length; t++) {
|
|
||||||
checkNotNull(this.typeArguments[t]);
|
|
||||||
checkNotPrimitive(this.typeArguments[t]);
|
|
||||||
this.typeArguments[t] = canonicalize(this.typeArguments[t]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type[] getActualTypeArguments() {
|
|
||||||
return typeArguments.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type getRawType() {
|
|
||||||
return rawType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type getOwnerType() {
|
|
||||||
return ownerType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean equals(Object other) {
|
|
||||||
return other instanceof ParameterizedType
|
|
||||||
&& $Gson$Types.equals(this, (ParameterizedType) other);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode() {
|
|
||||||
return Arrays.hashCode(typeArguments)
|
|
||||||
^ rawType.hashCode()
|
|
||||||
^ hashCodeOrZero(ownerType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString() {
|
|
||||||
StringBuilder stringBuilder = new StringBuilder(30 * (typeArguments.length + 1));
|
|
||||||
stringBuilder.append(typeToString(rawType));
|
|
||||||
|
|
||||||
if (typeArguments.length == 0) {
|
|
||||||
return stringBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuilder.append("<").append(typeToString(typeArguments[0]));
|
|
||||||
for (int i = 1; i < typeArguments.length; i++) {
|
|
||||||
stringBuilder.append(", ").append(typeToString(typeArguments[i]));
|
|
||||||
}
|
|
||||||
return stringBuilder.append(">").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class GenericArrayTypeImpl implements GenericArrayType, Serializable {
|
|
||||||
private final Type componentType;
|
|
||||||
|
|
||||||
public GenericArrayTypeImpl(Type componentType) {
|
|
||||||
this.componentType = canonicalize(componentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type getGenericComponentType() {
|
|
||||||
return componentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean equals(Object o) {
|
|
||||||
return o instanceof GenericArrayType
|
|
||||||
&& $Gson$Types.equals(this, (GenericArrayType) o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode() {
|
|
||||||
return componentType.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString() {
|
|
||||||
return typeToString(componentType) + "[]";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The WildcardType interface supports multiple upper bounds and multiple
|
|
||||||
* lower bounds. We only support what the Java 6 language needs - at most one
|
|
||||||
* bound. If a lower bound is set, the upper bound must be Object.class.
|
|
||||||
*/
|
|
||||||
private static final class WildcardTypeImpl implements WildcardType, Serializable {
|
|
||||||
private final Type upperBound;
|
|
||||||
private final Type lowerBound;
|
|
||||||
|
|
||||||
public WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) {
|
|
||||||
checkArgument(lowerBounds.length <= 1);
|
|
||||||
checkArgument(upperBounds.length == 1);
|
|
||||||
|
|
||||||
if (lowerBounds.length == 1) {
|
|
||||||
checkNotNull(lowerBounds[0]);
|
|
||||||
checkNotPrimitive(lowerBounds[0]);
|
|
||||||
checkArgument(upperBounds[0] == Object.class);
|
|
||||||
this.lowerBound = canonicalize(lowerBounds[0]);
|
|
||||||
this.upperBound = Object.class;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
checkNotNull(upperBounds[0]);
|
|
||||||
checkNotPrimitive(upperBounds[0]);
|
|
||||||
this.lowerBound = null;
|
|
||||||
this.upperBound = canonicalize(upperBounds[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type[] getUpperBounds() {
|
|
||||||
return new Type[] { upperBound };
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type[] getLowerBounds() {
|
|
||||||
return lowerBound != null ? new Type[] { lowerBound } : EMPTY_TYPE_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public boolean equals(Object other) {
|
|
||||||
return other instanceof WildcardType
|
|
||||||
&& $Gson$Types.equals(this, (WildcardType) other);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int hashCode() {
|
|
||||||
// this equals Arrays.hashCode(getLowerBounds()) ^ Arrays.hashCode(getUpperBounds());
|
|
||||||
return (lowerBound != null ? 31 + lowerBound.hashCode() : 1)
|
|
||||||
^ (31 + upperBound.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString() {
|
|
||||||
if (lowerBound != null) {
|
|
||||||
return "? super " + typeToString(lowerBound);
|
|
||||||
} else if (upperBound == Object.class) {
|
|
||||||
return "?";
|
|
||||||
} else {
|
|
||||||
return "? extends " + typeToString(upperBound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 0;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
/**
|
|
||||||
* Do NOT use any class in this package as they are meant for internal use in Gson.
|
|
||||||
* These classes will very likely change incompatibly in future versions. You have been warned.
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh, Joel Leitch, Jesse Wilson
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.gson.internal;
|
|
@ -1,11 +0,0 @@
|
|||||||
/**
|
|
||||||
* This package provides the {@link com.google.gson.Gson} class to convert Json to Java and
|
|
||||||
* vice-versa.
|
|
||||||
*
|
|
||||||
* <p>The primary class to use is {@link com.google.gson.Gson} which can be constructed with
|
|
||||||
* {@code new Gson()} (using default settings) or by using {@link com.google.gson.GsonBuilder}
|
|
||||||
* (to configure various options such as using versioning and so on).</p>
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh, Joel Leitch
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.gson;
|
|
@ -1,309 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.massivecraft.factions.gson.reflect;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Preconditions;
|
|
||||||
import com.massivecraft.factions.gson.internal.$Gson$Types;
|
|
||||||
|
|
||||||
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}. Java doesn't yet provide a way to
|
|
||||||
* represent generic types, so this class does. Forces clients to create a
|
|
||||||
* subclass of this class which enables retrieval the type information even at
|
|
||||||
* runtime.
|
|
||||||
*
|
|
||||||
* <p>For example, to create a type literal for {@code List<String>}, you can
|
|
||||||
* create an empty anonymous inner class:
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* {@code TypeToken<List<String>> list = new TypeToken<List<String>>() {};}
|
|
||||||
*
|
|
||||||
* <p>This syntax cannot be used to create type literals that have wildcard
|
|
||||||
* parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}.
|
|
||||||
*
|
|
||||||
* @author Bob Lee
|
|
||||||
* @author Sven Mawson
|
|
||||||
* @author Jesse Wilson
|
|
||||||
*/
|
|
||||||
public class TypeToken<T> {
|
|
||||||
|
|
||||||
final Class<? super T> rawType;
|
|
||||||
final Type type;
|
|
||||||
final int hashCode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new type literal. Derives represented class from type
|
|
||||||
* parameter.
|
|
||||||
*
|
|
||||||
* <p>Clients create an empty anonymous subclass. Doing so embeds the type
|
|
||||||
* parameter in the anonymous class's type hierarchy so we can reconstitute it
|
|
||||||
* at runtime despite erasure.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected TypeToken() {
|
|
||||||
this.type = getSuperclassTypeParameter(getClass());
|
|
||||||
this.rawType = (Class<? super T>) $Gson$Types.getRawType(type);
|
|
||||||
this.hashCode = type.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsafe. Constructs a type literal manually.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
TypeToken(Type type) {
|
|
||||||
this.type = $Gson$Types.canonicalize($Gson$Preconditions.checkNotNull(type));
|
|
||||||
this.rawType = (Class<? super T>) $Gson$Types.getRawType(this.type);
|
|
||||||
this.hashCode = this.type.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the type from super class's type parameter in {@link $Gson$Types#canonicalize
|
|
||||||
* canonical form}.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
static Type getSuperclassTypeParameter(Class<?> subclass) {
|
|
||||||
Type superclass = subclass.getGenericSuperclass();
|
|
||||||
if (superclass instanceof Class) {
|
|
||||||
throw new RuntimeException("Missing type parameter.");
|
|
||||||
}
|
|
||||||
ParameterizedType parameterized = (ParameterizedType) superclass;
|
|
||||||
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the raw (non-generic) type for this type.
|
|
||||||
*/
|
|
||||||
public final Class<? super T> getRawType() {
|
|
||||||
return rawType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets underlying {@code Type} instance.
|
|
||||||
*/
|
|
||||||
public final Type getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this type is assignable from the given class object.
|
|
||||||
*
|
|
||||||
* @deprecated this implementation may be inconsistent with javac for types
|
|
||||||
* with wildcards.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public boolean isAssignableFrom(Class<?> cls) {
|
|
||||||
return isAssignableFrom((Type) cls);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this type is assignable from the given Type.
|
|
||||||
*
|
|
||||||
* @deprecated this implementation may be inconsistent with javac for types
|
|
||||||
* with wildcards.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public boolean isAssignableFrom(Type from) {
|
|
||||||
if (from == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.equals(from)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type instanceof Class<?>) {
|
|
||||||
return rawType.isAssignableFrom($Gson$Types.getRawType(from));
|
|
||||||
} else if (type instanceof ParameterizedType) {
|
|
||||||
return isAssignableFrom(from, (ParameterizedType) type,
|
|
||||||
new HashMap<String, Type>());
|
|
||||||
} else if (type instanceof GenericArrayType) {
|
|
||||||
return rawType.isAssignableFrom($Gson$Types.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.
|
|
||||||
*
|
|
||||||
* @deprecated this implementation may be inconsistent with javac for types
|
|
||||||
* with wildcards.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
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 = $Gson$Types.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();
|
|
||||||
return isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if two types are the same or are equivalent under a variable mapping
|
|
||||||
* given in the type map that was provided.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
|
|
||||||
return to.equals(from)
|
|
||||||
|| (from instanceof TypeVariable
|
|
||||||
&& to.equals(typeMap.get(((TypeVariable<?>) from).getName())));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final int hashCode() {
|
|
||||||
return this.hashCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final boolean equals(Object o) {
|
|
||||||
return o instanceof TypeToken<?>
|
|
||||||
&& $Gson$Types.equals(type, ((TypeToken<?>) o).type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public final String toString() {
|
|
||||||
return $Gson$Types.typeToString(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets type literal for the given {@code Type} instance.
|
|
||||||
*/
|
|
||||||
public static TypeToken<?> get(Type type) {
|
|
||||||
return new TypeToken<Object>(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets type literal for the given {@code Class} instance.
|
|
||||||
*/
|
|
||||||
public static <T> TypeToken<T> get(Class<T> type) {
|
|
||||||
return new TypeToken<T>(type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* This package provides utility classes for finding type information for generic types.
|
|
||||||
*
|
|
||||||
* @author Inderjeet Singh, Joel Leitch
|
|
||||||
*/
|
|
||||||
package com.massivecraft.factions.gson.reflect;
|
|
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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,
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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
|
|
||||||
}
|
|
@ -1,553 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.massivecraft.factions.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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
59
src/com/massivecraft/factions/util/JarLoader.java
Normal file
59
src/com/massivecraft/factions/util/JarLoader.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package com.massivecraft.factions.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class JarLoader {
|
||||||
|
|
||||||
|
private static URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
|
||||||
|
|
||||||
|
public static boolean load(String filename) {
|
||||||
|
return load(new File(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean load(File file) {
|
||||||
|
if ( ! file.exists()) {
|
||||||
|
log("This file does not exist: " + file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return load(file.toURI().toURL());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
log("The url for \""+file+"\" was malformed." + e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean load(URL url) {
|
||||||
|
// If the file already is loaded we can skip it
|
||||||
|
for (URL otherUrl : sysloader.getURLs()) {
|
||||||
|
if (otherUrl.sameFile(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{ URL.class });
|
||||||
|
addURLMethod.setAccessible(true);
|
||||||
|
addURLMethod.invoke(sysloader, new Object[]{ url });
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("Failed to load \""+url+"\":" + e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Logger
|
||||||
|
// -------------------------------------------- //
|
||||||
|
private static void log(Object o) {
|
||||||
|
Logger.getLogger("Minecraft").log(Level.SEVERE, "[JAR-LOADER] " + o);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
name: Factions
|
name: Factions
|
||||||
version: 1.4.1
|
version: 1.4.2
|
||||||
main: com.massivecraft.factions.Factions
|
main: com.massivecraft.factions.Factions
|
||||||
softdepend:
|
softdepend:
|
||||||
- Permissions
|
- Permissions
|
||||||
|
Loading…
Reference in New Issue
Block a user