Custom collections with special GSON behavior, and other stuffs...

This commit is contained in:
Olof Larsson 2014-10-18 18:31:07 +02:00
parent c4a7a4988c
commit 7f48580e51
25 changed files with 1006 additions and 24 deletions

View File

@ -0,0 +1,24 @@
package com.massivecraft.massivecore;
import java.util.Comparator;
public class CaseInsensitiveComparator implements Comparator<String>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static CaseInsensitiveComparator i = new CaseInsensitiveComparator();
public static CaseInsensitiveComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public int compare(String o1, String o2)
{
return String.CASE_INSENSITIVE_ORDER.compare(o1, o2);
}
}

View File

@ -15,14 +15,29 @@ import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.adapter.InventoryAdapter; import com.massivecraft.massivecore.adapter.InventoryAdapter;
import com.massivecraft.massivecore.adapter.ItemStackAdapter; import com.massivecraft.massivecore.adapter.ItemStackAdapter;
import com.massivecraft.massivecore.adapter.JsonElementAdapter; import com.massivecraft.massivecore.adapter.JsonElementAdapter;
import com.massivecraft.massivecore.adapter.MassiveListAdapter;
import com.massivecraft.massivecore.adapter.MassiveMapAdapter;
import com.massivecraft.massivecore.adapter.MassiveSetAdapter;
import com.massivecraft.massivecore.adapter.MassiveTreeSetAdapter;
import com.massivecraft.massivecore.adapter.ModdedEnumTypeAdapter; import com.massivecraft.massivecore.adapter.ModdedEnumTypeAdapter;
import com.massivecraft.massivecore.adapter.PlayerInventoryAdapter; import com.massivecraft.massivecore.adapter.PlayerInventoryAdapter;
import com.massivecraft.massivecore.adapter.MassiveTreeMapAdapter;
import com.massivecraft.massivecore.adapter.UUIDAdapter; import com.massivecraft.massivecore.adapter.UUIDAdapter;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCore; import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCore;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreBuffer; import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreBuffer;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreCmdurl; import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreCmdurl;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreStore; import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreStore;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreUsys; import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreUsys;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveListDef;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveMapDef;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveSetDef;
import com.massivecraft.massivecore.collections.MassiveTreeMap;
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.event.EventMassiveCoreUuidUpdate; import com.massivecraft.massivecore.event.EventMassiveCoreUuidUpdate;
import com.massivecraft.massivecore.fetcher.Fetcher; import com.massivecraft.massivecore.fetcher.Fetcher;
import com.massivecraft.massivecore.fetcher.IdAndName; import com.massivecraft.massivecore.fetcher.IdAndName;
@ -88,6 +103,18 @@ public class MassiveCore extends MassivePlugin
.registerTypeAdapter(Inventory.class, InventoryAdapter.get()) .registerTypeAdapter(Inventory.class, InventoryAdapter.get())
.registerTypeAdapter(PlayerInventory.class, PlayerInventoryAdapter.get()) .registerTypeAdapter(PlayerInventory.class, PlayerInventoryAdapter.get())
.registerTypeAdapter(PS.class, PSAdapter.get()) .registerTypeAdapter(PS.class, PSAdapter.get())
.registerTypeAdapter(MassiveList.class, MassiveListAdapter.get())
.registerTypeAdapter(MassiveListDef.class, MassiveListAdapter.get())
.registerTypeAdapter(MassiveMap.class, MassiveMapAdapter.get())
.registerTypeAdapter(MassiveMapDef.class, MassiveMapAdapter.get())
.registerTypeAdapter(MassiveSet.class, MassiveSetAdapter.get())
.registerTypeAdapter(MassiveSetDef.class, MassiveSetAdapter.get())
.registerTypeAdapter(MassiveTreeMap.class, MassiveTreeMapAdapter.get())
.registerTypeAdapter(MassiveTreeMapDef.class, MassiveTreeMapAdapter.get())
.registerTypeAdapter(MassiveTreeSet.class, MassiveTreeSetAdapter.get())
.registerTypeAdapter(MassiveTreeSetDef.class, MassiveTreeSetAdapter.get())
.registerTypeAdapterFactory(ModdedEnumTypeAdapter.ENUM_FACTORY); .registerTypeAdapterFactory(ModdedEnumTypeAdapter.ENUM_FACTORY);
} }

