diff --git a/src/com/massivecraft/mcore/store/DriverMongo.java b/src/com/massivecraft/mcore/store/DriverMongo.java index b30f5860..d502f5bf 100644 --- a/src/com/massivecraft/mcore/store/DriverMongo.java +++ b/src/com/massivecraft/mcore/store/DriverMongo.java @@ -139,7 +139,7 @@ public class DriverMongo extends DriverAbstract Long mtime = ((Number)raw.removeField(MTIME_FIELD)).longValue(); raw.removeField(ID_FIELD); - JsonElement element = MongoGsonConverter.mongo2GsonObject(raw); + JsonElement element = GsonMongoConverter.mongo2GsonObject(raw); return new SimpleEntry(element, mtime); } @@ -149,7 +149,7 @@ public class DriverMongo extends DriverAbstract { DBCollection dbcoll = fixColl(coll); - BasicDBObject dbo = MongoGsonConverter.gson2MongoObject(data); + BasicDBObject dbo = GsonMongoConverter.gson2MongoObject(data); Long mtime = System.currentTimeMillis(); dbo.put(MTIME_FIELD, mtime); dbo.put(ID_FIELD, id); diff --git a/src/com/massivecraft/mcore/store/GsonEqualsChecker.java b/src/com/massivecraft/mcore/store/GsonEqualsChecker.java new file mode 100644 index 00000000..a7316233 --- /dev/null +++ b/src/com/massivecraft/mcore/store/GsonEqualsChecker.java @@ -0,0 +1,177 @@ +package com.massivecraft.mcore.store; + +import java.util.Map.Entry; + +import org.apache.commons.lang.StringUtils; + +import com.massivecraft.mcore.xlib.gson.JsonArray; +import com.massivecraft.mcore.xlib.gson.JsonElement; +import com.massivecraft.mcore.xlib.gson.JsonNull; +import com.massivecraft.mcore.xlib.gson.JsonObject; +import com.massivecraft.mcore.xlib.gson.JsonPrimitive; +import com.massivecraft.mcore.xlib.gson.internal.LazilyParsedNumber; + +public class GsonEqualsChecker +{ + // The argument one must be JsonElement, and can not be null. + // The argument twoObject may be anything, even null. + public static boolean equals(JsonElement one, Object twoObject) + { + // Null check (one can't ever be null) + if (twoObject == null) return false; + + // Object identity speedup + if (one == twoObject) return true; + + // Type-Switch + if (one.isJsonObject()) + { + // JsonObject + return objectEquals((JsonObject)one, twoObject); + } + else if (one.isJsonArray()) + { + // JsonArray + return arrayEquals((JsonArray)one, twoObject); + } + else if (one.isJsonPrimitive()) + { + // JsonPrimitive + return primitiveEquals((JsonPrimitive)one, twoObject); + } + else if (one.isJsonNull()) + { + // JsonNull + return nullEquals((JsonNull)one, twoObject); + } + else + { + // ??? + throw new IllegalArgumentException("Unsupported value type for: " + one); + } + } + + // The argument one must be JsonObject, and can not be null. + // The argument twoObject may be anything, even null. + public static boolean objectEquals(JsonObject one, Object twoObject) + { + // Null check (one can't ever be null) + if (twoObject == null) return false; + + // Object identity speedup + if (one == twoObject) return true; + + // twoObject must be JsonObject + if (!(twoObject instanceof JsonObject)) return false; + + // Cast to JsonObject + JsonObject two = (JsonObject)twoObject; + + // Size must be the same + if (one.entrySet().size() != two.entrySet().size()) return false; + + // And each entry must exist and be the same + for (Entry entry : one.entrySet()) + { + if (!equals(entry.getValue(), two.get(entry.getKey()))) return false; + } + return true; + } + + // The argument one must be JsonArray, and can not be null. + // The argument twoObject may be anything, even null. + public static boolean arrayEquals(JsonArray one, Object twoObject) + { + // Null check (one can't ever be null) + if (twoObject == null) return false; + + // Object identity speedup + if (one == twoObject) return true; + + // twoObject must be JsonArray + if (!(twoObject instanceof JsonArray)) return false; + + // Cast to JsonArray + JsonArray two = (JsonArray)twoObject; + + // Size must be the same + int size = one.size(); + if (two.size() != size) return false; + + // And each element index must be the same + for (int i = 0; i < size ; i++) + { + if (!equals(one.get(i), two.get(i))) return false; + } + return true; + } + + // The argument one must be JsonPrimitive, and can not be null. + // The argument twoObject may be anything, even null. + public static boolean primitiveEquals(JsonPrimitive one, Object twoObject) + { + // Null check (one can't ever be null) + if (twoObject == null) return false; + + // Object identity speedup + if (one == twoObject) return true; + + // if twoObject is JsonObject or JsonArray we are not equal. + if (!(twoObject instanceof JsonPrimitive)) return false; + + // Cast to JsonPrimitive + JsonPrimitive two = (JsonPrimitive)twoObject; + + // Boolean check + if (one.isBoolean()) + { + return one.getAsBoolean() == two.getAsBoolean(); + } + + // Number check + if (one.isNumber()) + { + Number oneNumber = one.getAsNumber(); + Number twoNumber = two.getAsNumber(); + + boolean floating; + if (oneNumber instanceof LazilyParsedNumber) + { + floating = StringUtils.contains(oneNumber.toString(), '.'); + } + else + { + floating = (oneNumber instanceof Double || oneNumber instanceof Float); + } + + if (floating) + { + // Our epsilon is pretty big in order to see float and double as the same. + return Math.abs(oneNumber.doubleValue() - twoNumber.doubleValue()) < 0.0001D; + } + else + { + return oneNumber.longValue() == twoNumber.longValue(); + } + + } + + // String check + if (one.isString()) + { + return one.getAsString().equals(two.getAsString()); + } + + throw new IllegalArgumentException("Unsupported value type for: " + one); + } + + // The argument one must be JsonNull, and can not be null. + // The argument twoObject may be anything, even null. + public static boolean nullEquals(JsonNull one, Object twoObject) + { + // Null check (one can't ever be null) + if (twoObject == null) return false; + + return twoObject == JsonNull.INSTANCE; + } +} diff --git a/src/com/massivecraft/mcore/store/MongoGsonConverter.java b/src/com/massivecraft/mcore/store/GsonMongoConverter.java similarity index 95% rename from src/com/massivecraft/mcore/store/MongoGsonConverter.java rename to src/com/massivecraft/mcore/store/GsonMongoConverter.java index 4fa2a332..b5b399fb 100644 --- a/src/com/massivecraft/mcore/store/MongoGsonConverter.java +++ b/src/com/massivecraft/mcore/store/GsonMongoConverter.java @@ -15,7 +15,7 @@ import com.massivecraft.mcore.xlib.mongodb.BasicDBList; import com.massivecraft.mcore.xlib.mongodb.BasicDBObject; import com.massivecraft.mcore.xlib.mongodb.DBObject; -public final class MongoGsonConverter +public final class GsonMongoConverter { // -------------------------------------------- // // CONSTANTS diff --git a/src/com/massivecraft/mcore/store/MStore.java b/src/com/massivecraft/mcore/store/MStore.java index b5fec907..a8b3882b 100644 --- a/src/com/massivecraft/mcore/store/MStore.java +++ b/src/com/massivecraft/mcore/store/MStore.java @@ -52,7 +52,7 @@ public class MStore if (one == null) return two == null; if (two == null) return one == null; - return one.toString().equals(two.toString()); + return GsonEqualsChecker.equals(one, two); } // -------------------------------------------- //