-
Notifications
You must be signed in to change notification settings - Fork 744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GOBBLIN-2158] upgraded gson version with unit test #4057
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,9 @@ | |
import com.google.gson.reflect.TypeToken; | ||
import com.google.gson.stream.JsonReader; | ||
import com.google.gson.stream.JsonWriter; | ||
import com.google.gson.JsonParseException; | ||
import com.google.gson.ToNumberStrategy; | ||
import com.google.gson.stream.MalformedJsonException; | ||
|
||
|
||
/** | ||
|
@@ -189,7 +192,38 @@ private <S> S readValue(JsonObject jsonObject, TypeToken<S> defaultTypeToken) th | |
} | ||
|
||
public static <T> Gson getGson(Class<T> clazz) { | ||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new GsonInterfaceAdapter(clazz)).create(); | ||
Gson gson = new GsonBuilder() | ||
.setObjectToNumberStrategy(CustomToNumberPolicy.INTEGER_OR_LONG_OR_DOUBLE) | ||
.registerTypeAdapterFactory(new GsonInterfaceAdapter(clazz)) | ||
.create(); | ||
return gson; | ||
} | ||
|
||
public enum CustomToNumberPolicy implements ToNumberStrategy { | ||
INTEGER_OR_LONG_OR_DOUBLE { | ||
@Override | ||
public Number readNumber(JsonReader in) throws IOException { | ||
String value = in.nextString(); | ||
try { | ||
return Integer.parseInt(value); | ||
} catch (NumberFormatException var3) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit : a better way for naming exceptions in this scenario could be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to this |
||
try { | ||
return Long.parseLong(value); | ||
} catch (NumberFormatException var2) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice work on the custom number parsing. But this includes a lot of nesting which could imapact readibility and maintainability , I sugges tbreaking down the nested try-catch blocks in readNumber into smaller methods for each number type (e.g., tryParseInteger, tryParseLong, tryParseDouble). This will improve readability and maintainability by reducing nesting.
` |
||
try { | ||
Double d = Double.valueOf(value); | ||
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) { | ||
throw new MalformedJsonException("JSON forbids NaN and infinities: " + d + "; at path " + in.getPath()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: prefer using String.format to improve readability and performance, as String concatenation using + can create multiple intermediate String objects, which impacts performance/ |
||
} else { | ||
return d; | ||
} | ||
} catch (NumberFormatException var1) { | ||
throw new JsonParseException("Cannot parse " + value + "; at path " + in.getPath(), var1); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ | |
|
||
import com.google.common.base.Optional; | ||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
|
||
import org.apache.gobblin.util.test.BaseClass; | ||
import org.apache.gobblin.util.test.TestClass; | ||
|
@@ -43,4 +44,58 @@ public void test() { | |
|
||
} | ||
|
||
@Test | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test for null/infinites are missing |
||
public void testObjectToIntegerDeserialize() { | ||
Gson gson = new GsonBuilder().create(); | ||
Integer test = 5; | ||
Blazer-007 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
String ser = gson.toJson(test); | ||
Object deser = gson.fromJson(ser, Object.class); | ||
Assert.assertNotEquals(test, deser); | ||
Blazer-007 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Assert.assertTrue(deser instanceof Double); | ||
|
||
Gson customGson = new GsonBuilder() | ||
.setObjectToNumberStrategy(GsonInterfaceAdapter.CustomToNumberPolicy.INTEGER_OR_LONG_OR_DOUBLE) | ||
.create(); | ||
|
||
Object deser2 = customGson.fromJson(ser, Object.class); | ||
Assert.assertEquals(test, deser2); | ||
Assert.assertTrue(deser2 instanceof Integer); | ||
} | ||
|
||
@Test | ||
public void testObjectToLongDeserialize() { | ||
Gson gson = new GsonBuilder().create(); | ||
Long test = 1234567890123456789L; | ||
String ser = gson.toJson(test); | ||
Object deser = gson.fromJson(ser, Object.class); | ||
Assert.assertNotEquals(test, deser); | ||
Assert.assertTrue(deser instanceof Double); | ||
|
||
Gson customGson = new GsonBuilder() | ||
.setObjectToNumberStrategy(GsonInterfaceAdapter.CustomToNumberPolicy.INTEGER_OR_LONG_OR_DOUBLE) | ||
.create(); | ||
|
||
Object deser2 = customGson.fromJson(ser, Object.class); | ||
Assert.assertEquals(test, deser2); | ||
Assert.assertTrue(deser2 instanceof Long); | ||
} | ||
|
||
@Test | ||
public void testObjectToDoubleDeserialize() { | ||
Gson gson = new GsonBuilder().create(); | ||
Double test = 5.0; | ||
String ser = gson.toJson(test); | ||
Object deser = gson.fromJson(ser, Object.class); | ||
Assert.assertEquals(test, deser); | ||
Assert.assertTrue(deser instanceof Double); | ||
|
||
Gson customGson = new GsonBuilder() | ||
.setObjectToNumberStrategy(GsonInterfaceAdapter.CustomToNumberPolicy.INTEGER_OR_LONG_OR_DOUBLE) | ||
.create(); | ||
|
||
Object deser2 = customGson.fromJson(ser, Object.class); | ||
Assert.assertEquals(test, deser2); | ||
Assert.assertTrue(deser2 instanceof Double); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit : minor suggestion on naming :CustomToNumberPolicy sounds a bit generic, can be renamed to something like GsonNumberParsingPolicy to reflect its purpose more clearly
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The library implementation is
public enum ToNumberPolicy implements ToNumberStrategy
Since my code is wrapper on top of this that's the reason for keeping it generic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be something like LongIntNumberPolicy