View File

@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveListDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveListAdapter extends MassiveXAdapter<MassiveList<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveListAdapter i = new MassiveListAdapter();
public static MassiveListAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveList<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveListDef((Collection)parent);
}
else
{
return new MassiveList((Collection)parent);
}
}
}

View File

@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Map;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveMapDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveMapAdapter extends MassiveXAdapter<MassiveMap<?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveMapAdapter i = new MassiveMapAdapter();
public static MassiveMapAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveMap<?,?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveMapDef((Map)parent);
}
else
{
return new MassiveMap((Map)parent);
}
}
}

View File

@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveSetDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveSetAdapter extends MassiveXAdapter<MassiveSet<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveSetAdapter i = new MassiveSetAdapter();
public static MassiveSetAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveSet<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveSetDef((Collection)parent);
}
else
{
return new MassiveSet((Collection)parent);
}
}
}

View File

@ -0,0 +1,48 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Map;
import com.massivecraft.massivecore.collections.MassiveTreeMap;
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveTreeMapAdapter extends MassiveXAdapter<MassiveTreeMap<?, ?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveTreeMapAdapter i = new MassiveTreeMapAdapter();
public static MassiveTreeMapAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveTreeMap<?, ?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
Object comparator = getComparator(typeOfT);
if (def)
{
return new MassiveTreeMapDef(comparator, (Map)parent);
}
else
{
return new MassiveTreeMap(comparator, (Map)parent);
}
}
// -------------------------------------------- //
// GET COMPARATOR
// -------------------------------------------- //
public static Object getComparator(Type typeOfT)
{
return getNewArgumentInstance(typeOfT, 2);
}
}

View File

@ -0,0 +1,48 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveTreeSetAdapter extends MassiveXAdapter<MassiveTreeSet<?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveTreeSetAdapter i = new MassiveTreeSetAdapter();
public static MassiveTreeSetAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveTreeSet<?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
Object comparator = getComparator(typeOfT);
if (def)
{
return new MassiveTreeSetDef(comparator, (Collection)parent);
}
else
{
return new MassiveTreeSet(comparator, (Collection)parent);
}
}
// -------------------------------------------- //
// GET COMPARATOR
// -------------------------------------------- //
public static Object getComparator(Type typeOfT)
{
return getNewArgumentInstance(typeOfT, 1);
}
}

View File

@ -0,0 +1,146 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import com.massivecraft.massivecore.collections.Def;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
/**
* This is the abstract adapter for all "Massive structures".
* It makes sure Def instances "handle empty as null".
* It makes sure we avoid infinite GSON recurse loops by recursing with supertype.
*/
public abstract class MassiveXAdapter<T> implements JsonDeserializer<T>, JsonSerializer<T>
{
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(T src, Type type, JsonSerializationContext context)
{
// Calculate def
Class<?> clazz = getClazz(type);
boolean def = Def.class.isAssignableFrom(clazz);
// If this is a Def ...
if (def)
{
// ... and the instance is null or contains no elements ...
if (isEmpty(src))
{
// ... then serialize as a JsonNull!
return JsonNull.INSTANCE;
}
// ... and it's non null and contains something ...
else
{
// ... then serialize it as if it were the regular Java collection!
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
return context.serialize(src, getSuperType(getSuperType(type)));
}
}
// If this a regular Massive structure and not a Def ...
else
{
// ... then serialize it as if it were the regular java collection!
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
return context.serialize(src, getSuperType(type));
}
}
@Override
public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException
{
// Calculate def
Class<?> clazz = getClazz(type);
boolean def = Def.class.isAssignableFrom(clazz);
// If this is a Def ...
if (def)
{
// ... then deserialize it as if it were the regular Java collection!
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
Object parent = context.deserialize(json, getSuperType(getSuperType(type)));
return create(parent, def, json, type, context);
}
// If this a regular Massive structure and not a Def ...
else
{
// ... and the json is null or a JsonNull ...
if (json == null || json instanceof JsonNull)
{
// ... then deserialize as a null!
return null;
}
// ... and it's non null and contains something ...
else
{
// ... then deserialize it as if it were the regular java collection!
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
Object parent = context.deserialize(json, getSuperType(type));
return create(parent, def, json, type, context);
}
}
}
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract T create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context);
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static Class<?> getClazz(Type type)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?> clazz = (Class<?>)parameterizedType.getRawType();
return clazz;
}
public static Type getSuperType(Type type)
{
Class<?> clazz = getClazz(type);
Type superclazz = clazz.getGenericSuperclass();
return superclazz;
}
public static Object getNewArgumentInstance(Type type, int index)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
Class<?> clazz = (Class<?>) actualTypeArguments[index];
try
{
return clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object object)
{
// A Map is not a Collection.
// Thus we have to use isEmpty() declared in different interfaces.
if (object == null) return true;
if (object instanceof Map) return ((Map)object).isEmpty();
if (object instanceof Collection) return ((Collection)object).isEmpty();
return false;
}
}

View File

@ -49,10 +49,29 @@ public class MassiveCommand
public void setSubCommands(List<MassiveCommand> subCommands) { this.subCommands = subCommands; } public void setSubCommands(List<MassiveCommand> subCommands) { this.subCommands = subCommands; }
public void addSubCommand(MassiveCommand subCommand) public void addSubCommand(MassiveCommand subCommand)
{
this.addSubCommand(subCommand, this.subCommands.size());
}
public void addSubCommand(MassiveCommand subCommand, MassiveCommand after)
{
int index = this.subCommands.indexOf(after);
if (index == -1)
{
index = this.subCommands.size();
}
else
{
index++;
}
this.addSubCommand(subCommand, index);
}
public void addSubCommand(MassiveCommand subCommand, int index)
{ {
subCommand.commandChain.addAll(this.commandChain); subCommand.commandChain.addAll(this.commandChain);
subCommand.commandChain.add(this); subCommand.commandChain.add(this);
this.subCommands.add(subCommand); this.subCommands.add(index, subCommand);
} }
// FIELD: aliases // FIELD: aliases

View File

@ -0,0 +1,6 @@
package com.massivecraft.massivecore.collections;
public interface Def
{
}

View File

@ -0,0 +1,50 @@
package com.massivecraft.massivecore.collections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
/**
* This subclass adds better constructors.
*/
public class MassiveList<E> extends ArrayList<E>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: BASE
// -------------------------------------------- //
public MassiveList(int initialCapacity)
{
super(initialCapacity);
}
public MassiveList()
{
super();
}
@SuppressWarnings("unchecked")
public MassiveList(Collection<? extends E> c)
{
// Support Null
super(c == null ? Collections.EMPTY_LIST : c);
}
// -------------------------------------------- //
// CONSTRUCT: EXTRA
// -------------------------------------------- //
@SafeVarargs
public MassiveList(E... elements)
{
this(Arrays.asList(elements));
}
}

View File

@ -0,0 +1,42 @@
package com.massivecraft.massivecore.collections;
import java.util.Collection;
/**
* This subclass does nothing new except implementing the Def interface.
* Def is short for "Default" and means GSON should handle "null" as "empty".
*/
public class MassiveListDef<E> extends MassiveList<E> implements Def
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: SUPER
// -------------------------------------------- //
public MassiveListDef(int initialCapacity)
{
super(initialCapacity);
}
public MassiveListDef()
{
super();
}
public MassiveListDef(Collection<? extends E> c)
{
super(c);
}
@SafeVarargs
public MassiveListDef(E... elements)
{
super(elements);
}
}

View File

@ -0,0 +1,82 @@
package com.massivecraft.massivecore.collections;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* This subclass adds better constructors.
*/
public class MassiveMap<K, V> extends LinkedHashMap<K, V>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: BASE
// -------------------------------------------- //
public MassiveMap(int initialCapacity, float loadFactor)
{
super(initialCapacity, loadFactor);
}
public MassiveMap(int initialCapacity)
{
super(initialCapacity);
}
public MassiveMap()
{
super();
}
@SuppressWarnings("unchecked")
public MassiveMap(Map<? extends K, ? extends V> m)
{
// Support Null
super(m == null ? Collections.EMPTY_MAP : m);
}
public MassiveMap(int initialCapacity, float loadFactor, boolean accessOrder)
{
super(initialCapacity, loadFactor, accessOrder);
}
// -------------------------------------------- //
// CONSTRUCT: EXTRA
// -------------------------------------------- //
public MassiveMap(K key1, V value1, Object... objects)
{
this(varargCreate(key1, value1, objects));
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public static <K, V> MassiveMap<K, V> varargCreate(K key1, V value1, Object... objects)
{
MassiveMap<K, V> ret = new MassiveMap<K, V>();
ret.put(key1, value1);
Iterator<Object> iter = Arrays.asList(objects).iterator();
while (iter.hasNext())
{
K key = (K) iter.next();
V value = (V) iter.next();
ret.put(key, value);
}
return ret;
}
}

View File

@ -0,0 +1,51 @@
package com.massivecraft.massivecore.collections;
import java.util.Map;
/**
* This subclass does nothing new except implementing the Def interface.
* Def is short for "Default" and means GSON should handle "null" as "empty".
*/
public class MassiveMapDef<K, V> extends MassiveMap<K, V> implements Def
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: SUPER
// -------------------------------------------- //
public MassiveMapDef(int initialCapacity, float loadFactor)
{
super(initialCapacity, loadFactor);
}
public MassiveMapDef(int initialCapacity)
{
super(initialCapacity);
}
public MassiveMapDef()
{
super();
}
public MassiveMapDef(Map<? extends K, ? extends V> m)
{
super(m);
}
public MassiveMapDef(int initialCapacity, float loadFactor, boolean accessOrder)
{
super(initialCapacity, loadFactor, accessOrder);
}
public MassiveMapDef(K key1, V value1, Object... objects)
{
super(key1, value1, objects);
}
}

View File

@ -0,0 +1,55 @@
package com.massivecraft.massivecore.collections;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
/**
* This subclass adds better constructors.
*/
public class MassiveSet<E> extends LinkedHashSet<E>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: BASE
// -------------------------------------------- //
public MassiveSet(int initialCapacity, float loadFactor)
{
super(initialCapacity, loadFactor);
}
public MassiveSet(int initialCapacity)
{
super(initialCapacity);
}
public MassiveSet()
{
super();
}
@SuppressWarnings("unchecked")
public MassiveSet(Collection<? extends E> c)
{
// Support Null
super(c == null ? Collections.EMPTY_LIST : c);
}
// -------------------------------------------- //
// CONSTRUCT: EXTRA
// -------------------------------------------- //
@SafeVarargs
public MassiveSet(E... elements)
{
this(Arrays.asList(elements));
}
}

View File

@ -0,0 +1,47 @@
package com.massivecraft.massivecore.collections;
import java.util.Collection;
/**
* This subclass does nothing new except implementing the Def interface.
* Def is short for "Default" and means GSON should handle "null" as "empty".
*/
public class MassiveSetDef<E> extends MassiveSet<E> implements Def
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: SUPER
// -------------------------------------------- //
public MassiveSetDef(int initialCapacity, float loadFactor)
{
super(initialCapacity, loadFactor);
}
public MassiveSetDef(int initialCapacity)
{
super(initialCapacity);
}
public MassiveSetDef()
{
super();
}
public MassiveSetDef(Collection<? extends E> c)
{
super(c);
}
@SafeVarargs
public MassiveSetDef(E... elements)
{
super(elements);
}
}

View File

@ -0,0 +1,45 @@
package com.massivecraft.massivecore.collections;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
/**
* This subclass adds better constructors.
* It also includes the comparator as a Generic for automatic use with GSON.
*/
public class MassiveTreeMap<K, V, C extends Comparator<? super K>> extends TreeMap<K, V>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: BASE
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public MassiveTreeMap(Object comparator)
{
super((comparator instanceof Comparator) ? (C)comparator : null);
}
public MassiveTreeMap(Object comparator, Map<? extends K, ? extends V> map)
{
// Support Null & this(comparator)
this(comparator);
if (map != null) putAll(map);
}
// -------------------------------------------- //
// CONSTRUCT: EXTRA
// -------------------------------------------- //
public MassiveTreeMap(Object comparator, K key1, V value1, Object... objects)
{
this(comparator, MassiveMap.varargCreate(key1, value1, objects));
}
}

View File

@ -0,0 +1,37 @@
package com.massivecraft.massivecore.collections;
import java.util.Comparator;
import java.util.Map;
/**
* This subclass does nothing new except implementing the Def interface.
* Def is short for "Default" and means GSON should handle "null" as "empty".
*/
public class MassiveTreeMapDef<K, V, C extends Comparator<? super K>> extends MassiveTreeMap<K, V, C> implements Def
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: SUPER
// -------------------------------------------- //
public MassiveTreeMapDef(Object comparator)
{
super(comparator);
}
public MassiveTreeMapDef(Object comparator, Map<? extends K, ? extends V> map)
{
super(comparator, map);
}
public MassiveTreeMapDef(Object comparator, K key1, V value1, Object... objects)
{
super(comparator, key1, value1, objects);
}
}

View File

@ -0,0 +1,47 @@
package com.massivecraft.massivecore.collections;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;
/**
* This subclass adds better constructors.
* It also includes the comparator as a Generic for automatic use with GSON.
*/
public class MassiveTreeSet<E, C extends Comparator<? super E>> extends TreeSet<E>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: BASE
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public MassiveTreeSet(Object comparator)
{
super((comparator instanceof Comparator) ? (C)comparator : null);
}
public MassiveTreeSet(Object comparator, Collection<? extends E> c)
{
// Support Null & this(comparator)
this(comparator);
if (c != null) addAll(c);
}
// -------------------------------------------- //
// CONSTRUCT: EXTRA
// -------------------------------------------- //
@SafeVarargs
public MassiveTreeSet(Object comparator, E... elements)
{
this(comparator, Arrays.asList(elements));
}
}

View File

@ -0,0 +1,38 @@
package com.massivecraft.massivecore.collections;
import java.util.Collection;
import java.util.Comparator;
/**
* This subclass does nothing new except implementing the Def interface.
* Def is short for "Default" and means GSON should handle "null" as "empty".
*/
public class MassiveTreeSetDef<E, C extends Comparator<? super E>> extends MassiveTreeSet<E, C> implements Def
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final long serialVersionUID = 1L;
// -------------------------------------------- //
// CONSTRUCT: SUPER
// -------------------------------------------- //
public MassiveTreeSetDef(Object comparator)
{
super(comparator);
}
public MassiveTreeSetDef(Object comparator, Collection<? extends E> c)
{
super(comparator, c);
}
@SafeVarargs
public MassiveTreeSetDef(Object comparator, E... elements)
{
super(comparator, elements);
}
}

View File

@ -55,6 +55,12 @@ public class Money
return mixin.format(amount); return mixin.format(amount);
} }
public static String format(double amount, boolean includeUnit)
{
if (disabled()) return String.valueOf(amount) + (includeUnit ? "$": "");
return mixin.format(amount, includeUnit);
}
public static String singular() public static String singular()
{ {
if (disabled()) return "singular"; if (disabled()) return "singular";
@ -67,6 +73,12 @@ public class Money
return mixin.plural(); return mixin.plural();
} }
public static int fractionalDigits()
{
if (disabled()) return 0;
return mixin.fractionalDigits();
}
// -------------------------------------------- // // -------------------------------------------- //
// EXISTANCE // EXISTANCE
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -15,8 +15,10 @@ public interface MoneyMixin
// -------------------------------------------- // // -------------------------------------------- //
public String format(double amount); public String format(double amount);
public String format(double amount, boolean includeUnit);
public String singular(); public String singular();
public String plural(); public String plural();
public int fractionalDigits();
// -------------------------------------------- // // -------------------------------------------- //
// EXISTANCE // EXISTANCE

View File

@ -6,6 +6,15 @@ import java.util.Collection;
public abstract class MoneyMixinAbstract implements MoneyMixin public abstract class MoneyMixinAbstract implements MoneyMixin
{ {
// -------------------------------------------- //
// FORMAT AND NAME
// -------------------------------------------- //
public String format(double amount)
{
return this.format(amount, true);
}
// -------------------------------------------- // // -------------------------------------------- //
// MOVE // MOVE
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -13,6 +13,7 @@ import com.massivecraft.massivecore.util.MUtil;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
public class MoneyMixinVault extends MoneyMixinAbstract public class MoneyMixinVault extends MoneyMixinAbstract
@ -63,10 +64,29 @@ public class MoneyMixinVault extends MoneyMixinAbstract
// -------------------------------------------- // // -------------------------------------------- //
@Override @Override
public String format(double amount) public String format(double amount, boolean includeUnit)
{
if (includeUnit)
{ {
return this.economy.format(amount); return this.economy.format(amount);
} }
else
{
int fractionalDigits = this.fractionalDigits();
if (fractionalDigits < 0)
{
return String.valueOf(amount);
}
else if (fractionalDigits == 0)
{
return String.valueOf((int)Math.round(amount));
}
else
{
return String.format("%." + fractionalDigits + "f", amount);
}
}
}
@Override @Override
public String singular() public String singular()
@ -80,6 +100,12 @@ public class MoneyMixinVault extends MoneyMixinAbstract
return this.economy.currencyNamePlural(); return this.economy.currencyNamePlural();
} }
@Override
public int fractionalDigits()
{
return this.economy.fractionalDigits();
}
// -------------------------------------------- // // -------------------------------------------- //
// EXISTS AND CREATE // EXISTS AND CREATE
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -13,7 +13,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -49,9 +48,13 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import com.massivecraft.massivecore.CaseInsensitiveComparator;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.MassiveCoreEngineMain; import com.massivecraft.massivecore.MassiveCoreEngineMain;
import com.massivecraft.massivecore.MassiveCoreEngineWorldNameSet; import com.massivecraft.massivecore.MassiveCoreEngineWorldNameSet;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.util.extractor.Extractor; import com.massivecraft.massivecore.util.extractor.Extractor;
import com.massivecraft.massivecore.util.extractor.ExtractorPlayer; import com.massivecraft.massivecore.util.extractor.ExtractorPlayer;
import com.massivecraft.massivecore.util.extractor.ExtractorPlayerName; import com.massivecraft.massivecore.util.extractor.ExtractorPlayerName;
@ -589,34 +592,21 @@ public class MUtil
// SIMPLE CONSTRUCTORS // SIMPLE CONSTRUCTORS
// -------------------------------------------- // // -------------------------------------------- //
@SafeVarargs @SafeVarargs
public static <T> List<T> list(T... items) public static <T> List<T> list(T... items)
{ {
return new ArrayList<T>(Arrays.asList(items)); return new MassiveList<T>(Arrays.asList(items));
} }
@SafeVarargs @SafeVarargs
public static <T> Set<T> set(T... items) public static <T> Set<T> set(T... items)
{ {
return new LinkedHashSet<T>(Arrays.asList(items)); return new MassiveSet<T>(Arrays.asList(items));
} }
@SuppressWarnings("unchecked") public static Set<String> treeset(String... items)
@SafeVarargs
public static <T> Set<T> treeset(T... items)
{ {
Set<T> ret; return new MassiveTreeSet<String, CaseInsensitiveComparator>(CaseInsensitiveComparator.get(), Arrays.asList(items));
if (items[0] instanceof String)
{
ret = (Set<T>) new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
}
else
{
ret = new TreeSet<T>();
}
ret.addAll(Arrays.asList(items));
return ret;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -750,12 +740,29 @@ public class MUtil
public static <T> int compare(Comparable<T> herp, T derp) public static <T> int compare(Comparable<T> herp, T derp)
{ {
if (herp == null && derp == null) return 0; Integer ret = compareNulls(herp, derp);
if (herp == null) return -1; if (ret != null) return ret;
if (derp == null) return +1;
return herp.compareTo(derp); return herp.compareTo(derp);
} }
public static Integer compareNulls(Object one, Object two)
{
if (one == null && two == null) return 0;
if (one == null) return -1;
if (two == null) return +1;
return null;
}
public static Integer compareWithList(Object one, Object two, List<? extends Object> list)
{
int oneIndex = list.indexOf(one);
int twoIndex = list.indexOf(two);
if (oneIndex != -1 && twoIndex != -1) return oneIndex - twoIndex;
if (oneIndex != -1) return -1;
if (twoIndex != -1) return +1;
return null;
}
// -------------------------------------------- // // -------------------------------------------- //
// SORTING // SORTING
// -------------------------------------------- // // -------------------------------------------- //