From 57d1f32de5bf3a7dd54613384cc7e979fba2660b Mon Sep 17 00:00:00 2001 From: Inderjeet Singh Date: Mon, 1 Sep 2008 03:13:32 +0000 Subject: [PATCH] moved gson as a project under trunk --- gson/LICENSE | 13 + gson/README | 7 + gson/docs/javadocs/allclasses-frame.html | 66 ++ gson/docs/javadocs/allclasses-noframe.html | 66 ++ .../com/google/gson/FieldNamingPolicy.html | 356 ++++++++ gson/docs/javadocs/com/google/gson/Gson.html | 610 ++++++++++++++ .../javadocs/com/google/gson/GsonBuilder.html | 528 ++++++++++++ .../com/google/gson/InstanceCreator.html | 275 ++++++ .../javadocs/com/google/gson/JsonArray.html | 680 +++++++++++++++ .../gson/JsonDeserializationContext.html | 235 ++++++ .../com/google/gson/JsonDeserializer.html | 275 ++++++ .../javadocs/com/google/gson/JsonElement.html | 745 +++++++++++++++++ .../javadocs/com/google/gson/JsonNull.html | 245 ++++++ .../javadocs/com/google/gson/JsonObject.html | 462 ++++++++++ .../com/google/gson/JsonParseException.html | 299 +++++++ .../com/google/gson/JsonPrimitive.html | 668 +++++++++++++++ .../google/gson/JsonSerializationContext.html | 246 ++++++ .../com/google/gson/JsonSerializer.html | 272 ++++++ .../com/google/gson/annotations/Expose.html | 206 +++++ .../gson/annotations/SerializedName.html | 253 ++++++ .../com/google/gson/annotations/Since.html | 245 ++++++ .../gson/annotations/class-use/Expose.html | 145 ++++ .../annotations/class-use/SerializedName.html | 145 ++++ .../gson/annotations/class-use/Since.html | 145 ++++ .../gson/annotations/package-frame.html | 37 + .../gson/annotations/package-summary.html | 185 ++++ .../google/gson/annotations/package-tree.html | 155 ++++ .../google/gson/annotations/package-use.html | 145 ++++ .../gson/class-use/FieldNamingPolicy.html | 208 +++++ .../com/google/gson/class-use/Gson.html | 182 ++++ .../google/gson/class-use/GsonBuilder.html | 249 ++++++ .../gson/class-use/InstanceCreator.html | 145 ++++ .../com/google/gson/class-use/JsonArray.html | 206 +++++ .../class-use/JsonDeserializationContext.html | 185 ++++ .../gson/class-use/JsonDeserializer.html | 145 ++++ .../google/gson/class-use/JsonElement.html | 334 ++++++++ .../com/google/gson/class-use/JsonNull.html | 182 ++++ .../com/google/gson/class-use/JsonObject.html | 190 +++++ .../gson/class-use/JsonParseException.html | 267 ++++++ .../google/gson/class-use/JsonPrimitive.html | 190 +++++ .../class-use/JsonSerializationContext.html | 185 ++++ .../google/gson/class-use/JsonSerializer.html | 145 ++++ .../com/google/gson/package-frame.html | 86 ++ .../com/google/gson/package-summary.html | 269 ++++++ .../com/google/gson/package-tree.html | 179 ++++ .../javadocs/com/google/gson/package-use.html | 237 ++++++ .../com/google/gson/reflect/TypeToken.html | 450 ++++++++++ .../gson/reflect/class-use/TypeToken.html | 212 +++++ .../google/gson/reflect/package-frame.html | 33 + .../google/gson/reflect/package-summary.html | 175 ++++ .../com/google/gson/reflect/package-tree.html | 154 ++++ .../com/google/gson/reflect/package-use.html | 171 ++++ gson/docs/javadocs/constant-values.html | 147 ++++ gson/docs/javadocs/deprecated-list.html | 147 ++++ gson/docs/javadocs/help-doc.html | 224 +++++ gson/docs/javadocs/index-all.html | 541 ++++++++++++ gson/docs/javadocs/index-files/index-1.html | 153 ++++ gson/docs/javadocs/index-files/index-10.html | 141 ++++ gson/docs/javadocs/index-files/index-11.html | 162 ++++ gson/docs/javadocs/index-files/index-12.html | 151 ++++ gson/docs/javadocs/index-files/index-13.html | 145 ++++ gson/docs/javadocs/index-files/index-2.html | 145 ++++ gson/docs/javadocs/index-files/index-3.html | 145 ++++ gson/docs/javadocs/index-files/index-4.html | 152 ++++ gson/docs/javadocs/index-files/index-5.html | 144 ++++ gson/docs/javadocs/index-files/index-6.html | 254 ++++++ gson/docs/javadocs/index-files/index-7.html | 144 ++++ gson/docs/javadocs/index-files/index-8.html | 169 ++++ gson/docs/javadocs/index-files/index-9.html | 175 ++++ gson/docs/javadocs/index.html | 40 + gson/docs/javadocs/overview-frame.html | 47 ++ gson/docs/javadocs/overview-summary.html | 166 ++++ gson/docs/javadocs/overview-tree.html | 186 +++++ gson/docs/javadocs/package-list | 3 + gson/docs/javadocs/resources/inherit.gif | Bin 0 -> 57 bytes gson/docs/javadocs/serialized-form.html | 167 ++++ gson/docs/javadocs/stylesheet.css | 29 + gson/lib/gson-cleanup-styles.xml | 51 ++ gson/lib/gson-formatting-styles.xml | 267 ++++++ gson/pom.xml | 213 +++++ .../gson/CamelCaseSeparatorNamingPolicy.java | 71 ++ .../gson/CompositionFieldNamingPolicy.java | 45 + .../com/google/gson/DefaultTypeAdapters.java | 415 +++++++++ .../gson/DelegatingJsonElementVisitor.java | 111 +++ .../gson/DisjunctionExclusionStrategy.java | 67 ++ .../main/java/com/google/gson/Escaper.java | 146 ++++ .../com/google/gson/ExclusionStrategy.java | 46 + ...xposeAnnotationBasedExclusionStrategy.java | 37 + .../com/google/gson/FieldNamingPolicy.java | 64 ++ .../com/google/gson/FieldNamingStrategy.java | 37 + .../com/google/gson/GenericArrayTypeImpl.java | 71 ++ gson/src/main/java/com/google/gson/Gson.java | 404 +++++++++ .../java/com/google/gson/GsonBuilder.java | 357 ++++++++ .../gson/InnerClassExclusionStrategy.java | 39 + .../java/com/google/gson/InstanceCreator.java | 91 ++ .../google/gson/JavaFieldNamingPolicy.java | 50 ++ .../main/java/com/google/gson/JsonArray.java | 291 +++++++ .../gson/JsonArrayDeserializationVisitor.java | 134 +++ .../com/google/gson/JsonCompactFormatter.java | 133 +++ .../gson/JsonDeserializationContext.java | 43 + .../JsonDeserializationContextDefault.java | 93 +++ .../gson/JsonDeserializationVisitor.java | 136 +++ .../com/google/gson/JsonDeserializer.java | 88 ++ .../JsonDeserializerExceptionWrapper.java | 66 ++ .../java/com/google/gson/JsonElement.java | 292 +++++++ .../com/google/gson/JsonElementVisitor.java | 42 + .../com/google/gson/JsonEscapingVisitor.java | 62 ++ .../google/gson/JsonFieldNameValidator.java | 68 ++ .../java/com/google/gson/JsonFormatter.java | 37 + .../main/java/com/google/gson/JsonNull.java | 32 + .../main/java/com/google/gson/JsonObject.java | 156 ++++ .../JsonObjectDeserializationVisitor.java | 150 ++++ .../com/google/gson/JsonParseException.java | 63 ++ .../main/java/com/google/gson/JsonParser.java | 506 +++++++++++ .../com/google/gson/JsonParserConstants.java | 51 ++ .../google/gson/JsonParserTokenManager.java | 789 ++++++++++++++++++ .../java/com/google/gson/JsonPrimitive.java | 282 +++++++ .../JsonPrimitiveDeserializationVisitor.java | 95 +++ .../com/google/gson/JsonPrintFormatter.java | 235 ++++++ .../google/gson/JsonSerializationContext.java | 48 ++ .../gson/JsonSerializationContextDefault.java | 50 ++ .../google/gson/JsonSerializationVisitor.java | 203 +++++ .../java/com/google/gson/JsonSerializer.java | 86 ++ .../gson/JsonSerializerExceptionWrapper.java | 64 ++ .../com/google/gson/JsonTreeNavigator.java | 102 +++ .../LowerCamelCaseSeparatorNamingPolicy.java | 43 + .../google/gson/LowerCaseNamingPolicy.java | 47 ++ .../google/gson/MappedObjectConstructor.java | 109 +++ .../java/com/google/gson/MemoryRefStack.java | 82 ++ .../gson/ModifierBasedExclusionStrategy.java | 60 ++ .../gson/ModifyFirstLetterNamingPolicy.java | 107 +++ .../google/gson/NullExclusionStrategy.java | 38 + .../com/google/gson/ObjectConstructor.java | 47 ++ .../java/com/google/gson/ObjectNavigator.java | 202 +++++ .../google/gson/ObjectNavigatorFactory.java | 79 ++ .../gson/ParameterizedTypeHandlerMap.java | 93 +++ .../google/gson/ParameterizedTypeImpl.java | 92 ++ .../java/com/google/gson/ParseException.java | 193 +++++ .../java/com/google/gson/Preconditions.java | 42 + .../com/google/gson/PrimitiveTypeAdapter.java | 74 ++ .../main/java/com/google/gson/Primitives.java | 114 +++ .../gson/RecursiveFieldNamingPolicy.java | 46 + ...ameAnnotationInterceptingNamingPolicy.java | 53 ++ .../com/google/gson/SimpleCharStream.java | 440 ++++++++++ gson/src/main/java/com/google/gson/Token.java | 82 ++ .../java/com/google/gson/TokenMgrError.java | 134 +++ .../java/com/google/gson/TypeAdapter.java | 35 + .../google/gson/TypeAdapterNotRequired.java | 53 ++ .../main/java/com/google/gson/TypeInfo.java | 84 ++ .../java/com/google/gson/TypeInfoArray.java | 72 ++ .../java/com/google/gson/TypeInfoFactory.java | 124 +++ .../java/com/google/gson/TypeInfoMap.java | 50 ++ .../main/java/com/google/gson/TypeUtils.java | 91 ++ .../google/gson/UpperCaseNamingPolicy.java | 47 ++ .../com/google/gson/VersionConstants.java | 29 + .../google/gson/VersionExclusionStrategy.java | 57 ++ .../com/google/gson/annotations/Expose.java | 61 ++ .../gson/annotations/SerializedName.java | 73 ++ .../com/google/gson/annotations/Since.java | 60 ++ .../google/gson/annotations/package-info.java | 6 + .../java/com/google/gson/package-info.java | 11 + .../com/google/gson/reflect/TypeToken.java | 375 +++++++++ .../com/google/gson/reflect/package-info.java | 6 + gson/src/main/javacc/JsonParser.jj | 259 ++++++ .../main/resources/assembly-descriptor.xml | 21 + .../CamelCaseSeparatorNamingPolicyTest.java | 79 ++ .../gson/DefaultDateTypeAdapterTest.java | 60 ++ .../gson/DefaultMapJsonSerializerTest.java | 61 ++ .../DisjunctionExclusionStrategyTest.java | 80 ++ .../java/com/google/gson/EscaperTest.java | 141 ++++ ...eAnnotationBasedExclusionStrategyTest.java | 58 ++ ...unctionalWithInternalDependenciesTest.java | 135 +++ .../google/gson/GenericArrayTypeImplTest.java | 58 ++ .../java/com/google/gson/GsonBuilderTest.java | 33 + .../com/google/gson/GsonTypeAdapterTest.java | 108 +++ .../gson/JavaFieldNamingPolicyTest.java | 49 ++ .../JsonDeserializerExceptionWrapperTest.java | 90 ++ .../google/gson/JsonEscapingVisitorTest.java | 180 ++++ .../gson/JsonFieldNameValidatorTest.java | 97 +++ .../JsonSerializerExceptionWrapperTest.java | 86 ++ ...werCamelCaseSeparatorNamingPolicyTest.java | 53 ++ .../gson/LowerCaseNamingPolicyTest.java | 52 ++ .../com/google/gson/MemoryRefStackTest.java | 86 ++ .../google/gson/MockExclusionStrategy.java | 45 + .../ModifyFirstLetterNamingPolicyTest.java | 87 ++ .../gson/NullExclusionStrategyTest.java | 44 + .../gson/ParameterizedTypeHandlerMapTest.java | 87 ++ .../gson/ParameterizedTypeImplTest.java | 57 ++ .../google/gson/ParamterizedTypeFixtures.java | 161 ++++ .../google/gson/PrimitiveTypeAdapterTest.java | 74 ++ ...nnotationInterceptingNamingPolicyTest.java | 60 ++ .../com/google/gson/TypeInfoArrayTest.java | 123 +++ .../com/google/gson/TypeInfoFactoryTest.java | 252 ++++++ .../java/com/google/gson/TypeInfoMapTest.java | 66 ++ .../java/com/google/gson/TypeInfoTest.java | 114 +++ .../java/com/google/gson/TypeUtilsTest.java | 57 ++ .../gson/UpperCaseNamingPolicyTest.java | 53 ++ .../gson/VersionExclusionStrategyTest.java | 72 ++ .../com/google/gson/common/MoreAsserts.java | 64 ++ .../com/google/gson/common/TestTypes.java | 352 ++++++++ .../com/google/gson/functional/ArrayTest.java | 136 +++ .../gson/functional/CollectionTest.java | 205 +++++ .../functional/CustomTypeAdaptersTest.java | 106 +++ .../functional/DefaultTypeAdaptersTest.java | 230 +++++ .../google/gson/functional/EscapingTest.java | 50 ++ .../gson/functional/ExposeFieldsTest.java | 134 +++ .../functional/InternationalizationTest.java | 73 ++ .../gson/functional/NamingPolicyTest.java | 72 ++ .../functional/NullObjectAndFieldTest.java | 94 +++ .../google/gson/functional/ObjectTest.java | 517 ++++++++++++ .../functional/ParameterizedTypesTest.java | 446 ++++++++++ .../google/gson/functional/PrimitiveTest.java | 313 +++++++ .../gson/functional/PrintFormattingTest.java | 56 ++ .../gson/functional/ReadersWritersTest.java | 83 ++ .../gson/functional/UncategorizedTest.java | 114 +++ .../gson/functional/VersioningTest.java | 109 +++ 216 files changed, 32947 insertions(+) create mode 100644 gson/LICENSE create mode 100644 gson/README create mode 100644 gson/docs/javadocs/allclasses-frame.html create mode 100644 gson/docs/javadocs/allclasses-noframe.html create mode 100644 gson/docs/javadocs/com/google/gson/FieldNamingPolicy.html create mode 100644 gson/docs/javadocs/com/google/gson/Gson.html create mode 100644 gson/docs/javadocs/com/google/gson/GsonBuilder.html create mode 100644 gson/docs/javadocs/com/google/gson/InstanceCreator.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonArray.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonDeserializationContext.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonDeserializer.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonElement.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonNull.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonObject.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonParseException.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonPrimitive.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonSerializationContext.html create mode 100644 gson/docs/javadocs/com/google/gson/JsonSerializer.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/Expose.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/SerializedName.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/Since.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/class-use/Expose.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/class-use/SerializedName.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/class-use/Since.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/package-frame.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/package-summary.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/package-tree.html create mode 100644 gson/docs/javadocs/com/google/gson/annotations/package-use.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/FieldNamingPolicy.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/Gson.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/GsonBuilder.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/InstanceCreator.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonArray.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonDeserializationContext.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonDeserializer.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonElement.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonNull.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonObject.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonParseException.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonPrimitive.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonSerializationContext.html create mode 100644 gson/docs/javadocs/com/google/gson/class-use/JsonSerializer.html create mode 100644 gson/docs/javadocs/com/google/gson/package-frame.html create mode 100644 gson/docs/javadocs/com/google/gson/package-summary.html create mode 100644 gson/docs/javadocs/com/google/gson/package-tree.html create mode 100644 gson/docs/javadocs/com/google/gson/package-use.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/TypeToken.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/class-use/TypeToken.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/package-frame.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/package-summary.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/package-tree.html create mode 100644 gson/docs/javadocs/com/google/gson/reflect/package-use.html create mode 100644 gson/docs/javadocs/constant-values.html create mode 100644 gson/docs/javadocs/deprecated-list.html create mode 100644 gson/docs/javadocs/help-doc.html create mode 100644 gson/docs/javadocs/index-all.html create mode 100644 gson/docs/javadocs/index-files/index-1.html create mode 100644 gson/docs/javadocs/index-files/index-10.html create mode 100644 gson/docs/javadocs/index-files/index-11.html create mode 100644 gson/docs/javadocs/index-files/index-12.html create mode 100644 gson/docs/javadocs/index-files/index-13.html create mode 100644 gson/docs/javadocs/index-files/index-2.html create mode 100644 gson/docs/javadocs/index-files/index-3.html create mode 100644 gson/docs/javadocs/index-files/index-4.html create mode 100644 gson/docs/javadocs/index-files/index-5.html create mode 100644 gson/docs/javadocs/index-files/index-6.html create mode 100644 gson/docs/javadocs/index-files/index-7.html create mode 100644 gson/docs/javadocs/index-files/index-8.html create mode 100644 gson/docs/javadocs/index-files/index-9.html create mode 100644 gson/docs/javadocs/index.html create mode 100644 gson/docs/javadocs/overview-frame.html create mode 100644 gson/docs/javadocs/overview-summary.html create mode 100644 gson/docs/javadocs/overview-tree.html create mode 100644 gson/docs/javadocs/package-list create mode 100644 gson/docs/javadocs/resources/inherit.gif create mode 100644 gson/docs/javadocs/serialized-form.html create mode 100644 gson/docs/javadocs/stylesheet.css create mode 100644 gson/lib/gson-cleanup-styles.xml create mode 100644 gson/lib/gson-formatting-styles.xml create mode 100644 gson/pom.xml create mode 100644 gson/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/DefaultTypeAdapters.java create mode 100644 gson/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java create mode 100644 gson/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/Escaper.java create mode 100644 gson/src/main/java/com/google/gson/ExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/FieldNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/FieldNamingStrategy.java create mode 100644 gson/src/main/java/com/google/gson/GenericArrayTypeImpl.java create mode 100644 gson/src/main/java/com/google/gson/Gson.java create mode 100644 gson/src/main/java/com/google/gson/GsonBuilder.java create mode 100644 gson/src/main/java/com/google/gson/InnerClassExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/InstanceCreator.java create mode 100644 gson/src/main/java/com/google/gson/JavaFieldNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/JsonArray.java create mode 100644 gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonCompactFormatter.java create mode 100644 gson/src/main/java/com/google/gson/JsonDeserializationContext.java create mode 100644 gson/src/main/java/com/google/gson/JsonDeserializationContextDefault.java create mode 100644 gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonDeserializer.java create mode 100644 gson/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java create mode 100644 gson/src/main/java/com/google/gson/JsonElement.java create mode 100644 gson/src/main/java/com/google/gson/JsonElementVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonEscapingVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonFieldNameValidator.java create mode 100644 gson/src/main/java/com/google/gson/JsonFormatter.java create mode 100755 gson/src/main/java/com/google/gson/JsonNull.java create mode 100644 gson/src/main/java/com/google/gson/JsonObject.java create mode 100644 gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonParseException.java create mode 100755 gson/src/main/java/com/google/gson/JsonParser.java create mode 100755 gson/src/main/java/com/google/gson/JsonParserConstants.java create mode 100755 gson/src/main/java/com/google/gson/JsonParserTokenManager.java create mode 100644 gson/src/main/java/com/google/gson/JsonPrimitive.java create mode 100644 gson/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonPrintFormatter.java create mode 100644 gson/src/main/java/com/google/gson/JsonSerializationContext.java create mode 100644 gson/src/main/java/com/google/gson/JsonSerializationContextDefault.java create mode 100644 gson/src/main/java/com/google/gson/JsonSerializationVisitor.java create mode 100644 gson/src/main/java/com/google/gson/JsonSerializer.java create mode 100644 gson/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java create mode 100644 gson/src/main/java/com/google/gson/JsonTreeNavigator.java create mode 100644 gson/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/LowerCaseNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/MappedObjectConstructor.java create mode 100644 gson/src/main/java/com/google/gson/MemoryRefStack.java create mode 100644 gson/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/NullExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/ObjectConstructor.java create mode 100644 gson/src/main/java/com/google/gson/ObjectNavigator.java create mode 100644 gson/src/main/java/com/google/gson/ObjectNavigatorFactory.java create mode 100644 gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java create mode 100644 gson/src/main/java/com/google/gson/ParameterizedTypeImpl.java create mode 100755 gson/src/main/java/com/google/gson/ParseException.java create mode 100644 gson/src/main/java/com/google/gson/Preconditions.java create mode 100644 gson/src/main/java/com/google/gson/PrimitiveTypeAdapter.java create mode 100644 gson/src/main/java/com/google/gson/Primitives.java create mode 100644 gson/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java create mode 100755 gson/src/main/java/com/google/gson/SimpleCharStream.java create mode 100755 gson/src/main/java/com/google/gson/Token.java create mode 100755 gson/src/main/java/com/google/gson/TokenMgrError.java create mode 100644 gson/src/main/java/com/google/gson/TypeAdapter.java create mode 100644 gson/src/main/java/com/google/gson/TypeAdapterNotRequired.java create mode 100644 gson/src/main/java/com/google/gson/TypeInfo.java create mode 100644 gson/src/main/java/com/google/gson/TypeInfoArray.java create mode 100644 gson/src/main/java/com/google/gson/TypeInfoFactory.java create mode 100644 gson/src/main/java/com/google/gson/TypeInfoMap.java create mode 100644 gson/src/main/java/com/google/gson/TypeUtils.java create mode 100644 gson/src/main/java/com/google/gson/UpperCaseNamingPolicy.java create mode 100644 gson/src/main/java/com/google/gson/VersionConstants.java create mode 100644 gson/src/main/java/com/google/gson/VersionExclusionStrategy.java create mode 100644 gson/src/main/java/com/google/gson/annotations/Expose.java create mode 100644 gson/src/main/java/com/google/gson/annotations/SerializedName.java create mode 100644 gson/src/main/java/com/google/gson/annotations/Since.java create mode 100644 gson/src/main/java/com/google/gson/annotations/package-info.java create mode 100644 gson/src/main/java/com/google/gson/package-info.java create mode 100644 gson/src/main/java/com/google/gson/reflect/TypeToken.java create mode 100644 gson/src/main/java/com/google/gson/reflect/package-info.java create mode 100755 gson/src/main/javacc/JsonParser.jj create mode 100644 gson/src/main/resources/assembly-descriptor.xml create mode 100644 gson/src/test/java/com/google/gson/CamelCaseSeparatorNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java create mode 100644 gson/src/test/java/com/google/gson/DefaultMapJsonSerializerTest.java create mode 100644 gson/src/test/java/com/google/gson/DisjunctionExclusionStrategyTest.java create mode 100644 gson/src/test/java/com/google/gson/EscaperTest.java create mode 100644 gson/src/test/java/com/google/gson/ExposeAnnotationBasedExclusionStrategyTest.java create mode 100644 gson/src/test/java/com/google/gson/FunctionalWithInternalDependenciesTest.java create mode 100644 gson/src/test/java/com/google/gson/GenericArrayTypeImplTest.java create mode 100755 gson/src/test/java/com/google/gson/GsonBuilderTest.java create mode 100644 gson/src/test/java/com/google/gson/GsonTypeAdapterTest.java create mode 100644 gson/src/test/java/com/google/gson/JavaFieldNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/JsonDeserializerExceptionWrapperTest.java create mode 100644 gson/src/test/java/com/google/gson/JsonEscapingVisitorTest.java create mode 100644 gson/src/test/java/com/google/gson/JsonFieldNameValidatorTest.java create mode 100644 gson/src/test/java/com/google/gson/JsonSerializerExceptionWrapperTest.java create mode 100644 gson/src/test/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/LowerCaseNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/MemoryRefStackTest.java create mode 100644 gson/src/test/java/com/google/gson/MockExclusionStrategy.java create mode 100644 gson/src/test/java/com/google/gson/ModifyFirstLetterNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/NullExclusionStrategyTest.java create mode 100644 gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java create mode 100644 gson/src/test/java/com/google/gson/ParameterizedTypeImplTest.java create mode 100644 gson/src/test/java/com/google/gson/ParamterizedTypeFixtures.java create mode 100644 gson/src/test/java/com/google/gson/PrimitiveTypeAdapterTest.java create mode 100644 gson/src/test/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/TypeInfoArrayTest.java create mode 100644 gson/src/test/java/com/google/gson/TypeInfoFactoryTest.java create mode 100644 gson/src/test/java/com/google/gson/TypeInfoMapTest.java create mode 100644 gson/src/test/java/com/google/gson/TypeInfoTest.java create mode 100644 gson/src/test/java/com/google/gson/TypeUtilsTest.java create mode 100644 gson/src/test/java/com/google/gson/UpperCaseNamingPolicyTest.java create mode 100644 gson/src/test/java/com/google/gson/VersionExclusionStrategyTest.java create mode 100644 gson/src/test/java/com/google/gson/common/MoreAsserts.java create mode 100644 gson/src/test/java/com/google/gson/common/TestTypes.java create mode 100644 gson/src/test/java/com/google/gson/functional/ArrayTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/CollectionTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/CustomTypeAdaptersTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/EscapingTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/ExposeFieldsTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/InternationalizationTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/NamingPolicyTest.java create mode 100755 gson/src/test/java/com/google/gson/functional/NullObjectAndFieldTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/ObjectTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/ParameterizedTypesTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/PrimitiveTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/PrintFormattingTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/ReadersWritersTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/UncategorizedTest.java create mode 100644 gson/src/test/java/com/google/gson/functional/VersioningTest.java diff --git a/gson/LICENSE b/gson/LICENSE new file mode 100644 index 00000000..291ee362 --- /dev/null +++ b/gson/LICENSE @@ -0,0 +1,13 @@ +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. diff --git a/gson/README b/gson/README new file mode 100644 index 00000000..a0562cc7 --- /dev/null +++ b/gson/README @@ -0,0 +1,7 @@ +Gson is a Java library that can be used to convert a Java object into its +JSON representation. It can also be used to convert a JSON string into an +equivalent Java object. Gson can work with arbitrary Java objects including +pre-existing objects that you do not have source-code of. + +Complete Gson documentation is available at its project page +http://code.google.com/p/google-gson diff --git a/gson/docs/javadocs/allclasses-frame.html b/gson/docs/javadocs/allclasses-frame.html new file mode 100644 index 00000000..c80566a3 --- /dev/null +++ b/gson/docs/javadocs/allclasses-frame.html @@ -0,0 +1,66 @@ + + + + + + + +All Classes (Gson 1.2 API) + + + + + + + + + + + +All Classes +
+ + + + + +
Expose +
+FieldNamingPolicy +
+Gson +
+GsonBuilder +
+InstanceCreator +
+JsonArray +
+JsonDeserializationContext +
+JsonDeserializer +
+JsonElement +
+JsonNull +
+JsonObject +
+JsonParseException +
+JsonPrimitive +
+JsonSerializationContext +
+JsonSerializer +
+SerializedName +
+Since +
+TypeToken +
+
+ + + diff --git a/gson/docs/javadocs/allclasses-noframe.html b/gson/docs/javadocs/allclasses-noframe.html new file mode 100644 index 00000000..babc673c --- /dev/null +++ b/gson/docs/javadocs/allclasses-noframe.html @@ -0,0 +1,66 @@ + + + + + + + +All Classes (Gson 1.2 API) + + + + + + + + + + + +All Classes +
+ + + + + +
Expose +
+FieldNamingPolicy +
+Gson +
+GsonBuilder +
+InstanceCreator +
+JsonArray +
+JsonDeserializationContext +
+JsonDeserializer +
+JsonElement +
+JsonNull +
+JsonObject +
+JsonParseException +
+JsonPrimitive +
+JsonSerializationContext +
+JsonSerializer +
+SerializedName +
+Since +
+TypeToken +
+
+ + + diff --git a/gson/docs/javadocs/com/google/gson/FieldNamingPolicy.html b/gson/docs/javadocs/com/google/gson/FieldNamingPolicy.html new file mode 100644 index 00000000..d338b13e --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/FieldNamingPolicy.html @@ -0,0 +1,356 @@ + + + + + + + +FieldNamingPolicy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Enum FieldNamingPolicy

+
+java.lang.Object
+  extended by java.lang.Enum<FieldNamingPolicy>
+      extended by com.google.gson.FieldNamingPolicy
+
+
+
All Implemented Interfaces:
Serializable, Comparable<FieldNamingPolicy>
+
+
+
+
public enum FieldNamingPolicy
extends Enum<FieldNamingPolicy>
+ + +

+An enumeration that defines a few standard naming conventions for JSON field names. + This enumeration should be used in conjunction with GsonBuilder + to configure a Gson instance to properly translate Java field + names into the desired JSON field names. +

+ +

+

+
Author:
+
Joel Leitch
+
+
+ +

+ + + + + + + + + + + + + +
+Enum Constant Summary
LOWER_CASE_WITH_UNDERSCORES + +
+          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 (_).
UPPER_CAMEL_CASE + +
+          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.
+  + + + + + + + + + + + + + + + +
+Method Summary
+static FieldNamingPolicyvalueOf(String name) + +
+          Returns the enum constant of this type with the specified name.
+static FieldNamingPolicy[]values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+ + + + + + + +
Methods inherited from class java.lang.Enum
compareTo, equals, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Enum Constant Detail
+ +

+UPPER_CAMEL_CASE

+
+public static final FieldNamingPolicy UPPER_CAMEL_CASE
+
+
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. + +

Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":

+
    +
  • someFieldName ---> SomeFieldName
  • +
  • _someFieldName ---> _SomeFieldName
  • +
+

+

+
+
+
+ +

+LOWER_CASE_WITH_UNDERSCORES

+
+public static final FieldNamingPolicy LOWER_CASE_WITH_UNDERSCORES
+
+
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 (_). + +

Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":

+
    +
  • someFieldName ---> some_field_name
  • +
  • _someFieldName ---> _some_field_name
  • +
  • aStringField ---> a_string_field
  • +
  • aURL ---> a_u_r_l
  • +
+

+

+
+
+ + + + + + + + +
+Method Detail
+ +

+values

+
+public static FieldNamingPolicy[] values()
+
+
Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
+for (FieldNamingPolicy c : FieldNamingPolicy.values())
+    System.out.println(c);
+
+

+

+ +
Returns:
an array containing the constants of this enum type, in +the order they are declared
+
+
+
+ +

+valueOf

+
+public static FieldNamingPolicy valueOf(String name)
+
+
Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.) +

+

+
Parameters:
name - the name of the enum constant to be returned. +
Returns:
the enum constant with the specified name +
Throws: +
IllegalArgumentException - if this enum type has no constant +with the specified name +
NullPointerException - if the argument is null
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/Gson.html b/gson/docs/javadocs/com/google/gson/Gson.html new file mode 100644 index 00000000..f72a77a1 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/Gson.html @@ -0,0 +1,610 @@ + + + + + + + +Gson (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class Gson

+
+java.lang.Object
+  extended by com.google.gson.Gson
+
+
+
+
public final class Gson
extends Object
+ + +

+This is the main class for using Gson. Gson is typically used by first constructing a + Gson instance and then invoking toJson(Object) or fromJson(String, Class) + methods on it. + +

You can create a Gson instance by invoking new Gson() if the default configuration + is all you need. You can also use GsonBuilder to build a Gson instance with various + configuration options such as versioning support, pretty printing, custom + JsonSerializers, JsonDeserializers, and InstanceCreators.

+ +

Here is an example of how Gson is used for a simple Class: + +

+ 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
+ 

+ +

If the object that your are serializing/deserializing is a ParameterizedType + (i.e. contains at least one type parameter and may be an array) then you must use the + toJson(Object, Type) or fromJson(String, Type) method. Here is an + example for serializing and deserialing a ParameterizedType: + +

+ Type listType = new TypeToken>() {}.getType();
+ List target = new LinkedList();
+ target.add("blah");
+
+ Gson gson = new Gson();
+ String json = gson.toJson(target, listType);
+ List target2 = gson.fromJson(json, listType);
+ 

+ +

See the Gson User Guide + for a more complete set of examples.

+

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
See Also:
TypeToken
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
Gson() + +
+          Constructs a Gson object with default configuration.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ + + + + +
+<T> T
+
fromJson(Reader json, + Class<T> classOfT) + +
+          This method deserializes the Json read from the specified reader into an object of the + specified class.
+ + + + + +
+<T> T
+
fromJson(Reader json, + Type typeOfT) + +
+          This method deserializes the Json read from the specified reader into an object of the + specified type.
+ + + + + +
+<T> T
+
fromJson(String json, + Class<T> classOfT) + +
+          This method deserializes the specified Json into an object of the specified class.
+ + + + + +
+<T> T
+
fromJson(String json, + Type typeOfT) + +
+          This method deserializes the specified Json into an object of the specified type.
+ StringtoJson(Object src) + +
+          This method serializes the specified object into its equivalent Json representation.
+ StringtoJson(Object src, + Type typeOfSrc) + +
+          This method serializes the specified object, including those of generic types, into its + equivalent Json representation.
+ voidtoJson(Object src, + Type typeOfSrc, + Writer writer) + +
+          This method serializes the specified object, including those of generic types, into its + equivalent Json representation.
+ voidtoJson(Object src, + Writer writer) + +
+          This method serializes the specified object into its equivalent Json representation.
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+Gson

+
+public Gson()
+
+
Constructs a Gson object with default configuration. The default configuration has the + following settings: + +

+

+ + + + + + + + +
+Method Detail
+ +

+toJson

+
+public String toJson(Object src)
+
+
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 + Object.getClass() to get the type for the specified object, but the + 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 + toJson(Object, Type) instead. If you want to write out the object to a + Writer, use toJson(Object, Writer) instead. +

+

+
Parameters:
src - the object for which Json representation is to be created setting for Gson +
Returns:
Json representation of src.
+
+
+
+ +

+toJson

+
+public String toJson(Object src,
+                     Type typeOfSrc)
+
+
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 toJson(Object) instead. If you want to write out + the object to a Writer, use toJson(Object, Type, Writer) instead. +

+

+
Parameters:
src - the object for which JSON representation is to be created
typeOfSrc - The specific genericized type of src. You can obtain + this type by using the TypeToken class. For example, + to get the type for Collection<Foo>, you should use: +
+ Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
+ 
+
Returns:
Json representation of src
+
+
+
+ +

+toJson

+
+public void toJson(Object src,
+                   Writer writer)
+
+
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 + Object.getClass() to get the type for the specified object, but the + 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 + toJson(Object, Type, Writer) instead. +

+

+
Parameters:
src - the object for which Json representation is to be created setting for Gson
writer - Writer to which the Json representation needs to be written
Since:
+
1.2
+
+
+
+
+ +

+toJson

+
+public void toJson(Object src,
+                   Type typeOfSrc,
+                   Writer 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 toJson(Object, Writer) instead. +

+

+
Parameters:
src - the object for which JSON representation is to be created
typeOfSrc - The specific genericized type of src. You can obtain + this type by using the TypeToken class. For example, + to get the type for Collection<Foo>, you should use: +
+ Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
+ 
writer - Writer to which the Json representation of src needs to be written.
Since:
+
1.2
+
+
+
+
+ +

+fromJson

+
+public <T> T fromJson(String json,
+                      Class<T> classOfT)
+           throws JsonParseException
+
+
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 + fromJson(String, Type). If you have the Json in a Reader instead of + a String, use fromJson(Reader, Class) instead. +

+

+
Type Parameters:
T - the type of the desired object
Parameters:
json - the string from which the object is to be deserialized
classOfT - the class of T +
Returns:
an object of type T from the string +
Throws: +
JsonParseException - if json is not a valid representation for an object of type + classOfT
+
+
+
+ +

+fromJson

+
+public <T> T fromJson(String json,
+                      Type typeOfT)
+           throws JsonParseException
+
+
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 + fromJson(String, Class) instead. If you have the Json in a Reader instead of + a String, use fromJson(Reader, Type) instead. +

+

+
Type Parameters:
T - the type of the desired object
Parameters:
json - the string from which the object is to be deserialized
typeOfT - The specific genericized type of src. You can obtain this type by using the + TypeToken class. For example, to get the type for + Collection<Foo>, you should use: +
+ Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
+ 
+
Returns:
an object of type T from the string +
Throws: +
JsonParseException - if json is not a valid representation for an object of type typeOfT
+
+
+
+ +

+fromJson

+
+public <T> T fromJson(Reader json,
+                      Class<T> classOfT)
+           throws JsonParseException
+
+
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 fromJson(Reader, Type). If you have the Json in a String form instead of a + Reader, use fromJson(String, Class) instead. +

+

+
Type Parameters:
T - the type of the desired object
Parameters:
json - the reader producing the Json from which the object is to be deserialized.
classOfT - the class of T +
Returns:
an object of type T from the string +
Throws: +
JsonParseException - if json is not a valid representation for an object of type + classOfT
Since:
+
1.2
+
+
+
+
+ +

+fromJson

+
+public <T> T fromJson(Reader json,
+                      Type typeOfT)
+           throws JsonParseException
+
+
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 fromJson(Reader, Class) instead. If you have the Json in a + String form instead of a Reader, use fromJson(String, Type) instead. +

+

+
Type Parameters:
T - the type of the desired object
Parameters:
json - the reader producing Json from which the object is to be deserialized
typeOfT - The specific genericized type of src. You can obtain this type by using the + TypeToken class. For example, to get the type for + Collection<Foo>, you should use: +
+ Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
+ 
+
Returns:
an object of type T from the json +
Throws: +
JsonParseException - if json is not a valid representation for an object of type typeOfT
Since:
+
1.2
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/GsonBuilder.html b/gson/docs/javadocs/com/google/gson/GsonBuilder.html new file mode 100644 index 00000000..1547fb7d --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/GsonBuilder.html @@ -0,0 +1,528 @@ + + + + + + + +GsonBuilder (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class GsonBuilder

+
+java.lang.Object
+  extended by com.google.gson.GsonBuilder
+
+
+
+
public final class GsonBuilder
extends Object
+ + +

+

Use this builder to construct a Gson instance when you need to set configuration + options other than the default. For Gson with default configuration, it is simpler to + use new Gson(). GsonBuilder is best used by creating it, and then invoking its + various configuration methods, and finally calling create.

+ +

The following is an example shows how to use the GsonBuilder to construct a Gson + instance: + +

+ Gson gson = new GsonBuilder()
+     .registerTypeAdapter(Id.class, new IdTypeAdapter())
+     .serializeNulls()
+     .setDateFormat(DateFormat.LONG)
+     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
+     .setPrettyPrinting()
+     .setVersion(1.0)
+     .create();
+ 

+ +

NOTE: the order of invocation of configuration methods does not matter.

+

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
GsonBuilder() + +
+          Creates a GsonBuilder instance that can be used to build Gson with various configuration + settings.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ Gsoncreate() + +
+          Creates a Gson instance based on the current configuration.
+ GsonBuilderexcludeFieldsWithModifiers(int... modifiers) + +
+          Configures Gson to excludes all class fields that have the specified modifiers.
+ GsonBuilderexcludeFieldsWithoutExposeAnnotation() + +
+          Configures Gson to exclude all fields from consideration for serialization or deserialization + that do not have the Expose annotation.
+ GsonBuilderregisterTypeAdapter(Type type, + Object typeAdapter) + +
+          Configures Gson for custom serialization or deserialization.
+ GsonBuilderserializeNulls() + +
+          Configure Gson to serialize null fields.
+ GsonBuildersetDateFormat(int style) + +
+          Configures Gson to to serialize Date objects according to the style value provided.
+ GsonBuildersetDateFormat(String pattern) + +
+          Configures Gson to serialize Date objects according to the pattern provided.
+ GsonBuildersetFieldNamingPolicy(FieldNamingPolicy namingConvention) + +
+          Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization.
+ GsonBuildersetPrettyPrinting() + +
+          Configures Gson to output Json that fits in a page for pretty printing.
+ GsonBuildersetVersion(double ignoreVersionsAfter) + +
+          Configures Gson to enable versioning support.
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+GsonBuilder

+
+public GsonBuilder()
+
+
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 + create(). +

+

+ + + + + + + + +
+Method Detail
+ +

+setVersion

+
+public GsonBuilder setVersion(double ignoreVersionsAfter)
+
+
Configures Gson to enable versioning support. +

+

+
Parameters:
ignoreVersionsAfter - any field or type marked with a version higher than this value + are ignored during serialization or deserialization. +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+excludeFieldsWithModifiers

+
+public GsonBuilder excludeFieldsWithModifiers(int... modifiers)
+
+
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. +

+

+
Parameters:
modifiers - the field modifiers. You must use the modifiers specified in the + Modifier class. For example, + Modifier.TRANSIENT, + Modifier.STATIC. +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+excludeFieldsWithoutExposeAnnotation

+
+public GsonBuilder excludeFieldsWithoutExposeAnnotation()
+
+
Configures Gson to exclude all fields from consideration for serialization or deserialization + that do not have the Expose annotation. +

+

+ +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+serializeNulls

+
+public GsonBuilder serializeNulls()
+
+
Configure Gson to serialize null fields. By default, Gson omits all fields that are null + during serialization. +

+

+ +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
Since:
+
1.2
+
+
+
+
+ +

+setFieldNamingPolicy

+
+public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention)
+
+
Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization. +

+

+
Parameters:
namingConvention - the JSON field naming convention to use for serialization and + deserialization. +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+setPrettyPrinting

+
+public GsonBuilder setPrettyPrinting()
+
+
Configures Gson to output Json that fits in a page for pretty printing. This option only + affects Json serialization. +

+

+ +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+setDateFormat

+
+public GsonBuilder setDateFormat(String pattern)
+
+
Configures Gson to serialize Date objects according to the pattern provided. You can + call this method or setDateFormat(int) multiple times, but only the last invocation + will be used to decide the serialization format. + +

Note that this pattern must abide by the convention provided by SimpleDateFormat + class. See the documentation in SimpleDateFormat for more information on + valid date and time patterns.

+

+

+
Parameters:
pattern - the pattern that dates will be serialized/deserialized to/from +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
Since:
+
1.2
+
+
+
+
+ +

+setDateFormat

+
+public GsonBuilder setDateFormat(int style)
+
+
Configures Gson to to serialize Date objects according to the style value provided. + You can call this method or setDateFormat(String) multiple times, but only the last + invocation will be used to decide the serialization format. + +

Note that this style value should be one of the predefined constants in the + DateFormat class. See the documentation in DateFormat for more + information on the valid style constants.

+

+

+
Parameters:
style - the predefined date style that date objects will be serialized/deserialized + to/from +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
Since:
+
1.2
+
+
+
+
+ +

+registerTypeAdapter

+
+public GsonBuilder registerTypeAdapter(Type type,
+                                       Object typeAdapter)
+
+
Configures Gson for custom serialization or deserialization. This method combines the + registration of an InstanceCreator, JsonSerializer, and a + JsonDeserializer. It is best used when a single object 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, it is + overwritten. +

+

+
Parameters:
type - the type definition for the type adapter being registered
typeAdapter - This object must implement at least one of the InstanceCreator, + JsonSerializer, and a JsonDeserializer interfaces. +
Returns:
a reference to this GsonBuilder object to fulfill the "Builder" pattern
+
+
+
+ +

+create

+
+public Gson create()
+
+
Creates a Gson instance based on the current configuration. This method is free of + side-effects to this GsonBuilder instance and hence can be called multiple times. +

+

+ +
Returns:
an instance of Gson configured with the options currently set in this builder
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/InstanceCreator.html b/gson/docs/javadocs/com/google/gson/InstanceCreator.html new file mode 100644 index 00000000..93887069 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/InstanceCreator.html @@ -0,0 +1,275 @@ + + + + + + + +InstanceCreator (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Interface InstanceCreator<T>

+
+
Type Parameters:
T - the type of object that will be created by this implementation.
+
+
+
public interface InstanceCreator<T>
+ + +

+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 + GsonBuilder.registerTypeAdapter(Type, Object) method before Gson will be able to use + them. +

Let us look at an example where defining an InstanceCreator might be useful. The + Id class defined below does not have a default no-args constructor.

+ +
+ 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;
+   }
+ }
+ 
+ +

If Gson encounters an object of type 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:

+ +
+ private Id() {
+   this(Object.class, 0L);
+ }
+ 
+ +

However, let us assume that the developer does not have access to the source-code of the + Id class, or does not want to define a no-args constructor for it. The developer + can solve this problem by defining an InstanceCreator for Id:

+ +
+ class IdInstanceCreator implements InstanceCreator<Id> {
+   public Id createInstance(Type type) {
+     return new Id(Object.class, 0L);
+   }
+ }
+ 
+ +

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 + new object is returned, not a common object since its fields will be overwritten. + The developer will need to register IdInstanceCreator with Gson as follows:

+ +
+ Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdInstanceCreator()).create();
+ 
+

+ +

+

+
Author:
+
Joel Leitch
+
+
+ +

+ + + + + + + + + + + + +
+Method Summary
+ TcreateInstance(Type type) + +
+          Gson invokes this call-back method during deserialization to create an instance of the + specified type.
+  +

+ + + + + + + + +
+Method Detail
+ +

+createInstance

+
+T createInstance(Type type)
+
+
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 new to create a new instance. +

+

+
Parameters:
type - the parameterized T represented as a Type. +
Returns:
a default object instance of type T.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonArray.html b/gson/docs/javadocs/com/google/gson/JsonArray.html new file mode 100644 index 00000000..aeacd7ce --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonArray.html @@ -0,0 +1,680 @@ + + + + + + + +JsonArray (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonArray

+
+java.lang.Object
+  extended by com.google.gson.JsonElement
+      extended by com.google.gson.JsonArray
+
+
+
All Implemented Interfaces:
Iterable<JsonElement>
+
+
+
+
public final class JsonArray
extends JsonElement
implements Iterable<JsonElement>
+ + +

+A class representing an array type in Json. An array is a list of JsonElements 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
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
JsonArray() + +
+          Creates an empty JsonArray.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidadd(JsonElement element) + +
+          Adds the specified element to self.
+ voidaddAll(JsonArray array) + +
+          Adds all the elements of the specified array to self.
+ JsonElementget(int i) + +
+          Returns the ith element of the array.
+ BigDecimalgetAsBigDecimal() + +
+          convenience method to get this array as a BigDecimal if it contains a single element.
+ BigIntegergetAsBigInteger() + +
+          convenience method to get this array as a BigInteger if it contains a single element.
+ booleangetAsBoolean() + +
+          convenience method to get this array as a boolean if it contains a single element.
+ doublegetAsDouble() + +
+          convenience method to get this array as a double if it contains a single element.
+ floatgetAsFloat() + +
+          convenience method to get this array as a float if it contains a single element.
+ intgetAsInt() + +
+          convenience method to get this array as an integer if it contains a single element.
+ longgetAsLong() + +
+          convenience method to get this array as a long if it contains a single element.
+ NumbergetAsNumber() + +
+          convenience method to get this array as a Number if it contains a single element.
+ shortgetAsShort() + +
+          convenience method to get this array as a primitive short if it contains a single element.
+ StringgetAsString() + +
+          convenience method to get this array as a String if it contains a single element.
+ Iterator<JsonElement>iterator() + +
+          Returns an iterator to navigate the elemetns of the array.
+ intsize() + +
+          Returns the number of elements in the array.
+ + + + + + + +
Methods inherited from class com.google.gson.JsonElement
getAsJsonArray, getAsJsonNull, getAsJsonObject, getAsJsonPrimitive, isJsonArray, isJsonNull, isJsonObject, isJsonPrimitive, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonArray

+
+public JsonArray()
+
+
Creates an empty JsonArray. +

+

+ + + + + + + + +
+Method Detail
+ +

+add

+
+public void add(JsonElement element)
+
+
Adds the specified element to self. +

+

+
+
+
+
Parameters:
element - the element that needs to be added to the array.
+
+
+
+ +

+addAll

+
+public void addAll(JsonArray array)
+
+
Adds all the elements of the specified array to self. +

+

+
+
+
+
Parameters:
array - the array whose elements need to be added to the array.
+
+
+
+ +

+size

+
+public int size()
+
+
Returns the number of elements in the array. +

+

+
+
+
+ +
Returns:
the number of elements in the array.
+
+
+
+ +

+iterator

+
+public Iterator<JsonElement> iterator()
+
+
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. +

+

+
Specified by:
iterator in interface Iterable<JsonElement>
+
+
+ +
Returns:
an iterator to navigate the elements of the array.
+
+
+
+ +

+get

+
+public JsonElement get(int i)
+
+
Returns the ith element of the array. +

+

+
+
+
+
Parameters:
i - the index of the element that is being sought. +
Returns:
the element present at the ith index. +
Throws: +
IndexOutOfBoundsException - if i is negative or greater than or equal to the + size() of the array.
+
+
+
+ +

+getAsNumber

+
+public Number getAsNumber()
+
+
convenience method to get this array as a Number if it contains a single element. +

+

+
Overrides:
getAsNumber in class JsonElement
+
+
+ +
Returns:
get this element as a number if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid Number. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsString

+
+public String getAsString()
+
+
convenience method to get this array as a String if it contains a single element. +

+

+
Overrides:
getAsString in class JsonElement
+
+
+ +
Returns:
get this element as a String if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid String. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsDouble

+
+public double getAsDouble()
+
+
convenience method to get this array as a double if it contains a single element. +

+

+
Overrides:
getAsDouble in class JsonElement
+
+
+ +
Returns:
get this element as a double if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid double. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsBigDecimal

+
+public BigDecimal getAsBigDecimal()
+
+
convenience method to get this array as a BigDecimal if it contains a single element. +

+

+
Overrides:
getAsBigDecimal in class JsonElement
+
+
+ +
Returns:
get this element as a BigDecimal if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive. +
NumberFormatException - if the element at index 0 is not a valid BigDecimal. +
IllegalStateException - if the array has more than one element.
Since:
+
1.2
+
+
+
+
+ +

+getAsBigInteger

+
+public BigInteger getAsBigInteger()
+
+
convenience method to get this array as a BigInteger if it contains a single element. +

+

+
Overrides:
getAsBigInteger in class JsonElement
+
+
+ +
Returns:
get this element as a BigInteger if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive. +
NumberFormatException - if the element at index 0 is not a valid BigInteger. +
IllegalStateException - if the array has more than one element.
Since:
+
1.2
+
+
+
+
+ +

+getAsFloat

+
+public float getAsFloat()
+
+
convenience method to get this array as a float if it contains a single element. +

+

+
Overrides:
getAsFloat in class JsonElement
+
+
+ +
Returns:
get this element as a float if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid float. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsLong

+
+public long getAsLong()
+
+
convenience method to get this array as a long if it contains a single element. +

+

+
Overrides:
getAsLong in class JsonElement
+
+
+ +
Returns:
get this element as a long if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid long. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsInt

+
+public int getAsInt()
+
+
convenience method to get this array as an integer if it contains a single element. +

+

+
Overrides:
getAsInt in class JsonElement
+
+
+ +
Returns:
get this element as an integer if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid integer. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsShort

+
+public short getAsShort()
+
+
convenience method to get this array as a primitive short if it contains a single element. +

+

+
Overrides:
getAsShort in class JsonElement
+
+
+ +
Returns:
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 JsonPrimitive and + is not a valid short. +
IllegalStateException - if the array has more than one element.
+
+
+
+ +

+getAsBoolean

+
+public boolean getAsBoolean()
+
+
convenience method to get this array as a boolean if it contains a single element. +

+

+
Overrides:
getAsBoolean in class JsonElement
+
+
+ +
Returns:
get this element as a boolean if it is single element array. +
Throws: +
ClassCastException - if the element in the array is of not a JsonPrimitive and + is not a valid boolean. +
IllegalStateException - if the array has more than one element.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonDeserializationContext.html b/gson/docs/javadocs/com/google/gson/JsonDeserializationContext.html new file mode 100644 index 00000000..e9563e36 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonDeserializationContext.html @@ -0,0 +1,235 @@ + + + + + + + +JsonDeserializationContext (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Interface JsonDeserializationContext

+
+
+
public interface JsonDeserializationContext
+ + +

+Context for deserialization that is passed to a custom deserializer during invocation of its + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) + method. +

+ +

+

+
Author:
+
Inderjeet Singh
+
+
+ +

+ + + + + + + + + + + + +
+Method Summary
+ + + + + +
+<T> T
+
deserialize(JsonElement json, + Type typeOfT) + +
+          Invokes default deserialization on the specified object.
+  +

+ + + + + + + + +
+Method Detail
+ +

+deserialize

+
+<T> T deserialize(JsonElement json,
+                  Type typeOfT)
+              throws JsonParseException
+
+
Invokes default deserialization on the specified object. It should never be invoked on + the element received as a parameter of the + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) method. Doing + so will result in an infinite loop since Gson will in-turn call the custom deserializer again. +

+

+
Type Parameters:
T - The type of the deserialized object.
Parameters:
json - the parse tree.
typeOfT - type of the expected return value. +
Returns:
An object of type typeOfT. +
Throws: +
JsonParseException - if the parse tree does not contain expected data.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonDeserializer.html b/gson/docs/javadocs/com/google/gson/JsonDeserializer.html new file mode 100644 index 00000000..48a0f1dd --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonDeserializer.html @@ -0,0 +1,275 @@ + + + + + + + +JsonDeserializer (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Interface JsonDeserializer<T>

+
+
Type Parameters:
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>
+ + +

+

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 + GsonBuilder.registerTypeAdapter(Type, Object).

+ +

Let us look at example where defining a deserializer will be useful. The Id class + defined below has two fields: clazz and value.

+ +
+ 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;
+   }
+ }
+ 
+ +

The default deserialization of Id(com.foo.MyObject.class, 20L) will require the + Json string to be {"clazz":com.foo.MyObject,"value":20}. Suppose, you already know + the type of the field that the Id will be deserialized into, and hence just want to + deserialize it from a Json string 20. You can achieve that by writing a custom + deserializer:

+ +
+ class IdDeserializer implements JsonDeserializer<Id>() {
+   public Id fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+       throws JsonParseException {
+     return (Id) new Id((Class)typeOfT, id.getValue());
+   }
+ 
+ +

You will also need to register IdDeserializer with Gson as follows:

+ +
+ Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create();
+ 
+

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ +

+ + + + + + + + + + + + +
+Method Summary
+ Tdeserialize(JsonElement json, + Type typeOfT, + JsonDeserializationContext context) + +
+          Gson invokes this call-back method during deserialization when it encounters a field of the + specified type.
+  +

+ + + + + + + + +
+Method Detail
+ +

+deserialize

+
+T deserialize(JsonElement json,
+              Type typeOfT,
+              JsonDeserializationContext context)
+              throws JsonParseException
+
+
Gson invokes this call-back method during deserialization when it encounters a field of the + specified type. +

In the implementation of this call-back method, you should consider invoking + 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 json since that will cause an infinite loop (Gson will call your + call-back method again). +

+

+
Parameters:
json - The Json data being deserialized
typeOfT - The type of the Object to deserialize to +
Returns:
a deserialized object of the specified type typeOfT which is a subclass of T +
Throws: +
JsonParseException - if json is not in the expected format of typeofT
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonElement.html b/gson/docs/javadocs/com/google/gson/JsonElement.html new file mode 100644 index 00000000..b7adbb9b --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonElement.html @@ -0,0 +1,745 @@ + + + + + + + +JsonElement (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonElement

+
+java.lang.Object
+  extended by com.google.gson.JsonElement
+
+
+
Direct Known Subclasses:
JsonArray, JsonNull, JsonObject, JsonPrimitive
+
+
+
+
public abstract class JsonElement
extends Object
+ + +

+A class representing an element of Json. It could either be a JsonObject, a + JsonArray, a JsonPrimitive or a JsonNull. +

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
JsonElement() + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ BigDecimalgetAsBigDecimal() + +
+          convenience method to get this element as a BigDecimal.
+ BigIntegergetAsBigInteger() + +
+          convenience method to get this element as a BigInteger.
+ booleangetAsBoolean() + +
+          convenience method to get this element as a boolean value.
+ doublegetAsDouble() + +
+          convenience method to get this element as a primitive double value.
+ floatgetAsFloat() + +
+          convenience method to get this element as a primitive float value.
+ intgetAsInt() + +
+          convenience method to get this element as a primitive integer value.
+ JsonArraygetAsJsonArray() + +
+          convenience method to get this element as a JsonArray.
+ JsonNullgetAsJsonNull() + +
+          convenience method to get this element as a JsonNull.
+ JsonObjectgetAsJsonObject() + +
+          convenience method to get this element as a JsonObject.
+ JsonPrimitivegetAsJsonPrimitive() + +
+          convenience method to get this element as a JsonPrimitive.
+ longgetAsLong() + +
+          convenience method to get this element as a primitive long value.
+ NumbergetAsNumber() + +
+          convenience method to get this element as a Number.
+ shortgetAsShort() + +
+          convenience method to get this element as a primitive short value.
+ StringgetAsString() + +
+          convenience method to get this element as a string value.
+ booleanisJsonArray() + +
+          provides check for verifying if this element is an array or not.
+ booleanisJsonNull() + +
+          provides check for verifying if this element represents a null value or not.
+ booleanisJsonObject() + +
+          provides check for verifying if this element is a Json object or not.
+ booleanisJsonPrimitive() + +
+          provides check for verifying if this element is a primitive or not.
+ StringtoString() + +
+          Returns a String representation of this element.
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonElement

+
+public JsonElement()
+
+
+ + + + + + + + +
+Method Detail
+ +

+isJsonArray

+
+public boolean isJsonArray()
+
+
provides check for verifying if this element is an array or not. +

+

+ +
Returns:
true if this element is of type JsonArray, false otherwise.
+
+
+
+ +

+isJsonObject

+
+public boolean isJsonObject()
+
+
provides check for verifying if this element is a Json object or not. +

+

+ +
Returns:
true if this element is of type JsonObject, false otherwise.
+
+
+
+ +

+isJsonPrimitive

+
+public boolean isJsonPrimitive()
+
+
provides check for verifying if this element is a primitive or not. +

+

+ +
Returns:
true if this element is of type JsonPrimitive, false otherwise.
+
+
+
+ +

+isJsonNull

+
+public boolean isJsonNull()
+
+
provides check for verifying if this element represents a null value or not. +

+

+ +
Returns:
true if this element is of type JsonNull, false otherwise.
Since:
+
1.2
+
+
+
+
+ +

+getAsJsonObject

+
+public JsonObject getAsJsonObject()
+
+
convenience method to get this element as a JsonObject. If the element is of some + other type, a ClassCastException will result. Hence it is best to use this method + after ensuring that this element is of the desired type by calling isJsonObject() + first. +

+

+ +
Returns:
get this element as a JsonObject. +
Throws: +
ClassCastException - if the element is of another type.
+
+
+
+ +

+getAsJsonArray

+
+public JsonArray getAsJsonArray()
+
+
convenience method to get this element as a JsonArray. If the element is of some + other type, a ClassCastException will result. Hence it is best to use this method + after ensuring that this element is of the desired type by calling isJsonArray() + first. +

+

+ +
Returns:
get this element as a JsonArray. +
Throws: +
ClassCastException - if the element is of another type.
+
+
+
+ +

+getAsJsonPrimitive

+
+public JsonPrimitive getAsJsonPrimitive()
+
+
convenience method to get this element as a JsonPrimitive. If the element is of some + other type, a ClassCastException will result. Hence it is best to use this method + after ensuring that this element is of the desired type by calling isJsonPrimitive() + first. +

+

+ +
Returns:
get this element as a JsonPrimitive. +
Throws: +
ClassCastException - if the element is of another type.
+
+
+
+ +

+getAsJsonNull

+
+public JsonNull getAsJsonNull()
+
+
convenience method to get this element as a JsonNull. If the element is of some + other type, a ClassCastException will result. Hence it is best to use this method + after ensuring that this element is of the desired type by calling isJsonNull() + first. +

+

+ +
Returns:
get this element as a JsonNull. +
Throws: +
ClassCastException - if the element is of another type.
Since:
+
1.2
+
+
+
+
+ +

+getAsBoolean

+
+public boolean getAsBoolean()
+
+
convenience method to get this element as a boolean value. +

+

+ +
Returns:
get this element as a primitive boolean value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + boolean value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsNumber

+
+public Number getAsNumber()
+
+
convenience method to get this element as a Number. +

+

+ +
Returns:
get this element as a Number. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + number. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsString

+
+public String getAsString()
+
+
convenience method to get this element as a string value. +

+

+ +
Returns:
get this element as a string value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + string value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsDouble

+
+public double getAsDouble()
+
+
convenience method to get this element as a primitive double value. +

+

+ +
Returns:
get this element as a primitive double value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + double value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsFloat

+
+public float getAsFloat()
+
+
convenience method to get this element as a primitive float value. +

+

+ +
Returns:
get this element as a primitive float value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + float value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsLong

+
+public long getAsLong()
+
+
convenience method to get this element as a primitive long value. +

+

+ +
Returns:
get this element as a primitive long value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + long value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsInt

+
+public int getAsInt()
+
+
convenience method to get this element as a primitive integer value. +

+

+ +
Returns:
get this element as a primitive integer value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + integer value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+getAsBigDecimal

+
+public BigDecimal getAsBigDecimal()
+
+
convenience method to get this element as a BigDecimal. +

+

+ +
Returns:
get this element as a BigDecimal. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive. + * @throws NumberFormatException if the element is not a valid BigDecimal. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
Since:
+
1.2
+
+
+
+
+ +

+getAsBigInteger

+
+public BigInteger getAsBigInteger()
+
+
convenience method to get this element as a BigInteger. +

+

+ +
Returns:
get this element as a BigInteger. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive. +
NumberFormatException - if the element is not a valid BigInteger. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
Since:
+
1.2
+
+
+
+
+ +

+getAsShort

+
+public short getAsShort()
+
+
convenience method to get this element as a primitive short value. +

+

+ +
Returns:
get this element as a primitive short value. +
Throws: +
ClassCastException - if the element is of not a JsonPrimitive and is not a valid + short value. +
IllegalStateException - if the element is of the type JsonArray but contains + more than a single element.
+
+
+
+ +

+toString

+
+public String toString()
+
+
Returns a String representation of this element. +

+

+
Overrides:
toString in class Object
+
+
+ +
Returns:
String the string representation of this element. The output is valid Json.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonNull.html b/gson/docs/javadocs/com/google/gson/JsonNull.html new file mode 100644 index 00000000..66904c09 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonNull.html @@ -0,0 +1,245 @@ + + + + + + + +JsonNull (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonNull

+
+java.lang.Object
+  extended by com.google.gson.JsonElement
+      extended by com.google.gson.JsonNull
+
+
+
+
public final class JsonNull
extends JsonElement
+ + +

+A class representing a Json null value. +

+ +

+

+
Since:
+
1.2
+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
JsonNull() + +
+           
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class com.google.gson.JsonElement
getAsBigDecimal, getAsBigInteger, getAsBoolean, getAsDouble, getAsFloat, getAsInt, getAsJsonArray, getAsJsonNull, getAsJsonObject, getAsJsonPrimitive, getAsLong, getAsNumber, getAsShort, getAsString, isJsonArray, isJsonNull, isJsonObject, isJsonPrimitive, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonNull

+
+public JsonNull()
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonObject.html b/gson/docs/javadocs/com/google/gson/JsonObject.html new file mode 100644 index 00000000..99b1e3a5 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonObject.html @@ -0,0 +1,462 @@ + + + + + + + +JsonObject (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonObject

+
+java.lang.Object
+  extended by com.google.gson.JsonElement
+      extended by com.google.gson.JsonObject
+
+
+
+
public final class JsonObject
extends JsonElement
+ + +

+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 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
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
JsonObject() + +
+          Creates an empty JsonObject.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ voidadd(String property, + JsonElement value) + +
+          Adds a member, which is a name-value pair, to self.
+ voidaddProperty(String property, + Number value) + +
+          Convenience method to add a primitive member.
+ voidaddProperty(String property, + String value) + +
+          Convenience method to add a primitive member.
+ Set<Map.Entry<String,JsonElement>>entrySet() + +
+          Returns a set of members of this object.
+ JsonElementget(String memberName) + +
+          Returns the member with the specified name.
+ JsonArraygetAsJsonArray(String memberName) + +
+          Convenience method to get the specified member as a JsonArray.
+ JsonObjectgetAsJsonObject(String memberName) + +
+          Convenience method to get the specified member as a JsonObject.
+ JsonPrimitivegetAsJsonPrimitive(String memberName) + +
+          Convenience method to get the specified member as a JsonPrimitive element.
+ booleanhas(String memberName) + +
+          Convenience method to check if a member with the specified name is present in this object.
+ + + + + + + +
Methods inherited from class com.google.gson.JsonElement
getAsBigDecimal, getAsBigInteger, getAsBoolean, getAsDouble, getAsFloat, getAsInt, getAsJsonArray, getAsJsonNull, getAsJsonObject, getAsJsonPrimitive, getAsLong, getAsNumber, getAsShort, getAsString, isJsonArray, isJsonNull, isJsonObject, isJsonPrimitive, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonObject

+
+public JsonObject()
+
+
Creates an empty JsonObject. +

+

+ + + + + + + + +
+Method Detail
+ +

+add

+
+public void add(String property,
+                JsonElement value)
+
+
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. +

+

+
Parameters:
property - name of the member.
value - the member object.
+
+
+
+ +

+addProperty

+
+public void addProperty(String property,
+                        String value)
+
+
Convenience method to add a primitive member. The specified value is converted to a + JsonPrimitive of String. +

+

+
Parameters:
property - name of the member.
value - the string value associated with the member.
+
+
+
+ +

+addProperty

+
+public void addProperty(String property,
+                        Number value)
+
+
Convenience method to add a primitive member. The specified value is converted to a + JsonPrimitive of Number. +

+

+
Parameters:
property - name of the member.
value - the number value associated with the member.
+
+
+
+ +

+entrySet

+
+public Set<Map.Entry<String,JsonElement>> entrySet()
+
+
Returns a set of members of this object. The set is ordered, and the order is in which the + elements were added. +

+

+ +
Returns:
a set of members of this object.
+
+
+
+ +

+has

+
+public boolean has(String memberName)
+
+
Convenience method to check if a member with the specified name is present in this object. +

+

+
Parameters:
memberName - name of the member that is being checked for presence. +
Returns:
true if there is a member with the specified name, false otherwise.
+
+
+
+ +

+get

+
+public JsonElement get(String memberName)
+
+
Returns the member with the specified name. +

+

+
Parameters:
memberName - name of the member that is being requested. +
Returns:
the member matching the name. Null if no such member exists.
+
+
+
+ +

+getAsJsonPrimitive

+
+public JsonPrimitive getAsJsonPrimitive(String memberName)
+
+
Convenience method to get the specified member as a JsonPrimitive element. +

+

+
Parameters:
memberName - name of the member being requested. +
Returns:
the JsonPrimitive corresponding to the specified member.
+
+
+
+ +

+getAsJsonArray

+
+public JsonArray getAsJsonArray(String memberName)
+
+
Convenience method to get the specified member as a JsonArray. +

+

+
Parameters:
memberName - name of the member being requested. +
Returns:
the JsonArray corresponding to the specified member.
+
+
+
+ +

+getAsJsonObject

+
+public JsonObject getAsJsonObject(String memberName)
+
+
Convenience method to get the specified member as a JsonObject. +

+

+
Parameters:
memberName - name of the member being requested. +
Returns:
the JsonObject corresponding to the specified member.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonParseException.html b/gson/docs/javadocs/com/google/gson/JsonParseException.html new file mode 100644 index 00000000..f1708067 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonParseException.html @@ -0,0 +1,299 @@ + + + + + + + +JsonParseException (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonParseException

+
+java.lang.Object
+  extended by java.lang.Throwable
+      extended by java.lang.Exception
+          extended by java.lang.RuntimeException
+              extended by com.google.gson.JsonParseException
+
+
+
All Implemented Interfaces:
Serializable
+
+
+
+
public final class JsonParseException
extends RuntimeException
+ + +

+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. + +

This exception is a RuntimeException because it is exposed to the client. Using a + 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 JsonParseException.

+

+ +

+

+
Author:
+
Joel Leitch
+
See Also:
Serialized Form
+
+ +

+ + + + + + + + + + + + + + + + + +
+Constructor Summary
JsonParseException(String msg) + +
+          Creates exception with the specified message.
JsonParseException(String msg, + Throwable cause) + +
+          Creates exception with the specified message and cause.
JsonParseException(Throwable cause) + +
+          Creates exception with the specified cause.
+  + + + + + + + +
+Method Summary
+ + + + + + + +
Methods inherited from class java.lang.Throwable
fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonParseException

+
+public JsonParseException(String msg)
+
+
Creates exception with the specified message. If you are wrapping another exception, consider + using JsonParseException(String, Throwable) instead. +

+

+
Parameters:
msg - error message describing a possible cause of this exception.
+
+
+ +

+JsonParseException

+
+public JsonParseException(String msg,
+                          Throwable cause)
+
+
Creates exception with the specified message and cause. +

+

+
Parameters:
msg - error message describing what happened.
cause - root exception that caused this exception to be thrown.
+
+
+ +

+JsonParseException

+
+public JsonParseException(Throwable cause)
+
+
Creates exception with the specified cause. Consider using + JsonParseException(String, Throwable) instead if you can describe what happened. +

+

+
Parameters:
cause - root exception that caused this exception to be thrown.
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonPrimitive.html b/gson/docs/javadocs/com/google/gson/JsonPrimitive.html new file mode 100644 index 00000000..70361829 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonPrimitive.html @@ -0,0 +1,668 @@ + + + + + + + +JsonPrimitive (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Class JsonPrimitive

+
+java.lang.Object
+  extended by com.google.gson.JsonElement
+      extended by com.google.gson.JsonPrimitive
+
+
+
+
public final class JsonPrimitive
extends JsonElement
+ + +

+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
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + +
+Constructor Summary
JsonPrimitive(Boolean bool) + +
+          Create a primitive containing a boolean value.
JsonPrimitive(char c) + +
+          Create a primitive containing a character.
JsonPrimitive(Character c) + +
+          Create a primitive containing a character.
JsonPrimitive(Number number) + +
+          Create a primitive containing a Number.
JsonPrimitive(String string) + +
+          Create a primitive containing a String value.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ BigDecimalgetAsBigDecimal() + +
+          convenience method to get this element as a BigDecimal.
+ BigIntegergetAsBigInteger() + +
+          convenience method to get this element as a BigInteger.
+ booleangetAsBoolean() + +
+          convenience method to get this element as a boolean value.
+ doublegetAsDouble() + +
+          convenience method to get this element as a primitive double.
+ floatgetAsFloat() + +
+          convenience method to get this element as a float.
+ intgetAsInt() + +
+          convenience method to get this element as a primitive integer.
+ longgetAsLong() + +
+          convenience method to get this element as a primitive long.
+ NumbergetAsNumber() + +
+          convenience method to get this element as a Number.
+ shortgetAsShort() + +
+          convenience method to get this element as a primitive short.
+ StringgetAsString() + +
+          convenience method to get this element as a String.
+ booleanisBoolean() + +
+          Check whether this primitive contains a boolean value.
+ booleanisNumber() + +
+          Check whether this primitive contains a Number.
+ booleanisString() + +
+          Check whether this primitive contains a String value.
+ + + + + + + +
Methods inherited from class com.google.gson.JsonElement
getAsJsonArray, getAsJsonNull, getAsJsonObject, getAsJsonPrimitive, isJsonArray, isJsonNull, isJsonObject, isJsonPrimitive, toString
+ + + + + + + +
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+JsonPrimitive

+
+public JsonPrimitive(Boolean bool)
+
+
Create a primitive containing a boolean value. +

+

+
Parameters:
bool - the value to create the primitive with.
+
+
+ +

+JsonPrimitive

+
+public JsonPrimitive(Number number)
+
+
Create a primitive containing a Number. +

+

+
Parameters:
number - the value to create the primitive with.
+
+
+ +

+JsonPrimitive

+
+public JsonPrimitive(String string)
+
+
Create a primitive containing a String value. +

+

+
Parameters:
string - the value to create the primitive with.
+
+
+ +

+JsonPrimitive

+
+public JsonPrimitive(Character c)
+
+
Create a primitive containing a character. The character is turned into a one character String + since Json only supports String. +

+

+
Parameters:
c - the value to create the primitive with.
+
+
+ +

+JsonPrimitive

+
+public JsonPrimitive(char c)
+
+
Create a primitive containing a character. The character is turned into a one character String + since Json only supports String. +

+

+
Parameters:
c - the value to create the primitive with.
+
+ + + + + + + + +
+Method Detail
+ +

+isBoolean

+
+public boolean isBoolean()
+
+
Check whether this primitive contains a boolean value. +

+

+ +
Returns:
true if this primitive contains a boolean value, false otherwise.
+
+
+
+ +

+getAsBoolean

+
+public boolean getAsBoolean()
+
+
convenience method to get this element as a boolean value. +

+

+
Overrides:
getAsBoolean in class JsonElement
+
+
+ +
Returns:
get this element as a primitive boolean value. +
Throws: +
ClassCastException - if the value contained is not a valid boolean value.
+
+
+
+ +

+isNumber

+
+public boolean isNumber()
+
+
Check whether this primitive contains a Number. +

+

+ +
Returns:
true if this primitive contains a Number, false otherwise.
+
+
+
+ +

+getAsNumber

+
+public Number getAsNumber()
+
+
convenience method to get this element as a Number. +

+

+
Overrides:
getAsNumber in class JsonElement
+
+
+ +
Returns:
get this element as a Number. +
Throws: +
ClassCastException - if the value contained is not a valid Number.
+
+
+
+ +

+isString

+
+public boolean isString()
+
+
Check whether this primitive contains a String value. +

+

+ +
Returns:
true if this primitive contains a String value, false otherwise.
+
+
+
+ +

+getAsString

+
+public String getAsString()
+
+
convenience method to get this element as a String. +

+

+
Overrides:
getAsString in class JsonElement
+
+
+ +
Returns:
get this element as a String. +
Throws: +
ClassCastException - if the value contained is not a valid String.
+
+
+
+ +

+getAsDouble

+
+public double getAsDouble()
+
+
convenience method to get this element as a primitive double. +

+

+
Overrides:
getAsDouble in class JsonElement
+
+
+ +
Returns:
get this element as a primitive double. +
Throws: +
ClassCastException - if the value contained is not a valid double.
+
+
+
+ +

+getAsBigDecimal

+
+public BigDecimal getAsBigDecimal()
+
+
convenience method to get this element as a BigDecimal. +

+

+
Overrides:
getAsBigDecimal in class JsonElement
+
+
+ +
Returns:
get this element as a BigDecimal. +
Throws: +
NumberFormatException - if the value contained is not a valid BigDecimal.
+
+
+
+ +

+getAsBigInteger

+
+public BigInteger getAsBigInteger()
+
+
convenience method to get this element as a BigInteger. +

+

+
Overrides:
getAsBigInteger in class JsonElement
+
+
+ +
Returns:
get this element as a BigInteger. +
Throws: +
NumberFormatException - if the value contained is not a valid BigInteger.
+
+
+
+ +

+getAsFloat

+
+public float getAsFloat()
+
+
convenience method to get this element as a float. +

+

+
Overrides:
getAsFloat in class JsonElement
+
+
+ +
Returns:
get this element as a float. +
Throws: +
ClassCastException - if the value contained is not a valid float.
+
+
+
+ +

+getAsLong

+
+public long getAsLong()
+
+
convenience method to get this element as a primitive long. +

+

+
Overrides:
getAsLong in class JsonElement
+
+
+ +
Returns:
get this element as a primitive long. +
Throws: +
ClassCastException - if the value contained is not a valid long.
+
+
+
+ +

+getAsShort

+
+public short getAsShort()
+
+
convenience method to get this element as a primitive short. +

+

+
Overrides:
getAsShort in class JsonElement
+
+
+ +
Returns:
get this element as a primitive short. +
Throws: +
ClassCastException - if the value contained is not a valid short value.
+
+
+
+ +

+getAsInt

+
+public int getAsInt()
+
+
convenience method to get this element as a primitive integer. +

+

+
Overrides:
getAsInt in class JsonElement
+
+
+ +
Returns:
get this element as a primitive integer. +
Throws: +
ClassCastException - if the value contained is not a valid integer.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonSerializationContext.html b/gson/docs/javadocs/com/google/gson/JsonSerializationContext.html new file mode 100644 index 00000000..c9960974 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonSerializationContext.html @@ -0,0 +1,246 @@ + + + + + + + +JsonSerializationContext (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Interface JsonSerializationContext

+
+
+
public interface JsonSerializationContext
+ + +

+Context for serialization that is passed to a custom serializer during invocation of its + JsonSerializer.serialize(Object, Type, JsonSerializationContext) method. +

+ +

+

+
Author:
+
Inderjeet Singh
+
+
+ +

+ + + + + + + + + + + + + + + + +
+Method Summary
+ JsonElementserialize(Object src) + +
+          Invokes default serialization on the specified object.
+ JsonElementserialize(Object src, + Type typeOfSrc) + +
+          Invokes default serialization on the specified object passing the specific type information.
+  +

+ + + + + + + + +
+Method Detail
+ +

+serialize

+
+JsonElement serialize(Object src)
+
+
Invokes default serialization on the specified object. +

+

+
Parameters:
src - the object that needs to be serialized. +
Returns:
a tree of JsonElements corresponding to the serialized form of src.
+
+
+
+ +

+serialize

+
+JsonElement serialize(Object src,
+                      Type typeOfSrc)
+
+
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 + JsonSerializer.serialize(Object, Type, JsonSerializationContext) method. Doing + so will result in an infinite loop since Gson will in-turn call the custom serializer again. +

+

+
Parameters:
src - the object that needs to be serialized.
typeOfSrc - the actual genericized type of src object. +
Returns:
a tree of JsonElements corresponding to the serialized form of src.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/JsonSerializer.html b/gson/docs/javadocs/com/google/gson/JsonSerializer.html new file mode 100644 index 00000000..33160117 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/JsonSerializer.html @@ -0,0 +1,272 @@ + + + + + + + +JsonSerializer (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson +
+Interface JsonSerializer<T>

+
+
Type Parameters:
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>
+ + +

+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 GsonBuilder.registerTypeAdapter(Type, Object). + +

Let us look at example where defining a serializer will be useful. The Id class + defined below has two fields: clazz and value.

+ +

+ 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;
+   }
+ }
+ 

+ +

The default serialization of Id(com.foo.MyObject.class, 20L) will be + {"clazz":com.foo.MyObject,"value":20}. Suppose, you just want the output to be + the value instead, which is 20 in this case. You can achieve that by writing a custom + serializer:

+ +

+ class IdSerializer implements JsonSerializer<Id>() {
+   public JsonElement toJson(Id id, Type typeOfId, JsonSerializationContext context) {
+     return new JsonPrimitive(id.getValue());
+   }
+ }
+ 

+ +

You will also need to register IdSerializer with Gson as follows:

+
+ Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create();
+ 
+

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ +

+ + + + + + + + + + + + +
+Method Summary
+ JsonElementserialize(T src, + Type typeOfSrc, + JsonSerializationContext context) + +
+          Gson invokes this call-back method during serialization when it encounters a field of the + specified type.
+  +

+ + + + + + + + +
+Method Detail
+ +

+serialize

+
+JsonElement serialize(T src,
+                      Type typeOfSrc,
+                      JsonSerializationContext context)
+
+
Gson invokes this call-back method during serialization when it encounters a field of the + specified type. + +

In the implementation of this call-back method, you should consider invoking + JsonSerializationContext.serialize(Object, Type) method to create JsonElements for any + non-trivial field of the src object. However, you should never invoke it on the + src object itself since that will cause an infinite loop (Gson will call your + call-back method again).

+

+

+
Parameters:
src - the object that needs to be converted to Json.
typeOfSrc - the actual type (fully genericized version) of the source object. +
Returns:
a JsonElement corresponding to the specified object.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/Expose.html b/gson/docs/javadocs/com/google/gson/annotations/Expose.html new file mode 100644 index 00000000..3524e6d4 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/Expose.html @@ -0,0 +1,206 @@ + + + + + + + +Expose (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson.annotations +
+Annotation Type Expose

+
+
+
@Retention(value=RUNTIME)
+@Target(value=FIELD)
+public @interface Expose
+ + +

+An annotation that indicates this member should be exposed for JSON + serialization or deserialization. + +

This annotation has no effect unless you build Gson + with a GsonBuilder and invoke + GsonBuilder.excludeFieldsWithoutExposeAnnotation() + method.

+ +

Here is an example of how this annotation is meant to be used: +

+ public class User {
+   @Expose private String firstName;
+   @Expose private String lastName;
+   @Expose private String emailAddress;
+   private String password;
+ }
+ 

+ If you created Gson with new Gson(), the toJson() and fromJson() + methods will use the password field along-with firstName, lastName, + and emailAddress for serialization and deserialization. However, if you created Gson + with Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() + then the toJson() and fromJson() methods of Gson will exclude the + password field. This is because the password field is not marked with the + @Expose annotation. + +

Note that another way to achieve the same effect would have been to just mark the + password field as transient, and Gson would have excluded it even with default + settings. The @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
+
+ +

+ +

+ +


+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/SerializedName.html b/gson/docs/javadocs/com/google/gson/annotations/SerializedName.html new file mode 100644 index 00000000..2a5504ee --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/SerializedName.html @@ -0,0 +1,253 @@ + + + + + + + +SerializedName (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson.annotations +
+Annotation Type SerializedName

+
+
+
@Retention(value=RUNTIME)
+@Target(value=FIELD)
+public @interface SerializedName
+ + +

+An annotation that indicates this member should be serialized to JSON with + the provided name value as its field name. + +

This annotation will override any FieldNamingPolicy, including + the default field naming policy, that may have been set on the Gson + instance. A different naming policy can set using the GsonBuilder class. See + GsonBuilder.setFieldNamingPolicy(com.google.gson.FieldNamingPolicy) + for more information.

+ +

Here is an example of how this annotation is meant to be used:

+
+ 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;
+   }
+ }
+ 
+ +

The following shows the output that is generated when serializing an instance of the + above example class:

+
+ SomeClassWithFields objectToSerialize = new SomeClassWithFields("a", "b");
+ Gson gson = new Gson();
+ String jsonRepresentation = gson.toJson(objectToSerialize);
+ System.out.println(jsonRepresentation);
+
+ ===== OUTPUT =====
+ {"name":"a","someOtherField":"b"}
+ 
+ +

NOTE: The value you specify in this annotation must be a valid JSON field name.

+

+ +

+

+
Author:
+
Joel Leitch
+
See Also:
FieldNamingPolicy
+
+ +

+ + + + + + + + + + + +
+Required Element Summary
+ Stringvalue + +
+           
+  +

+ + + + + + + + +
+Element Detail
+ +

+value

+
+public abstract String value
+
+
+
+
+
+ +
Returns:
the desired name of the field when it is serialized
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/Since.html b/gson/docs/javadocs/com/google/gson/annotations/Since.html new file mode 100644 index 00000000..ff974112 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/Since.html @@ -0,0 +1,245 @@ + + + + + + + +Since (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson.annotations +
+Annotation Type Since

+
+
+
@Retention(value=RUNTIME)
+@Target(value={FIELD,TYPE})
+public @interface Since
+ + +

+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. + +

+ This annotation has no effect unless you build Gson with a + GsonBuilder and invoke + GsonBuilder.setVersion(double) method. + +

Here is an example of how this annotation is meant to be used:

+
+ 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;
+ }
+ 
+ +

If you created Gson with new Gson(), the toJson() and fromJson() + methods will use all the fields for serialization and deserialization. However, if you created + Gson with Gson gson = new GsonBuilder().setVersion(1.0).create() the the + toJson() and fromJson() methods of Gson will exclude the address field + since it's version number is set to 1.1.

+

+ +

+

+
Author:
+
Inderjeet Singh
+
+
+ +

+ + + + + + + + + + + +
+Required Element Summary
+ doublevalue + +
+          the value indicating a version number since this member + or type has been present.
+  +

+ + + + + + + + +
+Element Detail
+ +

+value

+
+public abstract double value
+
+
the value indicating a version number since this member + or type has been present. +

+

+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/class-use/Expose.html b/gson/docs/javadocs/com/google/gson/annotations/class-use/Expose.html new file mode 100644 index 00000000..1647ed90 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/class-use/Expose.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Class com.google.gson.annotations.Expose (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.annotations.Expose

+
+No usage of com.google.gson.annotations.Expose +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/class-use/SerializedName.html b/gson/docs/javadocs/com/google/gson/annotations/class-use/SerializedName.html new file mode 100644 index 00000000..30e05a3f --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/class-use/SerializedName.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Class com.google.gson.annotations.SerializedName (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.annotations.SerializedName

+
+No usage of com.google.gson.annotations.SerializedName +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/class-use/Since.html b/gson/docs/javadocs/com/google/gson/annotations/class-use/Since.html new file mode 100644 index 00000000..fce3e9e3 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/class-use/Since.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Class com.google.gson.annotations.Since (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.annotations.Since

+
+No usage of com.google.gson.annotations.Since +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/package-frame.html b/gson/docs/javadocs/com/google/gson/annotations/package-frame.html new file mode 100644 index 00000000..25590521 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/package-frame.html @@ -0,0 +1,37 @@ + + + + + + + +com.google.gson.annotations (Gson 1.2 API) + + + + + + + + + + + +com.google.gson.annotations + + + + +
+Annotation Types  + +
+Expose +
+SerializedName +
+Since
+ + + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/package-summary.html b/gson/docs/javadocs/com/google/gson/annotations/package-summary.html new file mode 100644 index 00000000..73346761 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/package-summary.html @@ -0,0 +1,185 @@ + + + + + + + +com.google.gson.annotations (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package com.google.gson.annotations +

+This package provides annotations that can be used with Gson. +

+See: +
+          Description +

+ + + + + + + + + + + + + + + + + +
+Annotation Types Summary
ExposeAn annotation that indicates this member should be exposed for JSON + serialization or deserialization.
SerializedNameAn annotation that indicates this member should be serialized to JSON with + the provided name value as its field name.
SinceAn annotation that indicates the version number since a member or a type has been present.
+  + +

+

+Package com.google.gson.annotations Description +

+ +

+This package provides annotations that can be used with Gson. +

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/package-tree.html b/gson/docs/javadocs/com/google/gson/annotations/package-tree.html new file mode 100644 index 00000000..46e73c5a --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/package-tree.html @@ -0,0 +1,155 @@ + + + + + + + +com.google.gson.annotations Class Hierarchy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package com.google.gson.annotations +

+
+
+
Package Hierarchies:
All Packages
+
+

+Annotation Type Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/annotations/package-use.html b/gson/docs/javadocs/com/google/gson/annotations/package-use.html new file mode 100644 index 00000000..1a0963be --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/annotations/package-use.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Package com.google.gson.annotations (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
com.google.gson.annotations

+
+No usage of com.google.gson.annotations +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/FieldNamingPolicy.html b/gson/docs/javadocs/com/google/gson/class-use/FieldNamingPolicy.html new file mode 100644 index 00000000..c94dbb4f --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/FieldNamingPolicy.html @@ -0,0 +1,208 @@ + + + + + + + +Uses of Class com.google.gson.FieldNamingPolicy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.FieldNamingPolicy

+
+ + + + + + + + + +
+Packages that use FieldNamingPolicy
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of FieldNamingPolicy in com.google.gson
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson that return FieldNamingPolicy
+static FieldNamingPolicyFieldNamingPolicy.valueOf(String name) + +
+          Returns the enum constant of this type with the specified name.
+static FieldNamingPolicy[]FieldNamingPolicy.values() + +
+          Returns an array containing the constants of this enum type, in +the order they are declared.
+  +

+ + + + + + + + + +
Methods in com.google.gson with parameters of type FieldNamingPolicy
+ GsonBuilderGsonBuilder.setFieldNamingPolicy(FieldNamingPolicy namingConvention) + +
+          Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/Gson.html b/gson/docs/javadocs/com/google/gson/class-use/Gson.html new file mode 100644 index 00000000..0de980ff --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/Gson.html @@ -0,0 +1,182 @@ + + + + + + + +Uses of Class com.google.gson.Gson (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.Gson

+
+ + + + + + + + + +
+Packages that use Gson
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of Gson in com.google.gson
+  +

+ + + + + + + + + +
Methods in com.google.gson that return Gson
+ GsonGsonBuilder.create() + +
+          Creates a Gson instance based on the current configuration.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/GsonBuilder.html b/gson/docs/javadocs/com/google/gson/class-use/GsonBuilder.html new file mode 100644 index 00000000..e397ed34 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/GsonBuilder.html @@ -0,0 +1,249 @@ + + + + + + + +Uses of Class com.google.gson.GsonBuilder (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.GsonBuilder

+
+ + + + + + + + + +
+Packages that use GsonBuilder
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of GsonBuilder in com.google.gson
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.google.gson that return GsonBuilder
+ GsonBuilderGsonBuilder.excludeFieldsWithModifiers(int... modifiers) + +
+          Configures Gson to excludes all class fields that have the specified modifiers.
+ GsonBuilderGsonBuilder.excludeFieldsWithoutExposeAnnotation() + +
+          Configures Gson to exclude all fields from consideration for serialization or deserialization + that do not have the Expose annotation.
+ GsonBuilderGsonBuilder.registerTypeAdapter(Type type, + Object typeAdapter) + +
+          Configures Gson for custom serialization or deserialization.
+ GsonBuilderGsonBuilder.serializeNulls() + +
+          Configure Gson to serialize null fields.
+ GsonBuilderGsonBuilder.setDateFormat(int style) + +
+          Configures Gson to to serialize Date objects according to the style value provided.
+ GsonBuilderGsonBuilder.setDateFormat(String pattern) + +
+          Configures Gson to serialize Date objects according to the pattern provided.
+ GsonBuilderGsonBuilder.setFieldNamingPolicy(FieldNamingPolicy namingConvention) + +
+          Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization.
+ GsonBuilderGsonBuilder.setPrettyPrinting() + +
+          Configures Gson to output Json that fits in a page for pretty printing.
+ GsonBuilderGsonBuilder.setVersion(double ignoreVersionsAfter) + +
+          Configures Gson to enable versioning support.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/InstanceCreator.html b/gson/docs/javadocs/com/google/gson/class-use/InstanceCreator.html new file mode 100644 index 00000000..7b93c494 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/InstanceCreator.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Interface com.google.gson.InstanceCreator (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
com.google.gson.InstanceCreator

+
+No usage of com.google.gson.InstanceCreator +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonArray.html b/gson/docs/javadocs/com/google/gson/class-use/JsonArray.html new file mode 100644 index 00000000..57d88f07 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonArray.html @@ -0,0 +1,206 @@ + + + + + + + +Uses of Class com.google.gson.JsonArray (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonArray

+
+ + + + + + + + + +
+Packages that use JsonArray
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonArray in com.google.gson
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson that return JsonArray
+ JsonArrayJsonElement.getAsJsonArray() + +
+          convenience method to get this element as a JsonArray.
+ JsonArrayJsonObject.getAsJsonArray(String memberName) + +
+          Convenience method to get the specified member as a JsonArray.
+  +

+ + + + + + + + + +
Methods in com.google.gson with parameters of type JsonArray
+ voidJsonArray.addAll(JsonArray array) + +
+          Adds all the elements of the specified array to self.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializationContext.html b/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializationContext.html new file mode 100644 index 00000000..2f5f4388 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializationContext.html @@ -0,0 +1,185 @@ + + + + + + + +Uses of Interface com.google.gson.JsonDeserializationContext (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
com.google.gson.JsonDeserializationContext

+
+ + + + + + + + + +
+Packages that use JsonDeserializationContext
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonDeserializationContext in com.google.gson
+  +

+ + + + + + + + + +
Methods in com.google.gson with parameters of type JsonDeserializationContext
+ TJsonDeserializer.deserialize(JsonElement json, + Type typeOfT, + JsonDeserializationContext context) + +
+          Gson invokes this call-back method during deserialization when it encounters a field of the + specified type.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializer.html b/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializer.html new file mode 100644 index 00000000..2a813a4a --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonDeserializer.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Interface com.google.gson.JsonDeserializer (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
com.google.gson.JsonDeserializer

+
+No usage of com.google.gson.JsonDeserializer +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonElement.html b/gson/docs/javadocs/com/google/gson/class-use/JsonElement.html new file mode 100644 index 00000000..c8043025 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonElement.html @@ -0,0 +1,334 @@ + + + + + + + +Uses of Class com.google.gson.JsonElement (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonElement

+
+ + + + + + + + + +
+Packages that use JsonElement
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonElement in com.google.gson
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Subclasses of JsonElement in com.google.gson
+ classJsonArray + +
+          A class representing an array type in Json.
+ classJsonNull + +
+          A class representing a Json null value.
+ classJsonObject + +
+          A class representing an object type in Json.
+ classJsonPrimitive + +
+          A class representing a Json primitive value.
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.google.gson that return JsonElement
+ JsonElementJsonArray.get(int i) + +
+          Returns the ith element of the array.
+ JsonElementJsonObject.get(String memberName) + +
+          Returns the member with the specified name.
+ JsonElementJsonSerializationContext.serialize(Object src) + +
+          Invokes default serialization on the specified object.
+ JsonElementJsonSerializationContext.serialize(Object src, + Type typeOfSrc) + +
+          Invokes default serialization on the specified object passing the specific type information.
+ JsonElementJsonSerializer.serialize(T src, + Type typeOfSrc, + JsonSerializationContext context) + +
+          Gson invokes this call-back method during serialization when it encounters a field of the + specified type.
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson that return types with arguments of type JsonElement
+ Set<Map.Entry<String,JsonElement>>JsonObject.entrySet() + +
+          Returns a set of members of this object.
+ Iterator<JsonElement>JsonArray.iterator() + +
+          Returns an iterator to navigate the elemetns of the array.
+  +

+ + + + + + + + + + + + + + + + + + + + + +
Methods in com.google.gson with parameters of type JsonElement
+ voidJsonArray.add(JsonElement element) + +
+          Adds the specified element to self.
+ voidJsonObject.add(String property, + JsonElement value) + +
+          Adds a member, which is a name-value pair, to self.
+ + + + + +
+<T> T
+
JsonDeserializationContext.deserialize(JsonElement json, + Type typeOfT) + +
+          Invokes default deserialization on the specified object.
+ TJsonDeserializer.deserialize(JsonElement json, + Type typeOfT, + JsonDeserializationContext context) + +
+          Gson invokes this call-back method during deserialization when it encounters a field of the + specified type.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonNull.html b/gson/docs/javadocs/com/google/gson/class-use/JsonNull.html new file mode 100644 index 00000000..6b9d5835 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonNull.html @@ -0,0 +1,182 @@ + + + + + + + +Uses of Class com.google.gson.JsonNull (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonNull

+
+ + + + + + + + + +
+Packages that use JsonNull
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonNull in com.google.gson
+  +

+ + + + + + + + + +
Methods in com.google.gson that return JsonNull
+ JsonNullJsonElement.getAsJsonNull() + +
+          convenience method to get this element as a JsonNull.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonObject.html b/gson/docs/javadocs/com/google/gson/class-use/JsonObject.html new file mode 100644 index 00000000..3b9526a4 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonObject.html @@ -0,0 +1,190 @@ + + + + + + + +Uses of Class com.google.gson.JsonObject (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonObject

+
+ + + + + + + + + +
+Packages that use JsonObject
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonObject in com.google.gson
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson that return JsonObject
+ JsonObjectJsonElement.getAsJsonObject() + +
+          convenience method to get this element as a JsonObject.
+ JsonObjectJsonObject.getAsJsonObject(String memberName) + +
+          Convenience method to get the specified member as a JsonObject.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonParseException.html b/gson/docs/javadocs/com/google/gson/class-use/JsonParseException.html new file mode 100644 index 00000000..0d91180a --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonParseException.html @@ -0,0 +1,267 @@ + + + + + + + +Uses of Class com.google.gson.JsonParseException (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonParseException

+
+ + + + + + + + + +
+Packages that use JsonParseException
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonParseException in com.google.gson
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Methods in com.google.gson that throw JsonParseException
+ + + + + +
+<T> T
+
JsonDeserializationContext.deserialize(JsonElement json, + Type typeOfT) + +
+          Invokes default deserialization on the specified object.
+ TJsonDeserializer.deserialize(JsonElement json, + Type typeOfT, + JsonDeserializationContext context) + +
+          Gson invokes this call-back method during deserialization when it encounters a field of the + specified type.
+ + + + + +
+<T> T
+
Gson.fromJson(Reader json, + Class<T> classOfT) + +
+          This method deserializes the Json read from the specified reader into an object of the + specified class.
+ + + + + +
+<T> T
+
Gson.fromJson(Reader json, + Type typeOfT) + +
+          This method deserializes the Json read from the specified reader into an object of the + specified type.
+ + + + + +
+<T> T
+
Gson.fromJson(String json, + Class<T> classOfT) + +
+          This method deserializes the specified Json into an object of the specified class.
+ + + + + +
+<T> T
+
Gson.fromJson(String json, + Type typeOfT) + +
+          This method deserializes the specified Json into an object of the specified type.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonPrimitive.html b/gson/docs/javadocs/com/google/gson/class-use/JsonPrimitive.html new file mode 100644 index 00000000..d4768f95 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonPrimitive.html @@ -0,0 +1,190 @@ + + + + + + + +Uses of Class com.google.gson.JsonPrimitive (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.JsonPrimitive

+
+ + + + + + + + + +
+Packages that use JsonPrimitive
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonPrimitive in com.google.gson
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson that return JsonPrimitive
+ JsonPrimitiveJsonElement.getAsJsonPrimitive() + +
+          convenience method to get this element as a JsonPrimitive.
+ JsonPrimitiveJsonObject.getAsJsonPrimitive(String memberName) + +
+          Convenience method to get the specified member as a JsonPrimitive element.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonSerializationContext.html b/gson/docs/javadocs/com/google/gson/class-use/JsonSerializationContext.html new file mode 100644 index 00000000..f133d3f2 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonSerializationContext.html @@ -0,0 +1,185 @@ + + + + + + + +Uses of Interface com.google.gson.JsonSerializationContext (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
com.google.gson.JsonSerializationContext

+
+ + + + + + + + + +
+Packages that use JsonSerializationContext
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + +
+Uses of JsonSerializationContext in com.google.gson
+  +

+ + + + + + + + + +
Methods in com.google.gson with parameters of type JsonSerializationContext
+ JsonElementJsonSerializer.serialize(T src, + Type typeOfSrc, + JsonSerializationContext context) + +
+          Gson invokes this call-back method during serialization when it encounters a field of the + specified type.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/class-use/JsonSerializer.html b/gson/docs/javadocs/com/google/gson/class-use/JsonSerializer.html new file mode 100644 index 00000000..3b8cb94c --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/class-use/JsonSerializer.html @@ -0,0 +1,145 @@ + + + + + + + +Uses of Interface com.google.gson.JsonSerializer (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Interface
com.google.gson.JsonSerializer

+
+No usage of com.google.gson.JsonSerializer +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/package-frame.html b/gson/docs/javadocs/com/google/gson/package-frame.html new file mode 100644 index 00000000..23c270ba --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/package-frame.html @@ -0,0 +1,86 @@ + + + + + + + +com.google.gson (Gson 1.2 API) + + + + + + + + + + + +com.google.gson + + + + +
+Interfaces  + +
+InstanceCreator +
+JsonDeserializationContext +
+JsonDeserializer +
+JsonSerializationContext +
+JsonSerializer
+ + + + + + +
+Classes  + +
+Gson +
+GsonBuilder +
+JsonArray +
+JsonElement +
+JsonNull +
+JsonObject +
+JsonPrimitive
+ + + + + + +
+Enums  + +
+FieldNamingPolicy
+ + + + + + +
+Exceptions  + +
+JsonParseException
+ + + + diff --git a/gson/docs/javadocs/com/google/gson/package-summary.html b/gson/docs/javadocs/com/google/gson/package-summary.html new file mode 100644 index 00000000..7ad4922a --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/package-summary.html @@ -0,0 +1,269 @@ + + + + + + + +com.google.gson (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package com.google.gson +

+This package provides the Gson class to convert Json to Java and + vice-versa. +

+See: +
+          Description +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+Interface Summary
InstanceCreator<T>This interface is implemented to create instances of a class that does not define a no-args + constructor.
JsonDeserializationContextContext for deserialization that is passed to a custom deserializer during invocation of its + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) + method.
JsonDeserializer<T>Interface representing a custom deserializer for Json.
JsonSerializationContextContext for serialization that is passed to a custom serializer during invocation of its + serialize(Object, Type, JsonSerializationContext) method.
JsonSerializer<T>Interface representing a custom serializer for Json.
+  + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Class Summary
GsonThis is the main class for using Gson.
GsonBuilderUse this builder to construct a Gson instance when you need to set configuration + options other than the default.
JsonArrayA class representing an array type in Json.
JsonElementA class representing an element of Json.
JsonNullA class representing a Json null value.
JsonObjectA class representing an object type in Json.
JsonPrimitiveA class representing a Json primitive value.
+  + +

+ + + + + + + + + +
+Enum Summary
FieldNamingPolicyAn enumeration that defines a few standard naming conventions for JSON field names.
+  + +

+ + + + + + + + + +
+Exception Summary
JsonParseExceptionThis exception is raised if there is a serious issue that occurs during parsing of a Json + string.
+  + +

+

+Package com.google.gson Description +

+ +

+This package provides the Gson class to convert Json to Java and + vice-versa. + +

The primary class to use is Gson which can be constructed with + new Gson() (using default settings) or by using GsonBuilder + (to configure various options such as using versioning and so on).

+

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/package-tree.html b/gson/docs/javadocs/com/google/gson/package-tree.html new file mode 100644 index 00000000..53858237 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/package-tree.html @@ -0,0 +1,179 @@ + + + + + + + +com.google.gson Class Hierarchy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package com.google.gson +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+ +

+Interface Hierarchy +

+ +

+Enum Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/package-use.html b/gson/docs/javadocs/com/google/gson/package-use.html new file mode 100644 index 00000000..8fed2ef5 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/package-use.html @@ -0,0 +1,237 @@ + + + + + + + +Uses of Package com.google.gson (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
com.google.gson

+
+ + + + + + + + + +
+Packages that use com.google.gson
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa. 
+  +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Classes in com.google.gson used by com.google.gson
FieldNamingPolicy + +
+          An enumeration that defines a few standard naming conventions for JSON field names.
Gson + +
+          This is the main class for using Gson.
GsonBuilder + +
+          Use this builder to construct a Gson instance when you need to set configuration + options other than the default.
JsonArray + +
+          A class representing an array type in Json.
JsonDeserializationContext + +
+          Context for deserialization that is passed to a custom deserializer during invocation of its + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) + method.
JsonElement + +
+          A class representing an element of Json.
JsonNull + +
+          A class representing a Json null value.
JsonObject + +
+          A class representing an object type in Json.
JsonParseException + +
+          This exception is raised if there is a serious issue that occurs during parsing of a Json + string.
JsonPrimitive + +
+          A class representing a Json primitive value.
JsonSerializationContext + +
+          Context for serialization that is passed to a custom serializer during invocation of its + JsonSerializer.serialize(Object, Type, JsonSerializationContext) method.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/TypeToken.html b/gson/docs/javadocs/com/google/gson/reflect/TypeToken.html new file mode 100644 index 00000000..863a3559 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/TypeToken.html @@ -0,0 +1,450 @@ + + + + + + + +TypeToken (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +com.google.gson.reflect +
+Class TypeToken<T>

+
+java.lang.Object
+  extended by com.google.gson.reflect.TypeToken<T>
+
+
+
+
public abstract class TypeToken<T>
extends Object
+ + +

+Represents a generic type T. + + You can use this class to get the generic type for a class. For example, + to get the generic type for Collection<Foo>, you can use: +

+ Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType() + + +

Assumes Type implements equals() and hashCode() + as a value (as opposed to identity) comparison. + + Also implements isAssignableFrom(Type) to check type-safe + assignability. +

+ +

+

+
Author:
+
Bob Lee, Sven Mawson
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ booleanequals(Object o) + +
+          Method to test equality.
+static + + + + +
+<T> TypeToken<T>
+
get(Class<T> type) + +
+          Gets type token for the given Class instance.
+static TypeToken<?>get(Type type) + +
+          Gets type token for the given Type instance.
+ Class<? super T>getRawType() + +
+          Gets the raw type.
+ TypegetType() + +
+          Gets underlying Type instance.
+ inthashCode() + +
+          Hashcode for this object.
+ booleanisAssignableFrom(Class<?> cls) + +
+          Check if this type is assignable from the given class object.
+ booleanisAssignableFrom(Type from) + +
+          Check if this type is assignable from the given Type.
+ booleanisAssignableFrom(TypeToken<?> token) + +
+          Check if this type is assignable from the given type token.
+ StringtoString() + +
+          Returns a string representation of this object.
+ + + + + + + +
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+getRawType

+
+public Class<? super T> getRawType()
+
+
Gets the raw type. +

+

+
+
+
+
+ +

+getType

+
+public Type getType()
+
+
Gets underlying Type instance. +

+

+
+
+
+
+ +

+isAssignableFrom

+
+public boolean isAssignableFrom(Class<?> cls)
+
+
Check if this type is assignable from the given class object. +

+

+
+
+
+
+ +

+isAssignableFrom

+
+public boolean isAssignableFrom(Type from)
+
+
Check if this type is assignable from the given Type. +

+

+
+
+
+
+ +

+isAssignableFrom

+
+public boolean isAssignableFrom(TypeToken<?> token)
+
+
Check if this type is assignable from the given type token. +

+

+
+
+
+
+ +

+hashCode

+
+public int hashCode()
+
+
Hashcode for this object. +

+

+
Overrides:
hashCode in class Object
+
+
+ +
Returns:
hashcode for this object.
+
+
+
+ +

+equals

+
+public boolean equals(Object o)
+
+
Method to test equality. +

+

+
Overrides:
equals in class Object
+
+
+ +
Returns:
true if this object is logically equal to the specified object, false otherwise.
+
+
+
+ +

+toString

+
+public String toString()
+
+
Returns a string representation of this object. +

+

+
Overrides:
toString in class Object
+
+
+ +
Returns:
a string representation of this object.
+
+
+
+ +

+get

+
+public static TypeToken<?> get(Type type)
+
+
Gets type token for the given Type instance. +

+

+
+
+
+
+ +

+get

+
+public static <T> TypeToken<T> get(Class<T> type)
+
+
Gets type token for the given Class instance. +

+

+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/class-use/TypeToken.html b/gson/docs/javadocs/com/google/gson/reflect/class-use/TypeToken.html new file mode 100644 index 00000000..a5bec5bf --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/class-use/TypeToken.html @@ -0,0 +1,212 @@ + + + + + + + +Uses of Class com.google.gson.reflect.TypeToken (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
com.google.gson.reflect.TypeToken

+
+ + + + + + + + + +
+Packages that use TypeToken
com.google.gson.reflectThis package provides utility classes for finding type information for generic types. 
+  +

+ + + + + +
+Uses of TypeToken in com.google.gson.reflect
+  +

+ + + + + + + + + + + + + +
Methods in com.google.gson.reflect that return TypeToken
+static + + + + +
+<T> TypeToken<T>
+
TypeToken.get(Class<T> type) + +
+          Gets type token for the given Class instance.
+static TypeToken<?>TypeToken.get(Type type) + +
+          Gets type token for the given Type instance.
+  +

+ + + + + + + + + +
Methods in com.google.gson.reflect with parameters of type TypeToken
+ booleanTypeToken.isAssignableFrom(TypeToken<?> token) + +
+          Check if this type is assignable from the given type token.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/package-frame.html b/gson/docs/javadocs/com/google/gson/reflect/package-frame.html new file mode 100644 index 00000000..36a4b7f2 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/package-frame.html @@ -0,0 +1,33 @@ + + + + + + + +com.google.gson.reflect (Gson 1.2 API) + + + + + + + + + + + +com.google.gson.reflect + + + + +
+Classes  + +
+TypeToken
+ + + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/package-summary.html b/gson/docs/javadocs/com/google/gson/reflect/package-summary.html new file mode 100644 index 00000000..76e2b615 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/package-summary.html @@ -0,0 +1,175 @@ + + + + + + + +com.google.gson.reflect (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package com.google.gson.reflect +

+This package provides utility classes for finding type information for generic types. +

+See: +
+          Description +

+ + + + + + + + + +
+Class Summary
TypeToken<T>Represents a generic type T.
+  + +

+

+Package com.google.gson.reflect Description +

+ +

+This package provides utility classes for finding type information for generic types. +

+ +

+

+
Author:
+
Inderjeet Singh, Joel Leitch
+
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/package-tree.html b/gson/docs/javadocs/com/google/gson/reflect/package-tree.html new file mode 100644 index 00000000..d33a2b67 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/package-tree.html @@ -0,0 +1,154 @@ + + + + + + + +com.google.gson.reflect Class Hierarchy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package com.google.gson.reflect +

+
+
+
Package Hierarchies:
All Packages
+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/com/google/gson/reflect/package-use.html b/gson/docs/javadocs/com/google/gson/reflect/package-use.html new file mode 100644 index 00000000..2fae08e9 --- /dev/null +++ b/gson/docs/javadocs/com/google/gson/reflect/package-use.html @@ -0,0 +1,171 @@ + + + + + + + +Uses of Package com.google.gson.reflect (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
com.google.gson.reflect

+
+ + + + + + + + + +
+Packages that use com.google.gson.reflect
com.google.gson.reflectThis package provides utility classes for finding type information for generic types. 
+  +

+ + + + + + + + +
+Classes in com.google.gson.reflect used by com.google.gson.reflect
TypeToken + +
+          Represents a generic type T.
+  +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/constant-values.html b/gson/docs/javadocs/constant-values.html new file mode 100644 index 00000000..bb3ab9d5 --- /dev/null +++ b/gson/docs/javadocs/constant-values.html @@ -0,0 +1,147 @@ + + + + + + + +Constant Field Values (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/deprecated-list.html b/gson/docs/javadocs/deprecated-list.html new file mode 100644 index 00000000..8fc20afb --- /dev/null +++ b/gson/docs/javadocs/deprecated-list.html @@ -0,0 +1,147 @@ + + + + + + + +Deprecated List (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/help-doc.html b/gson/docs/javadocs/help-doc.html new file mode 100644 index 00000000..b1555d22 --- /dev/null +++ b/gson/docs/javadocs/help-doc.html @@ -0,0 +1,224 @@ + + + + + + + +API Help (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Overview

+
+ +

+The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.

+

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+ +

+Annotation Type

+
+ +

+Each annotation type has its own separate page with the following sections:

+
+ +

+Enum

+
+ +

+Each enum has its own separate page with the following sections:

+
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object. +
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+

+Constant Field Values

+The Constant Field Values page lists the static final fields and their values. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/index-all.html b/gson/docs/javadocs/index-all.html new file mode 100644 index 00000000..18700ab5 --- /dev/null +++ b/gson/docs/javadocs/index-all.html @@ -0,0 +1,541 @@ + + + + + + + +Index (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+A

+
+
add(JsonElement) - +Method in class com.google.gson.JsonArray +
Adds the specified element to self. +
add(String, JsonElement) - +Method in class com.google.gson.JsonObject +
Adds a member, which is a name-value pair, to self. +
addAll(JsonArray) - +Method in class com.google.gson.JsonArray +
Adds all the elements of the specified array to self. +
addProperty(String, String) - +Method in class com.google.gson.JsonObject +
Convenience method to add a primitive member. +
addProperty(String, Number) - +Method in class com.google.gson.JsonObject +
Convenience method to add a primitive member. +
+
+

+C

+
+
com.google.gson - package com.google.gson
This package provides the Gson class to convert Json to Java and + vice-versa.
com.google.gson.annotations - package com.google.gson.annotations
This package provides annotations that can be used with Gson.
com.google.gson.reflect - package com.google.gson.reflect
This package provides utility classes for finding type information for generic types.
create() - +Method in class com.google.gson.GsonBuilder +
Creates a Gson instance based on the current configuration. +
createInstance(Type) - +Method in interface com.google.gson.InstanceCreator +
Gson invokes this call-back method during deserialization to create an instance of the + specified type. +
+
+

+D

+
+
deserialize(JsonElement, Type) - +Method in interface com.google.gson.JsonDeserializationContext +
Invokes default deserialization on the specified object. +
deserialize(JsonElement, Type, JsonDeserializationContext) - +Method in interface com.google.gson.JsonDeserializer +
Gson invokes this call-back method during deserialization when it encounters a field of the + specified type. +
+
+

+E

+
+
entrySet() - +Method in class com.google.gson.JsonObject +
Returns a set of members of this object. +
equals(Object) - +Method in class com.google.gson.reflect.TypeToken +
Method to test equality. +
excludeFieldsWithModifiers(int...) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to excludes all class fields that have the specified modifiers. +
excludeFieldsWithoutExposeAnnotation() - +Method in class com.google.gson.GsonBuilder +
Configures Gson to exclude all fields from consideration for serialization or deserialization + that do not have the Expose annotation. +
Expose - Annotation Type in com.google.gson.annotations
An annotation that indicates this member should be exposed for JSON + serialization or deserialization.
+
+

+F

+
+
FieldNamingPolicy - Enum in com.google.gson
An enumeration that defines a few standard naming conventions for JSON field names.
fromJson(String, Class<T>) - +Method in class com.google.gson.Gson +
This method deserializes the specified Json into an object of the specified class. +
fromJson(String, Type) - +Method in class com.google.gson.Gson +
This method deserializes the specified Json into an object of the specified type. +
fromJson(Reader, Class<T>) - +Method in class com.google.gson.Gson +
This method deserializes the Json read from the specified reader into an object of the + specified class. +
fromJson(Reader, Type) - +Method in class com.google.gson.Gson +
This method deserializes the Json read from the specified reader into an object of the + specified type. +
+
+

+G

+
+
get(int) - +Method in class com.google.gson.JsonArray +
Returns the ith element of the array. +
get(String) - +Method in class com.google.gson.JsonObject +
Returns the member with the specified name. +
get(Type) - +Static method in class com.google.gson.reflect.TypeToken +
Gets type token for the given Type instance. +
get(Class<T>) - +Static method in class com.google.gson.reflect.TypeToken +
Gets type token for the given Class instance. +
getAsBigDecimal() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a BigDecimal if it contains a single element. +
getAsBigDecimal() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a BigDecimal. +
getAsBigDecimal() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a BigDecimal. +
getAsBigInteger() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a BigInteger if it contains a single element. +
getAsBigInteger() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a BigInteger. +
getAsBigInteger() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a BigInteger. +
getAsBoolean() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a boolean if it contains a single element. +
getAsBoolean() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a boolean value. +
getAsBoolean() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a boolean value. +
getAsDouble() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a double if it contains a single element. +
getAsDouble() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive double value. +
getAsDouble() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive double. +
getAsFloat() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a float if it contains a single element. +
getAsFloat() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive float value. +
getAsFloat() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a float. +
getAsInt() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as an integer if it contains a single element. +
getAsInt() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive integer value. +
getAsInt() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive integer. +
getAsJsonArray() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonArray. +
getAsJsonArray(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonArray. +
getAsJsonNull() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonNull. +
getAsJsonObject() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonObject. +
getAsJsonObject(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonObject. +
getAsJsonPrimitive() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonPrimitive. +
getAsJsonPrimitive(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonPrimitive element. +
getAsLong() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a long if it contains a single element. +
getAsLong() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive long value. +
getAsLong() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive long. +
getAsNumber() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a Number if it contains a single element. +
getAsNumber() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a Number. +
getAsNumber() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a Number. +
getAsShort() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a primitive short if it contains a single element. +
getAsShort() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive short value. +
getAsShort() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive short. +
getAsString() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a String if it contains a single element. +
getAsString() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a string value. +
getAsString() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a String. +
getRawType() - +Method in class com.google.gson.reflect.TypeToken +
Gets the raw type. +
getType() - +Method in class com.google.gson.reflect.TypeToken +
Gets underlying Type instance. +
Gson - Class in com.google.gson
This is the main class for using Gson.
Gson() - +Constructor for class com.google.gson.Gson +
Constructs a Gson object with default configuration. +
GsonBuilder - Class in com.google.gson
Use this builder to construct a Gson instance when you need to set configuration + options other than the default.
GsonBuilder() - +Constructor for class com.google.gson.GsonBuilder +
Creates a GsonBuilder instance that can be used to build Gson with various configuration + settings. +
+
+

+H

+
+
has(String) - +Method in class com.google.gson.JsonObject +
Convenience method to check if a member with the specified name is present in this object. +
hashCode() - +Method in class com.google.gson.reflect.TypeToken +
Hashcode for this object. +
+
+

+I

+
+
InstanceCreator<T> - Interface in com.google.gson
This interface is implemented to create instances of a class that does not define a no-args + constructor.
isAssignableFrom(Class<?>) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given class object. +
isAssignableFrom(Type) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given Type. +
isAssignableFrom(TypeToken<?>) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given type token. +
isBoolean() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a boolean value. +
isJsonArray() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is an array or not. +
isJsonNull() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element represents a null value or not. +
isJsonObject() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is a Json object or not. +
isJsonPrimitive() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is a primitive or not. +
isNumber() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a Number. +
isString() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a String value. +
iterator() - +Method in class com.google.gson.JsonArray +
Returns an iterator to navigate the elemetns of the array. +
+
+

+J

+
+
JsonArray - Class in com.google.gson
A class representing an array type in Json.
JsonArray() - +Constructor for class com.google.gson.JsonArray +
Creates an empty JsonArray. +
JsonDeserializationContext - Interface in com.google.gson
Context for deserialization that is passed to a custom deserializer during invocation of its + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) + method.
JsonDeserializer<T> - Interface in com.google.gson
Interface representing a custom deserializer for Json.
JsonElement - Class in com.google.gson
A class representing an element of Json.
JsonElement() - +Constructor for class com.google.gson.JsonElement +
  +
JsonNull - Class in com.google.gson
A class representing a Json null value.
JsonNull() - +Constructor for class com.google.gson.JsonNull +
  +
JsonObject - Class in com.google.gson
A class representing an object type in Json.
JsonObject() - +Constructor for class com.google.gson.JsonObject +
Creates an empty JsonObject. +
JsonParseException - Exception in com.google.gson
This exception is raised if there is a serious issue that occurs during parsing of a Json + string.
JsonParseException(String) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified message. +
JsonParseException(String, Throwable) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified message and cause. +
JsonParseException(Throwable) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified cause. +
JsonPrimitive - Class in com.google.gson
A class representing a Json primitive value.
JsonPrimitive(Boolean) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a boolean value. +
JsonPrimitive(Number) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a Number. +
JsonPrimitive(String) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a String value. +
JsonPrimitive(Character) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a character. +
JsonPrimitive(char) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a character. +
JsonSerializationContext - Interface in com.google.gson
Context for serialization that is passed to a custom serializer during invocation of its + JsonSerializer.serialize(Object, Type, JsonSerializationContext) method.
JsonSerializer<T> - Interface in com.google.gson
Interface representing a custom serializer for Json.
+
+

+R

+
+
registerTypeAdapter(Type, Object) - +Method in class com.google.gson.GsonBuilder +
Configures Gson for custom serialization or deserialization. +
+
+

+S

+
+
serialize(Object) - +Method in interface com.google.gson.JsonSerializationContext +
Invokes default serialization on the specified object. +
serialize(Object, Type) - +Method in interface com.google.gson.JsonSerializationContext +
Invokes default serialization on the specified object passing the specific type information. +
serialize(T, Type, JsonSerializationContext) - +Method in interface com.google.gson.JsonSerializer +
Gson invokes this call-back method during serialization when it encounters a field of the + specified type. +
SerializedName - Annotation Type in com.google.gson.annotations
An annotation that indicates this member should be serialized to JSON with + the provided name value as its field name.
serializeNulls() - +Method in class com.google.gson.GsonBuilder +
Configure Gson to serialize null fields. +
setDateFormat(String) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to serialize Date objects according to the pattern provided. +
setDateFormat(int) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to to serialize Date objects according to the style value provided. +
setFieldNamingPolicy(FieldNamingPolicy) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization. +
setPrettyPrinting() - +Method in class com.google.gson.GsonBuilder +
Configures Gson to output Json that fits in a page for pretty printing. +
setVersion(double) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to enable versioning support. +
Since - Annotation Type in com.google.gson.annotations
An annotation that indicates the version number since a member or a type has been present.
size() - +Method in class com.google.gson.JsonArray +
Returns the number of elements in the array. +
+
+

+T

+
+
toJson(Object) - +Method in class com.google.gson.Gson +
This method serializes the specified object into its equivalent Json representation. +
toJson(Object, Type) - +Method in class com.google.gson.Gson +
This method serializes the specified object, including those of generic types, into its + equivalent Json representation. +
toJson(Object, Writer) - +Method in class com.google.gson.Gson +
This method serializes the specified object into its equivalent Json representation. +
toJson(Object, Type, Writer) - +Method in class com.google.gson.Gson +
This method serializes the specified object, including those of generic types, into its + equivalent Json representation. +
toString() - +Method in class com.google.gson.JsonElement +
Returns a String representation of this element. +
toString() - +Method in class com.google.gson.reflect.TypeToken +
Returns a string representation of this object. +
TypeToken<T> - Class in com.google.gson.reflect
Represents a generic type T.
+
+

+V

+
+
valueOf(String) - +Static method in enum com.google.gson.FieldNamingPolicy +
Returns the enum constant of this type with the specified name. +
values() - +Static method in enum com.google.gson.FieldNamingPolicy +
Returns an array containing the constants of this enum type, in +the order they are declared. +
+
+A C D E F G H I J R S T V + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/index-files/index-1.html b/gson/docs/javadocs/index-files/index-1.html new file mode 100644 index 00000000..5a9045cd --- /dev/null +++ b/gson/docs/javadocs/index-files/index-1.html @@ -0,0 +1,153 @@ + + + + + + +A-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+A

+
+
add(JsonElement) - +Method in class com.google.gson.JsonArray +
Adds the specified element to self. +
add(String, JsonElement) - +Method in class com.google.gson.JsonObject +
Adds a member, which is a name-value pair, to self. +
addAll(JsonArray) - +Method in class com.google.gson.JsonArray +
Adds all the elements of the specified array to self. +
addProperty(String, String) - +Method in class com.google.gson.JsonObject +
Convenience method to add a primitive member. +
addProperty(String, Number) - +Method in class com.google.gson.JsonObject +
Convenience method to add a primitive member. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-10.html b/gson/docs/javadocs/index-files/index-10.html new file mode 100644 index 00000000..57dc9c8a --- /dev/null +++ b/gson/docs/javadocs/index-files/index-10.html @@ -0,0 +1,141 @@ + + + + + + +R-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+R

+
+
registerTypeAdapter(Type, Object) - +Method in class com.google.gson.GsonBuilder +
Configures Gson for custom serialization or deserialization. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-11.html b/gson/docs/javadocs/index-files/index-11.html new file mode 100644 index 00000000..809189bd --- /dev/null +++ b/gson/docs/javadocs/index-files/index-11.html @@ -0,0 +1,162 @@ + + + + + + +S-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+S

+
+
serialize(Object) - +Method in interface com.google.gson.JsonSerializationContext +
Invokes default serialization on the specified object. +
serialize(Object, Type) - +Method in interface com.google.gson.JsonSerializationContext +
Invokes default serialization on the specified object passing the specific type information. +
serialize(T, Type, JsonSerializationContext) - +Method in interface com.google.gson.JsonSerializer +
Gson invokes this call-back method during serialization when it encounters a field of the + specified type. +
SerializedName - Annotation Type in com.google.gson.annotations
An annotation that indicates this member should be serialized to JSON with + the provided name value as its field name.
setFieldNamingPolicy(FieldNamingPolicy) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to apply a specific naming policy to an object's field during serialization + and deserialization. +
setPrettyPrinting() - +Method in class com.google.gson.GsonBuilder +
Configures Gson to output Json that fits in a page for pretty printing. +
setVersion(double) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to enable versioning support. +
Since - Annotation Type in com.google.gson.annotations
An annotation that indicates the version number since a member or a type has been present.
size() - +Method in class com.google.gson.JsonArray +
Returns the number of elements in the array. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-12.html b/gson/docs/javadocs/index-files/index-12.html new file mode 100644 index 00000000..42ad164f --- /dev/null +++ b/gson/docs/javadocs/index-files/index-12.html @@ -0,0 +1,151 @@ + + + + + + +T-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+T

+
+
toJson(Object) - +Method in class com.google.gson.Gson +
This method serializes the specified object into its equivalent Json representation. +
toJson(Object, Type) - +Method in class com.google.gson.Gson +
This method serializes the specified object, including those of generic types, into its + equivalent Json representation. +
toString() - +Method in class com.google.gson.JsonElement +
Returns a String representation of this element. +
toString() - +Method in class com.google.gson.reflect.TypeToken +
Returns a string representation of this object. +
TypeToken<T> - Class in com.google.gson.reflect
Represents a generic type T.
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-13.html b/gson/docs/javadocs/index-files/index-13.html new file mode 100644 index 00000000..c04fe486 --- /dev/null +++ b/gson/docs/javadocs/index-files/index-13.html @@ -0,0 +1,145 @@ + + + + + + +V-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+V

+
+
valueOf(String) - +Static method in enum com.google.gson.FieldNamingPolicy +
Returns the enum constant of this type with the specified name. +
values() - +Static method in enum com.google.gson.FieldNamingPolicy +
Returns an array containing the constants of this enum type, in +the order they're declared. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-2.html b/gson/docs/javadocs/index-files/index-2.html new file mode 100644 index 00000000..3b6f788d --- /dev/null +++ b/gson/docs/javadocs/index-files/index-2.html @@ -0,0 +1,145 @@ + + + + + + +C-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+C

+
+
com.google.gson.annotations - package com.google.gson.annotations
This package provides annotations that can be used with Gson.
com.google.gson.reflect - package com.google.gson.reflect
This package provides utility classes for finding type information for generic types.
create() - +Method in class com.google.gson.GsonBuilder +
Creates a Gson instance based on the current configuration. +
createInstance(Type) - +Method in interface com.google.gson.InstanceCreator +
Gson invokes this call-back method during deserialization to create an instance of the + specified type. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-3.html b/gson/docs/javadocs/index-files/index-3.html new file mode 100644 index 00000000..9c0ed0b9 --- /dev/null +++ b/gson/docs/javadocs/index-files/index-3.html @@ -0,0 +1,145 @@ + + + + + + +D-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+D

+
+
deserialize(JsonElement, Type) - +Method in interface com.google.gson.JsonDeserializationContext +
Invokes default deserialization on the specified object. +
deserialize(JsonElement, Type, JsonDeserializationContext) - +Method in interface com.google.gson.JsonDeserializer +
Gson invokes this call-back method during deserialization when it encounters a field of the + specified type. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-4.html b/gson/docs/javadocs/index-files/index-4.html new file mode 100644 index 00000000..5754d8e2 --- /dev/null +++ b/gson/docs/javadocs/index-files/index-4.html @@ -0,0 +1,152 @@ + + + + + + +E-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+E

+
+
entrySet() - +Method in class com.google.gson.JsonObject +
Returns a set of members of this object. +
equals(Object) - +Method in class com.google.gson.reflect.TypeToken +
Method to test equality. +
excludeFieldsWithModifiers(int...) - +Method in class com.google.gson.GsonBuilder +
Configures Gson to excludes all class fields that have the specified modifiers. +
excludeFieldsWithoutExposeAnnotation() - +Method in class com.google.gson.GsonBuilder +
Configures Gson to exclude all fields from consideration for serialization or deserialization + that do not have the Expose annotation. +
Expose - Annotation Type in com.google.gson.annotations
An annotation that indicates this member should be exposed for JSON + serialization or deserialization.
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-5.html b/gson/docs/javadocs/index-files/index-5.html new file mode 100644 index 00000000..849d4bff --- /dev/null +++ b/gson/docs/javadocs/index-files/index-5.html @@ -0,0 +1,144 @@ + + + + + + +F-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+F

+
+
FieldNamingPolicy - Enum in com.google.gson
An enumeration that defines a few standard naming conventions for JSON field names.
fromJson(String, Class<T>) - +Method in class com.google.gson.Gson +
This method deserializes the specified Json into an object of the specified class. +
fromJson(String, Type) - +Method in class com.google.gson.Gson +
This method deserializes the specified Json into an object of the specified type. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-6.html b/gson/docs/javadocs/index-files/index-6.html new file mode 100644 index 00000000..96724f56 --- /dev/null +++ b/gson/docs/javadocs/index-files/index-6.html @@ -0,0 +1,254 @@ + + + + + + +G-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+G

+
+
get(int) - +Method in class com.google.gson.JsonArray +
Returns the ith element of the array. +
get(String) - +Method in class com.google.gson.JsonObject +
Returns the member with the specified name. +
get(Type) - +Static method in class com.google.gson.reflect.TypeToken +
Gets type token for the given Type instance. +
get(Class<T>) - +Static method in class com.google.gson.reflect.TypeToken +
Gets type token for the given Class instance. +
getAsBoolean() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a boolean if it contains a single element. +
getAsBoolean() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a boolean value. +
getAsBoolean() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a boolean value. +
getAsDouble() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a double if it contains a single element. +
getAsDouble() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive double value. +
getAsDouble() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive double. +
getAsFloat() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a float if it contains a single element. +
getAsFloat() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive float value. +
getAsFloat() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a float. +
getAsInt() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as an integer if it contains a single element. +
getAsInt() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive integer value. +
getAsInt() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive integer. +
getAsJsonArray() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonArray. +
getAsJsonArray(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonArray. +
getAsJsonObject() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonObject. +
getAsJsonObject(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonObject. +
getAsJsonPrimitive() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a JsonPrimitive. +
getAsJsonPrimitive(String) - +Method in class com.google.gson.JsonObject +
Convenience method to get the specified member as a JsonPrimitive element. +
getAsLong() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a long if it contains a single element. +
getAsLong() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive long value. +
getAsLong() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive long. +
getAsNumber() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a Number if it contains a single element. +
getAsNumber() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a Number. +
getAsNumber() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a Number. +
getAsShort() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a primitive short if it contains a single element. +
getAsShort() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a primitive short value. +
getAsShort() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a primitive short. +
getAsString() - +Method in class com.google.gson.JsonArray +
convenience method to get this array as a String if it contains a single element. +
getAsString() - +Method in class com.google.gson.JsonElement +
convenience method to get this element as a string value. +
getAsString() - +Method in class com.google.gson.JsonPrimitive +
convenience method to get this element as a String. +
getRawType() - +Method in class com.google.gson.reflect.TypeToken +
Gets the raw type. +
getType() - +Method in class com.google.gson.reflect.TypeToken +
Gets underlying Type instance. +
Gson - Class in com.google.gson
This is the main class for using Gson.
Gson() - +Constructor for class com.google.gson.Gson +
Constructs a Gson object with default configuration. +
GsonBuilder - Class in com.google.gson
Use this builder to construct a Gson instance when you need to set configuration + options other than the default.
GsonBuilder() - +Constructor for class com.google.gson.GsonBuilder +
Creates a GsonBuilder instance that can be used to build Gson with various configuration + settings. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-7.html b/gson/docs/javadocs/index-files/index-7.html new file mode 100644 index 00000000..e50dc9eb --- /dev/null +++ b/gson/docs/javadocs/index-files/index-7.html @@ -0,0 +1,144 @@ + + + + + + +H-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+H

+
+
has(String) - +Method in class com.google.gson.JsonObject +
Convenience method to check if a member with the specified name is present in this object. +
hashCode() - +Method in class com.google.gson.reflect.TypeToken +
Hashcode for this object. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-8.html b/gson/docs/javadocs/index-files/index-8.html new file mode 100644 index 00000000..52003a25 --- /dev/null +++ b/gson/docs/javadocs/index-files/index-8.html @@ -0,0 +1,169 @@ + + + + + + +I-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+I

+
+
InstanceCreator<T> - Interface in com.google.gson
This interface is implemented to create instances of a class that does not define a no-args + constructor.
isAssignableFrom(Class<?>) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given class object. +
isAssignableFrom(Type) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given Type. +
isAssignableFrom(TypeToken<?>) - +Method in class com.google.gson.reflect.TypeToken +
Check if this type is assignable from the given type token. +
isBoolean() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a boolean value. +
isJsonArray() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is an array or not. +
isJsonObject() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is a Json object or not. +
isJsonPrimitive() - +Method in class com.google.gson.JsonElement +
provides check for verifying if this element is a primitive or not. +
isNumber() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a Number. +
isString() - +Method in class com.google.gson.JsonPrimitive +
Check whether this primitive contains a String value. +
iterator() - +Method in class com.google.gson.JsonArray +
Returns an iterator to navigate the elemetns of the array. +
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index-files/index-9.html b/gson/docs/javadocs/index-files/index-9.html new file mode 100644 index 00000000..d083414e --- /dev/null +++ b/gson/docs/javadocs/index-files/index-9.html @@ -0,0 +1,175 @@ + + + + + + +J-Index + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+

+J

+
+
JsonArray - Class in com.google.gson
A class representing an array type in Json.
JsonArray() - +Constructor for class com.google.gson.JsonArray +
Creates an empty JsonArray. +
JsonDeserializationContext - Interface in com.google.gson
Context for deserialization that is passed to a custom deserializer during invocation of its + JsonDeserializer.deserialize(JsonElement, Type, JsonDeserializationContext) + method.
JsonDeserializer<T> - Interface in com.google.gson
Interface representing a custom deserializer for Json.
JsonElement - Class in com.google.gson
A class representing an element of Json.
JsonElement() - +Constructor for class com.google.gson.JsonElement +
This is an abstract class and can not be instantiated directly. +
JsonObject - Class in com.google.gson
A class representing an object type in Json.
JsonObject() - +Constructor for class com.google.gson.JsonObject +
Creates an empty JsonObject. +
JsonParseException - Exception in com.google.gson
This exception is raised if there is a serious issue that occurs during parsing of a Json + string.
JsonParseException(String) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified message. +
JsonParseException(String, Throwable) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified message and cause. +
JsonParseException(Throwable) - +Constructor for exception com.google.gson.JsonParseException +
Creates exception with the specified cause. +
JsonPrimitive - Class in com.google.gson
A class representing a Json primitive value.
JsonPrimitive(Boolean) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a boolean value. +
JsonPrimitive(Number) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a Number. +
JsonPrimitive(String) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a String value. +
JsonPrimitive(Character) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a character. +
JsonPrimitive(char) - +Constructor for class com.google.gson.JsonPrimitive +
Create a primitive containing a character. +
JsonSerializationContext - Interface in com.google.gson
Context for serialization that is passed to a custom serializer during invocation of its + JsonSerializer.serialize(Object, Type, JsonSerializationContext) method
JsonSerializer<T> - Interface in com.google.gson
Interface representing a custom serializer for Json.
+
+ + + + + + + + + + + + + + + +
+ +
+ + + +A C D E F G H I J R S T V
+ + + diff --git a/gson/docs/javadocs/index.html b/gson/docs/javadocs/index.html new file mode 100644 index 00000000..af8169bb --- /dev/null +++ b/gson/docs/javadocs/index.html @@ -0,0 +1,40 @@ + + + + + + + +Gson 1.2 API + + + + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="overview-summary.html">Non-frame version.</A> + + + diff --git a/gson/docs/javadocs/overview-frame.html b/gson/docs/javadocs/overview-frame.html new file mode 100644 index 00000000..d688d1c6 --- /dev/null +++ b/gson/docs/javadocs/overview-frame.html @@ -0,0 +1,47 @@ + + + + + + + +Overview List (Gson 1.2 API) + + + + + + + + + + + + + + + +
+
+ + + + + +
All Classes +

+ +Packages +
+com.google.gson +
+com.google.gson.annotations +
+com.google.gson.reflect +
+

+ +

+  + + diff --git a/gson/docs/javadocs/overview-summary.html b/gson/docs/javadocs/overview-summary.html new file mode 100644 index 00000000..75526c75 --- /dev/null +++ b/gson/docs/javadocs/overview-summary.html @@ -0,0 +1,166 @@ + + + + + + + +Overview (Gson 1.2 API) + + + + + + + + + + + + +


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Gson 1.2 API +

+
+ + + + + + + + + + + + + + + + + +
+Packages
com.google.gsonThis package provides the Gson class to convert Json to Java and + vice-versa.
com.google.gson.annotationsThis package provides annotations that can be used with Gson.
com.google.gson.reflectThis package provides utility classes for finding type information for generic types.
+ +


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/overview-tree.html b/gson/docs/javadocs/overview-tree.html new file mode 100644 index 00000000..e5edb4a0 --- /dev/null +++ b/gson/docs/javadocs/overview-tree.html @@ -0,0 +1,186 @@ + + + + + + + +Class Hierarchy (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
com.google.gson, com.google.gson.annotations, com.google.gson.reflect
+
+

+Class Hierarchy +

+ +

+Interface Hierarchy +

+ +

+Annotation Type Hierarchy +

+ +

+Enum Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/package-list b/gson/docs/javadocs/package-list new file mode 100644 index 00000000..a83dff87 --- /dev/null +++ b/gson/docs/javadocs/package-list @@ -0,0 +1,3 @@ +com.google.gson +com.google.gson.annotations +com.google.gson.reflect diff --git a/gson/docs/javadocs/resources/inherit.gif b/gson/docs/javadocs/resources/inherit.gif new file mode 100644 index 0000000000000000000000000000000000000000..c814867a13deb0ca7ea2156c6ca1d5a03372af7e GIT binary patch literal 57 zcmZ?wbhEHbIIT!9-C*e{wE9>Kx3D)-;0v)C; KYxQGgum%9JOA&7X literal 0 HcmV?d00001 diff --git a/gson/docs/javadocs/serialized-form.html b/gson/docs/javadocs/serialized-form.html new file mode 100644 index 00000000..44affcd9 --- /dev/null +++ b/gson/docs/javadocs/serialized-form.html @@ -0,0 +1,167 @@ + + + + + + + +Serialized Form (Gson 1.2 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Serialized Form

+
+
+ + + + + +
+Package com.google.gson
+ +

+ + + + + +
+Class com.google.gson.JsonParseException extends RuntimeException implements Serializable
+ +

+serialVersionUID: -4086729973971783390L + +

+ +

+


+ + + + + + + + + + + + + + + +
+ +
+ + + +
+Copyright © 2008. All Rights Reserved. + + diff --git a/gson/docs/javadocs/stylesheet.css b/gson/docs/javadocs/stylesheet.css new file mode 100644 index 00000000..6ea9e516 --- /dev/null +++ b/gson/docs/javadocs/stylesheet.css @@ -0,0 +1,29 @@ +/* Javadoc style sheet */ + +/* Define colors, fonts and other style attributes here to override the defaults */ + +/* Page background color */ +body { background-color: #FFFFFF; color:#000000 } + +/* Headings */ +h1 { font-size: 145% } + +/* Table colors */ +.TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */ +.TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */ +.TableRowColor { background: #FFFFFF; color:#000000 } /* White */ + +/* Font used in left-hand frame lists */ +.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } +.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 } + +/* Navigation bar fonts and colors */ +.NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */ +.NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */ +.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;} +.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;} + +.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} +.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000} + diff --git a/gson/lib/gson-cleanup-styles.xml b/gson/lib/gson-cleanup-styles.xml new file mode 100644 index 00000000..9e20cb96 --- /dev/null +++ b/gson/lib/gson-cleanup-styles.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gson/lib/gson-formatting-styles.xml b/gson/lib/gson-formatting-styles.xml new file mode 100644 index 00000000..177e9997 --- /dev/null +++ b/gson/lib/gson-formatting-styles.xml @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gson/pom.xml b/gson/pom.xml new file mode 100644 index 00000000..9662c5c8 --- /dev/null +++ b/gson/pom.xml @@ -0,0 +1,213 @@ + + 4.0.0 + com.google.code.gson + gson + jar + 1.2 + 2008 + gson + http://code.google.com/p/google-gson/ + Google Gson library + + + local.repo + file repository to svn + file://${basedir}/../mavenrepo + + + + + gson + http://google-gson.googlecode.com/svn/mavenrepo/ + + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + scm:svn:http://google-gson.googlecode.com/svn/trunk + scm:svn:https://google-gson.googlecode.com/svn/trunk + http://google-gson.codegoogle.com/svn/trunk/ + + + Google Code Issue Tracking + http://code.google.com/p/google-gson/issues/list + + + + junit + junit + 3.8.2 + test + + + + package + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-jar-plugin + + + package + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar + + + + + + org.apache.maven.plugins + maven-eclipse-plugin + + true + true + + ../eclipse-ws/ + + + file:///${basedir}/lib/gson-formatting-styles.xml + + + + + + org.apache.maven.plugins + maven-jxr-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + http://java.sun.com/j2se/1.5.0/docs/api/ + + Gson ${project.version} API + Gson ${project.version} API + public + + + + org.apache.maven.plugins + maven-pmd-plugin + + 1.5 + + /rulesets/basic.xml + /rulesets/imports.xml + /rulesets/unusedcode.xml + /rulesets/finalizers.xml + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + config/maven_checks.xml + + + + org.codehaus.mojo + taglist-maven-plugin + + + TODO + @todo + FIXME + XXX + + + + + org.codehaus.mojo + cobertura-maven-plugin + + + clean + + clean + + + + + + org.apache.maven.plugins + maven-release-plugin + + -DenableCiProfile=true + + + + maven-assembly-plugin + 2.2-beta-2 + + src/main/resources/assembly-descriptor.xml + google-gson-${version} + target/dist + target/assembly/work + + + + + + + Inderjeet Singh + Google Inc. + + + Joel Leitch + Google Inc. + + + diff --git a/gson/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java b/gson/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java new file mode 100644 index 00000000..33457ef8 --- /dev/null +++ b/gson/src/main/java/com/google/gson/CamelCaseSeparatorNamingPolicy.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * Converts the field name that uses camel-case define word separation into separate words that + * are separated by the provided {@code separatorString}. + * + *

The following is an example:

+ *
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * CamelCaseSeparatorNamingPolicy policy = new CamelCaseSeparatorNamingPolicy("_");
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integer_Field".equals(translatedFieldName));
+ * 
+ * + * @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 purely whitespace. + */ + public CamelCaseSeparatorNamingPolicy(String separatorString) { + Preconditions.checkNotNull(separatorString); + Preconditions.checkArgument(!"".equals(separatorString.trim())); + this.separatorString = separatorString; + } + + @Override + protected String translateName(String target, Type fieldType, 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(); + } +} diff --git a/gson/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java b/gson/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java new file mode 100644 index 00000000..652168c7 --- /dev/null +++ b/gson/src/main/java/com/google/gson/CompositionFieldNamingPolicy.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * 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, Annotation[] annotations) { + for (RecursiveFieldNamingPolicy policy : fieldPolicies) { + target = policy.translateName(target, fieldType, annotations); + } + return target; + } +} diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java new file mode 100644 index 00000000..8a2df058 --- /dev/null +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -0,0 +1,415 @@ +/* + * 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.google.gson; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; + +/** + * List of all the default type adapters ({@link JsonSerializer}s, {@link JsonDeserializer}s, + * and {@link InstanceCreator}s. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class DefaultTypeAdapters { + + private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER = + new DefaultDateTypeAdapter(DateFormat.DEFAULT); + @SuppressWarnings("unchecked") + private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter(); + private static final UrlTypeAdapter URL_TYPE_ADAPTER = new UrlTypeAdapter(); + private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter(); + private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter(); + private static final MapTypeAdapter MAP_TYPE_ADAPTER = new MapTypeAdapter(); + private static final BigDecimalTypeAdapter BIG_DECIMAL_TYPE_ADAPTER = new BigDecimalTypeAdapter(); + private static final BigIntegerTypeAdapter BIG_INTEGER_TYPE_ADAPTER = new BigIntegerTypeAdapter(); + + private static final BooleanCreator BOOLEAN_CREATOR = new BooleanCreator(); + private static final ByteCreator BYTE_CREATOR = new ByteCreator(); + private static final CharacterCreator CHARACTER_CREATOR = new CharacterCreator(); + private static final DoubleCreator DOUBLE_CREATOR = new DoubleCreator(); + private static final FloatCreator FLOAT_CREATOR = new FloatCreator(); + private static final IntegerCreator INTEGER_CREATOR = new IntegerCreator(); + private static final LongCreator LONG_CREATOR = new LongCreator(); + private static final ShortCreator SHORT_CREATOR = new ShortCreator(); + private static final LinkedListCreator LINKED_LIST_CREATOR = new LinkedListCreator(); + private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator(); + + // The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS + // must be defined after the constants for the type adapters. Otherwise, the type adapter + // constants will appear as nulls. + static final ParameterizedTypeHandlerMap> DEFAULT_SERIALIZERS = + getDefaultSerializers(); + static final ParameterizedTypeHandlerMap> DEFAULT_DESERIALIZERS = + getDefaultDeserializers(); + static final ParameterizedTypeHandlerMap> DEFAULT_INSTANCE_CREATORS = + getDefaultInstanceCreators(); + + private static ParameterizedTypeHandlerMap> getDefaultSerializers() { + ParameterizedTypeHandlerMap> map = + new ParameterizedTypeHandlerMap>(); + + map.register(Enum.class, wrapSerializer(ENUM_TYPE_ADAPTER)); + map.register(URL.class, wrapSerializer(URL_TYPE_ADAPTER)); + map.register(URI.class, wrapSerializer(URI_TYPE_ADAPTER)); + map.register(Locale.class, wrapSerializer(LOCALE_TYPE_ADAPTER)); + map.register(Map.class, wrapSerializer(MAP_TYPE_ADAPTER)); + map.register(Date.class, wrapSerializer(DATE_TYPE_ADAPTER)); + map.register(BigDecimal.class, wrapSerializer(BIG_DECIMAL_TYPE_ADAPTER)); + map.register(BigInteger.class, wrapSerializer(BIG_INTEGER_TYPE_ADAPTER)); + map.makeUnmodifiable(); + return map; + } + + private static ParameterizedTypeHandlerMap> getDefaultDeserializers() { + ParameterizedTypeHandlerMap> map = + new ParameterizedTypeHandlerMap>(); + map.register(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER)); + map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER)); + map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER)); + map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER)); + map.register(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER)); + map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER)); + map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER)); + map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER)); + map.makeUnmodifiable(); + return map; + } + + private static ParameterizedTypeHandlerMap> getDefaultInstanceCreators() { + ParameterizedTypeHandlerMap> map = + new ParameterizedTypeHandlerMap>(); + map.register(Enum.class, ENUM_TYPE_ADAPTER); + map.register(URL.class, URL_TYPE_ADAPTER); + map.register(Locale.class, LOCALE_TYPE_ADAPTER); + map.register(Map.class, MAP_TYPE_ADAPTER); + map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER); + map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER); + + // Add primitive instance creators + map.register(Boolean.class, BOOLEAN_CREATOR); + map.register(boolean.class, BOOLEAN_CREATOR); + map.register(Byte.class, BYTE_CREATOR); + map.register(byte.class, BYTE_CREATOR); + map.register(Character.class, CHARACTER_CREATOR); + map.register(char.class, CHARACTER_CREATOR); + map.register(Double.class, DOUBLE_CREATOR); + map.register(double.class, DOUBLE_CREATOR); + map.register(Float.class, FLOAT_CREATOR); + map.register(float.class, FLOAT_CREATOR); + map.register(Integer.class, INTEGER_CREATOR); + map.register(int.class, INTEGER_CREATOR); + map.register(Long.class, LONG_CREATOR); + map.register(long.class, LONG_CREATOR); + map.register(Short.class, SHORT_CREATOR); + map.register(short.class, SHORT_CREATOR); + + map.register(Collection.class, LINKED_LIST_CREATOR); + map.register(List.class, LINKED_LIST_CREATOR); + map.register(Queue.class, LINKED_LIST_CREATOR); + + map.register(Set.class, TREE_SET_CREATOR); + map.register(SortedSet.class, TREE_SET_CREATOR); + map.makeUnmodifiable(); + return map; + } + + @SuppressWarnings("unchecked") + private static JsonSerializer wrapSerializer(JsonSerializer serializer) { + return new JsonSerializerExceptionWrapper(serializer); + } + + @SuppressWarnings("unchecked") + private static JsonDeserializer wrapDeserializer(JsonDeserializer deserializer) { + return new JsonDeserializerExceptionWrapper(deserializer); + } + + static class DefaultDateTypeAdapter implements JsonSerializer, JsonDeserializer { + + private final DateFormat format; + + public DefaultDateTypeAdapter(String datePattern) { + this.format = new SimpleDateFormat(datePattern); + } + + public DefaultDateTypeAdapter(int style) { + this.format = DateFormat.getDateInstance(style); + } + + public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) { + String dateFormatAsString = format.format(src); + return new JsonPrimitive(dateFormatAsString); + } + + public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + if (!(json instanceof JsonPrimitive)) { + throw new JsonParseException("The date should be a string value"); + } + + try { + return format.parse(json.getAsString()); + } catch (ParseException e) { + throw new JsonParseException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static class EnumTypeAdapter> implements JsonSerializer, + JsonDeserializer, InstanceCreator> { + public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.name()); + } + @SuppressWarnings("cast") + public T deserialize(JsonElement json, Type classOfT, JsonDeserializationContext context) + throws JsonParseException { + return (T) Enum.valueOf((Class)classOfT, json.getAsString()); + } + public Enum createInstance(Type type) { + Class> enumClass = (Class>) type; + try { + Method valuesMethod = enumClass.getMethod("values"); + Enum[] enums = (Enum[]) valuesMethod.invoke(null); + return enums[0]; + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + private static class UrlTypeAdapter implements JsonSerializer, JsonDeserializer, + InstanceCreator { + public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toExternalForm()); + } + public URL deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + try { + return new URL(json.getAsString()); + } catch (MalformedURLException e) { + throw new JsonParseException(e); + } + } + public URL createInstance(Type type) { + try { + return new URL("http://google.com/"); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + } + + private static class UriTypeAdapter implements JsonSerializer, JsonDeserializer { + public JsonElement serialize(URI src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toASCIIString()); + } + public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + try { + return new URI(json.getAsString()); + } catch (URISyntaxException e) { + throw new JsonParseException(e); + } + } + } + + private static class LocaleTypeAdapter implements JsonSerializer, + JsonDeserializer, InstanceCreator { + public JsonElement serialize(Locale src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toString()); + } + public Locale deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + String locale = json.getAsString(); + StringTokenizer tokenizer = new StringTokenizer(locale, "_"); + String language = null; + String country = null; + String variant = null; + if (tokenizer.hasMoreElements()) { + language = tokenizer.nextToken(); + } + if (tokenizer.hasMoreElements()) { + country = tokenizer.nextToken(); + } + if (tokenizer.hasMoreElements()) { + variant = tokenizer.nextToken(); + } + if (country == null && variant == null) { + return new Locale(language); + } else if (variant == null) { + return new Locale(language, country); + } else { + return new Locale(language, country, variant); + } + } + public Locale createInstance(Type type) { + return new Locale("en_US"); + } + } + + @SuppressWarnings("unchecked") + static class MapTypeAdapter implements JsonSerializer, JsonDeserializer, + InstanceCreator { + public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject map = new JsonObject(); + Type childType = new TypeInfoMap(typeOfSrc).getValueType(); + for (Iterator iterator = src.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry entry = (Map.Entry) iterator.next(); + JsonElement valueElement = context.serialize(entry.getValue(), childType); + map.add(entry.getKey().toString(), valueElement); + } + return map; + } + public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + // Using linked hash map to preserve order in which elements are entered + Map map = new LinkedHashMap(); + Type childType = new TypeInfoMap(typeOfT).getValueType(); + for (Map.Entry entry : json.getAsJsonObject().entrySet()) { + Object value = context.deserialize(entry.getValue(), childType); + map.put(entry.getKey(), value); + } + return map; + } + public Map createInstance(Type type) { + return new LinkedHashMap(); + } + } + + private static class BigDecimalTypeAdapter implements JsonSerializer, + JsonDeserializer, InstanceCreator { + + public JsonElement serialize(BigDecimal src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src); + } + + public BigDecimal deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + return json.getAsBigDecimal(); + } + + public BigDecimal createInstance(Type type) { + return new BigDecimal(0); + } + } + + private static class BigIntegerTypeAdapter implements JsonSerializer, + JsonDeserializer, InstanceCreator { + + public JsonElement serialize(BigInteger src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src); + } + + public BigInteger deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + return json.getAsBigInteger(); + } + + public BigInteger createInstance(Type type) { + return new BigInteger("0"); + } + } + + private static class LongCreator implements InstanceCreator { + public Long createInstance(Type type) { + return new Long(0L); + } + } + + private static class IntegerCreator implements InstanceCreator { + public Integer createInstance(Type type) { + return new Integer(0); + } + } + + private static class ShortCreator implements InstanceCreator { + public Short createInstance(Type type) { + return new Short((short) 0); + } + } + + private static class ByteCreator implements InstanceCreator { + public Byte createInstance(Type type) { + return new Byte((byte) 0); + } + } + + private static class FloatCreator implements InstanceCreator { + public Float createInstance(Type type) { + return new Float(0F); + } + } + + private static class DoubleCreator implements InstanceCreator { + public Double createInstance(Type type) { + return new Double(0D); + } + } + + private static class CharacterCreator implements InstanceCreator { + public Character createInstance(Type type) { + return new Character((char) 0); + } + } + + private static class BooleanCreator implements InstanceCreator { + public Boolean createInstance(Type type) { + return new Boolean(false); + } + } + + private static class LinkedListCreator implements InstanceCreator> { + public LinkedList createInstance(Type type) { + return new LinkedList(); + } + } + + private static class TreeSetCreator implements InstanceCreator> { + public TreeSet createInstance(Type type) { + return new TreeSet(); + } + } +} diff --git a/gson/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java b/gson/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java new file mode 100644 index 00000000..74be57b6 --- /dev/null +++ b/gson/src/main/java/com/google/gson/DelegatingJsonElementVisitor.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * 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". + * + *

The following is an example use case: + * + *

+ * 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());
+ * 

+ * + * @author Joel Leitch + */ +class DelegatingJsonElementVisitor implements JsonElementVisitor { + private final JsonElementVisitor delegate; + + protected DelegatingJsonElementVisitor(JsonElementVisitor delegate) { + Preconditions.checkNotNull(delegate); + this.delegate = delegate; + } + + public void endArray(JsonArray array) { + delegate.endArray(array); + } + + public void endObject(JsonObject object) { + delegate.endObject(object); + } + + public void startArray(JsonArray array) { + delegate.startArray(array); + } + + public void startObject(JsonObject object) { + delegate.startObject(object); + } + + public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) { + delegate.visitArrayMember(parent, member, isFirst); + } + + public void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) { + delegate.visitArrayMember(parent, member, isFirst); + } + + public void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) { + delegate.visitArrayMember(parent, member, isFirst); + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonPrimitive member, boolean isFirst) { + delegate.visitObjectMember(parent, memberName, member, isFirst); + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonArray member, boolean isFirst) { + delegate.visitObjectMember(parent, memberName, member, isFirst); + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonObject member, boolean isFirst) { + delegate.visitObjectMember(parent, memberName, member, isFirst); + } + + public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) { + delegate.visitNullObjectMember(parent, memberName, isFirst); + } + + public void visitPrimitive(JsonPrimitive primitive) { + delegate.visitPrimitive(primitive); + } + + public void visitNull() { + delegate.visitNull(); + } + + public void visitNullArrayMember(JsonArray parent, boolean isFirst) { + delegate.visitNullArrayMember(parent, isFirst); + } +} diff --git a/gson/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java b/gson/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java new file mode 100644 index 00000000..76799a63 --- /dev/null +++ b/gson/src/main/java/com/google/gson/DisjunctionExclusionStrategy.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.LinkedList; + +/** + * 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 strategies; + + public DisjunctionExclusionStrategy(ExclusionStrategy... strategies) { + Preconditions.checkNotNull(strategies); + Preconditions.checkArgument(strategies.length > 0); + + this.strategies = new LinkedList(); + for (ExclusionStrategy strategy : strategies) { + this.strategies.add(strategy); + } + } + + public DisjunctionExclusionStrategy(Collection strategies) { + Preconditions.checkNotNull(strategies); + Preconditions.checkArgument(!strategies.isEmpty()); + + this.strategies = new LinkedList(); + this.strategies.addAll(strategies); + } + + public boolean shouldSkipField(Field 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; + } +} diff --git a/gson/src/main/java/com/google/gson/Escaper.java b/gson/src/main/java/com/google/gson/Escaper.java new file mode 100644 index 00000000..83aef526 --- /dev/null +++ b/gson/src/main/java/com/google/gson/Escaper.java @@ -0,0 +1,146 @@ +/* + * 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.google.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. + * + *

This class contains a single method to escape a passed in string value: + *

+ *   String jsonStringValue = "beforeQuote\"afterQuote";
+ *   String escapedValue = Escaper.escapeJsonString(jsonStringValue);
+ * 

+ * + * @author Inderjeet Singh + * @author Joel Leitch + */ +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 JS_ESCAPE_CHARS; + + static { + Set tmpSet = new HashSet(); + tmpSet.add('\u0000'); + tmpSet.add('\r'); + tmpSet.add('\n'); + tmpSet.add('\u2028'); + tmpSet.add('\u2029'); + tmpSet.add('\u0085'); + tmpSet.add('\''); + tmpSet.add('"'); + tmpSet.add('<'); + tmpSet.add('>'); + tmpSet.add('&'); + tmpSet.add('='); + tmpSet.add('\\'); + JS_ESCAPE_CHARS = Collections.unmodifiableSet(tmpSet); + } + + public static String escapeJsonString(CharSequence plainText) { + StringBuffer escapedString = new StringBuffer(plainText.length() + 20); + try { + escapeJsonString(plainText, escapedString); + } catch (IOException e) { + throw new RuntimeException(e); + } + return escapedString.toString(); + } + + private static void escapeJsonString(CharSequence plainText, StringBuffer out) throws IOException { + int pos = 0; // Index just past the last char in plainText written to out. + int len = plainText.length(); + for (int charCount, i = 0; i < len; i += charCount) { + int codePoint = Character.codePointAt(plainText, i); + charCount = Character.charCount(codePoint); + + if (!((codePoint < 0x20 || codePoint >= 0x7f) + || 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('\\').append((char) codePoint); + break; + case '\'': + out.append((char) codePoint); + break; + default: + appendHexJavaScriptRepresentation(codePoint, out); + break; + } + } + out.append(plainText, pos, len); + } + + 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]); + } + + private static boolean mustEscapeCharInJsString(int codepoint) { + if (!Character.isSupplementaryCodePoint(codepoint)) { + return JS_ESCAPE_CHARS.contains((char)codepoint); + } else { + return false; + } + } +} diff --git a/gson/src/main/java/com/google/gson/ExclusionStrategy.java b/gson/src/main/java/com/google/gson/ExclusionStrategy.java new file mode 100644 index 00000000..51156463 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ExclusionStrategy.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Field; + +/** + * A strategy definition that is used by the {@link ObjectNavigator} to + * determine whether or not the field of the object should be ignored during + * navigation. + * + * As well, for now this class is also responsible for excluding entire + * classes. This is somewhat a mixing of concerns for this object, but + * it will suffice for now. We can always break it down into two + * different strategies later. + * + * @author Joel Leitch + */ +interface ExclusionStrategy { + + /** + * @param f the field object that is under test + * @return true if the field should be ignored otherwise false + */ + public boolean shouldSkipField(Field 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); +} diff --git a/gson/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java b/gson/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java new file mode 100644 index 00000000..19cff662 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ExposeAnnotationBasedExclusionStrategy.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.annotations.Expose; + +import java.lang.reflect.Field; + +/** + * Excludes fields that do not have the {@link Expose} annotation + * + * @author Inderjeet Singh + */ +class ExposeAnnotationBasedExclusionStrategy implements ExclusionStrategy { + + public boolean shouldSkipClass(Class clazz) { + return false; + } + + public boolean shouldSkipField(Field f) { + return f.getAnnotation(Expose.class) == null; + } +} diff --git a/gson/src/main/java/com/google/gson/FieldNamingPolicy.java b/gson/src/main/java/com/google/gson/FieldNamingPolicy.java new file mode 100644 index 00000000..792c5232 --- /dev/null +++ b/gson/src/main/java/com/google/gson/FieldNamingPolicy.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * An enumeration that defines a few standard naming conventions for JSON field names. + * This enumeration should be used in conjunction with {@link com.google.gson.GsonBuilder} + * to configure a {@link com.google.gson.Gson} instance to properly translate Java field + * names into the desired JSON field names. + * + * @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. + * + *

Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":

+ *
    + *
  • someFieldName ---> SomeFieldName
  • + *
  • _someFieldName ---> _SomeFieldName
  • + *
+ */ + UPPER_CAMEL_CASE(new ModifyFirstLetterNamingPolicy( + ModifyFirstLetterNamingPolicy.LetterModifier.UPPER)), + + /** + * 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 (_). + * + *

Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":

+ *
    + *
  • someFieldName ---> some_field_name
  • + *
  • _someFieldName ---> _some_field_name
  • + *
  • aStringField ---> a_string_field
  • + *
  • aURL ---> a_u_r_l
  • + *
+ */ + LOWER_CASE_WITH_UNDERSCORES(new LowerCamelCaseSeparatorNamingPolicy("_")); + + private final FieldNamingStrategy namingPolicy; + + private FieldNamingPolicy(FieldNamingStrategy namingPolicy) { + this.namingPolicy = namingPolicy; + } + + FieldNamingStrategy getFieldNamingPolicy() { + return namingPolicy; + } +} diff --git a/gson/src/main/java/com/google/gson/FieldNamingStrategy.java b/gson/src/main/java/com/google/gson/FieldNamingStrategy.java new file mode 100644 index 00000000..59bf3325 --- /dev/null +++ b/gson/src/main/java/com/google/gson/FieldNamingStrategy.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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 Joel Leitch + */ +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. + */ + public String translateName(Field f); +} diff --git a/gson/src/main/java/com/google/gson/GenericArrayTypeImpl.java b/gson/src/main/java/com/google/gson/GenericArrayTypeImpl.java new file mode 100644 index 00000000..0a886441 --- /dev/null +++ b/gson/src/main/java/com/google/gson/GenericArrayTypeImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Type; + +/** + * An simple pojo-like immutable instance of the {@link GenericArrayType}. This object provides + * us the ability to create reflective types on demand. This object is required for support + * object similar to the one defined below: + *
+ * class Foo {
+ *   private final List[] arrayOfListT;
+ *
+ *   Foo(List[] arrayList) {
+ *     this.arrayOfListT = arrayList;
+ *   }
+ * }
+ * 
+ * + *

During parsing or serialization, we know the real variable type parameter {@code T}, + * so we can build a new {@code GenericTypeArray} with the "real" type parameters and + * pass that object along instead. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class GenericArrayTypeImpl implements GenericArrayType { + + private final Type genericComponentType; + + public GenericArrayTypeImpl(Type genericComponentType) { + this.genericComponentType = genericComponentType; + } + + public Type getGenericComponentType() { + return genericComponentType; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof GenericArrayType)) { + return false; + } else { + GenericArrayType that = (GenericArrayType) o; + Type thatComponentType = that.getGenericComponentType(); + return genericComponentType == null ? + thatComponentType == null : genericComponentType.equals(thatComponentType); + } + } + + @Override + public int hashCode() { + return (genericComponentType == null) ? 0 : genericComponentType.hashCode(); + } +} diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java new file mode 100644 index 00000000..8d819fdb --- /dev/null +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -0,0 +1,404 @@ +/* + * 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.google.gson; + +import java.io.IOException; +import java.io.PrintWriter; +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; +import java.util.logging.Logger; + +/** + * 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. + * + *

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.

+ * + *

Here is an example of how Gson is used for a simple Class: + * + *

+ * 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
+ * 

+ * + *

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}: + * + *

+ * Type listType = new TypeToken>() {}.getType();
+ * List target = new LinkedList();
+ * target.add("blah");
+ *
+ * Gson gson = new Gson();
+ * String json = gson.toJson(target, listType);
+ * List target2 = gson.fromJson(json, listType);
+ * 

+ * + *

See the Gson User Guide + * for a more complete set of examples.

+ * + * @see com.google.gson.reflect.TypeToken + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public final class Gson { + + //TODO(inder): get rid of all the registerXXX methods and take all such parameters in the + // constructor instead. At the minimum, mark those methods private. + + private static final String NULL_STRING = "null"; + // Default instances of plug-ins + static final TypeAdapter DEFAULT_TYPE_ADAPTER = + new TypeAdapterNotRequired(new PrimitiveTypeAdapter()); + static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY = + new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC }); + static final JsonFormatter DEFAULT_JSON_FORMATTER = new JsonCompactFormatter(); + static final FieldNamingStrategy DEFAULT_NAMING_POLICY = + new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy()); + + static final Logger logger = Logger.getLogger(Gson.class.getName()); + + private final ObjectNavigatorFactory navigatorFactory; + private final MappedObjectConstructor objectConstructor; + private final TypeAdapter typeAdapter; + + /** Map containing Type or Class objects as keys */ + private final ParameterizedTypeHandlerMap> serializers; + + /** Map containing Type or Class objects as keys */ + private final ParameterizedTypeHandlerMap> deserializers; + + private final JsonFormatter formatter; + private final boolean serializeNulls; + + /** + * Constructs a Gson object with default configuration. The default configuration has the + * following settings: + *
    + *
  • The JSON generated by toJson methods is in compact representation. This + * means that all the unneeded white-space is removed. You can change this behavior with + * {@link GsonBuilder#setPrettyPrinting()}.
  • + *
  • 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()}.
  • + *
  • 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)}.
  • + *
  • The default Date format is same as {@link java.text.DateFormat#DEFAULT}. You can change + * this by invoking {@link GsonBuilder#setDateFormat(int)} or + * {@link GsonBuilder#setDateFormat(String)}.
  • + *
  • By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation. + * You can enable Gson to serialize/deserialize only those fields marked with this annotation + * through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}.
  • + *
  • By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You + * can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.
  • + *
  • The default field naming policy for the output Json is same as in Java. So, a Java class + * field versionNumber will be output as "versionNumber@quot; 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)}.
  • + *
  • By default, Gson excludes transient or static fields from + * consideration for serialization and deserialization. You can change this behavior through + * {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.
  • + *
+ */ + public Gson() { + this(createDefaultObjectNavigatorFactory()); + } + + /** + * Constructs a Gson object with the specified version and the mode of operation while + * encountering inner class references. + * + * @param factory the object navigator factory to use when creating a new {@link ObjectNavigator} + * instance + */ + Gson(ObjectNavigatorFactory factory) { + this(factory, createObjectConstructor(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS), + DEFAULT_TYPE_ADAPTER, DEFAULT_JSON_FORMATTER, false, + DefaultTypeAdapters.DEFAULT_SERIALIZERS, DefaultTypeAdapters.DEFAULT_DESERIALIZERS); + } + + Gson(ObjectNavigatorFactory factory, MappedObjectConstructor objectConstructor, + TypeAdapter typeAdapter, JsonFormatter formatter, boolean serializeNulls, + ParameterizedTypeHandlerMap> serializers, + ParameterizedTypeHandlerMap> deserializers) { + this.navigatorFactory = factory; + this.objectConstructor = objectConstructor; + this.typeAdapter = typeAdapter; + this.formatter = formatter; + this.serializeNulls = serializeNulls; + this.serializers = serializers; + this.deserializers = deserializers; + } + + static MappedObjectConstructor createObjectConstructor( + ParameterizedTypeHandlerMap> instanceCreators) { + MappedObjectConstructor objectConstructor = new MappedObjectConstructor(); + for (Map.Entry> entry : instanceCreators.entrySet()) { + objectConstructor.register(entry.getKey(), entry.getValue()); + } + return objectConstructor; + } + + private static ObjectNavigatorFactory createDefaultObjectNavigatorFactory() { + return new ObjectNavigatorFactory( + createExclusionStrategy(VersionConstants.IGNORE_VERSIONS), DEFAULT_NAMING_POLICY); + } + + private static ExclusionStrategy createExclusionStrategy(double version) { + List strategies = new LinkedList(); + strategies.add(new InnerClassExclusionStrategy()); + strategies.add(DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY); + if (version != VersionConstants.IGNORE_VERSIONS) { + strategies.add(new VersionExclusionStrategy(version)); + } + return new DisjunctionExclusionStrategy(strategies); + } + + /** + * This method serializes the specified object into its equivalent 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, Writer)} instead. + * + * @param src the object for which Json representation is to be created setting for Gson + * @return Json representation of {@code src}. + */ + public String toJson(Object src) { + if (src == null) { + return serializeNulls ? NULL_STRING : ""; + } + return toJson(src, src.getClass()); + } + + /** + * This method serializes the specified object, including those of generic types, into its + * equivalent Json representation. This method must be used if the specified object is a generic + * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out + * the object to a {@link Writer}, use {@link #toJson(Object, Type, Writer)} 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.google.gson.reflect.TypeToken} class. For example, + * to get the type for {@code Collection}, you should use: + *
+   * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
+   * 
+ * @return Json representation of {@code src} + */ + public String toJson(Object src, Type typeOfSrc) { + StringWriter writer = new StringWriter(); + toJson(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, Writer)} 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 + * @since 1.2 + */ + public void toJson(Object src, Writer writer) { + if (src != null) { + toJson(src, src.getClass(), writer); + } else if (serializeNulls) { + writeOutNullString(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, Writer)} 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.google.gson.reflect.TypeToken} class. For example, + * to get the type for {@code Collection}, you should use: + *
+   * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
+   * 
+ * @param writer Writer to which the Json representation of src needs to be written. + * @since 1.2 + */ + public void toJson(Object src, Type typeOfSrc, Writer writer) { + if (src != null) { + JsonSerializationContext context = + new JsonSerializationContextDefault(navigatorFactory, serializeNulls, serializers); + JsonElement jsonElement = context.serialize(src, typeOfSrc); + + //TODO(Joel): instead of navigating the "JsonElement" inside the formatter, do it here. + formatter.format(jsonElement, new PrintWriter(writer), serializeNulls); + } else { + if (serializeNulls) { + writeOutNullString(writer); + } + } + } + + /** + * 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 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 JsonParseException if json is not a valid representation for an object of type + * classOfT + */ + @SuppressWarnings("unchecked") + public T fromJson(String json, Class classOfT) throws JsonParseException { + T target = (T) fromJson(json, (Type) classOfT); + return target; + } + + /** + * 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 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.google.gson.reflect.TypeToken} class. For example, to get the type for + * {@code Collection}, you should use: + *
+   * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
+   * 
+ * @return an object of type T from the string + * @throws JsonParseException if json is not a valid representation for an object of type typeOfT + */ + @SuppressWarnings("unchecked") + public T fromJson(String json, Type typeOfT) throws JsonParseException { + 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 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 JsonParseException if json is not a valid representation for an object of type + * classOfT + * @since 1.2 + */ + public T fromJson(Reader json, Class classOfT) throws JsonParseException { + T target = classOfT.cast(fromJson(json, (Type) classOfT)); + return target; + } + + /** + * 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 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.google.gson.reflect.TypeToken} class. For example, to get the type for + * {@code Collection}, you should use: + *
+   * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
+   * 
+ * @return an object of type T from the json + * @throws JsonParseException if json is not a valid representation for an object of type typeOfT + * @since 1.2 + */ + @SuppressWarnings("unchecked") + public T fromJson(Reader json, Type typeOfT) throws JsonParseException { + try { + JsonParser parser = new JsonParser(json); + JsonElement root = parser.parse(); + JsonDeserializationContext context = new JsonDeserializationContextDefault(navigatorFactory, + deserializers, objectConstructor, typeAdapter); + T target = (T) context.deserialize(root, typeOfT); + return target; + } catch (TokenMgrError e) { + throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e); + } catch (ParseException e) { + throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e); + } 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); + } + } + + /** + * Appends the {@link #NULL_STRING} to the {@code writer} object. + * + * @param writer the object to append the null value to + */ + private void writeOutNullString(Writer writer) { + try { + writer.append(NULL_STRING); + } catch (IOException e) { + // Should this be a different exception??? + throw new JsonParseException(e); + } + } +} diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java new file mode 100644 index 00000000..ccf1269b --- /dev/null +++ b/gson/src/main/java/com/google/gson/GsonBuilder.java @@ -0,0 +1,357 @@ +/* + * 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.google.gson; + +import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter; + +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; + +/** + *

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.

+ * + *

The following is an example shows how to use the {@code GsonBuilder} to construct a Gson + * instance: + * + *

+ * Gson gson = new GsonBuilder()
+ *     .registerTypeAdapter(Id.class, new IdTypeAdapter())
+ *     .serializeNulls()
+ *     .setDateFormat(DateFormat.LONG)
+ *     .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
+ *     .setPrettyPrinting()
+ *     .setVersion(1.0)
+ *     .create();
+ * 

+ * + *

NOTE: the order of invocation of configuration methods does not matter.

+ * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public final class GsonBuilder { + + private double ignoreVersionsAfter; + private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy; + private final InnerClassExclusionStrategy innerClassExclusionStrategy; + private boolean excludeFieldsWithoutExposeAnnotation; + private final TypeAdapter typeAdapter; + private JsonFormatter formatter; + private FieldNamingStrategy fieldNamingPolicy; + private final ParameterizedTypeHandlerMap> instanceCreators; + private final ParameterizedTypeHandlerMap> serializers; + private final ParameterizedTypeHandlerMap> deserializers; + private boolean serializeNulls; + private String datePattern; + private int dateStyle; + + /** + * 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() { + // setup default values + ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS; + innerClassExclusionStrategy = new InnerClassExclusionStrategy(); + modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY; + excludeFieldsWithoutExposeAnnotation = false; + typeAdapter = Gson.DEFAULT_TYPE_ADAPTER; + formatter = Gson.DEFAULT_JSON_FORMATTER; + fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY; + instanceCreators = new ParameterizedTypeHandlerMap>(); + serializers = new ParameterizedTypeHandlerMap>(); + deserializers = new ParameterizedTypeHandlerMap>(); + serializeNulls = false; + dateStyle = DateFormat.DEFAULT; + } + + /** + * 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) { + boolean skipSynthetics = true; + modifierBasedExclusionStrategy = new ModifierBasedExclusionStrategy(skipSynthetics, modifiers); + return this; + } + + /** + * Configures Gson to exclude all fields from consideration for serialization or deserialization + * that do not have the {@link com.google.gson.annotations.Expose} annotation. + * + * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern + */ + public GsonBuilder excludeFieldsWithoutExposeAnnotation() { + excludeFieldsWithoutExposeAnnotation = true; + return this; + } + + /** + * Configure Gson to serialize null fields. By default, Gson omits all fields that are null + * during serialization. + * + * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern + * @since 1.2 + */ + public GsonBuilder serializeNulls() { + this.serializeNulls = true; + return this; + } + /** + * Configures Gson to 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 fieldNamingPolicy the actual naming strategy to apply to the fields + * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern + */ + private GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingPolicy) { + this.fieldNamingPolicy = new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingPolicy); + 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() { + setFormatter(new JsonPrintFormatter()); + return this; + } + + /** + * Configures Gson with a new formatting strategy other than the default strategy. The default + * strategy is to provide a compact representation that eliminates all unneeded white-space. + * + * @param formatter the new formatter to use. + * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern + * @see JsonPrintFormatter + */ + GsonBuilder setFormatter(JsonFormatter formatter) { + this.formatter = formatter; + 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. + * + *

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.

+ * + * @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. + * + *

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.

+ * + * @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 for custom serialization or deserialization. This method combines the + * registration of an {@link InstanceCreator}, {@link JsonSerializer}, and a + * {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements + * all the required interfaces for custom serialization with Gson. If an instance creator, + * serializer or deserializer was previously registered for the specified {@code type}, it is + * overwritten. + * + * @param type the type definition for the type adapter being registered + * @param typeAdapter This object must implement at least one of the {@link InstanceCreator}, + * {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces. + * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern + */ + public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) { + Preconditions.checkArgument(typeAdapter instanceof JsonSerializer + || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof InstanceCreator); + if (typeAdapter instanceof InstanceCreator) { + registerInstanceCreator(type, (InstanceCreator) typeAdapter); + } + if (typeAdapter instanceof JsonSerializer) { + registerSerializer(type, (JsonSerializer) typeAdapter); + } + if (typeAdapter instanceof JsonDeserializer) { + registerDeserializer(type, (JsonDeserializer) typeAdapter); + } + return this; + } + + /** + * Configures Gson to use a custom {@link InstanceCreator} for the specified type. If an instance + * creator was previously registered for the specified class, it is overwritten. Since this method + * takes a type instead of a Class object, it can be used to register a specific handler for a + * generic type corresponding to a raw type. + * + * @param 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 GsonBuilder registerInstanceCreator(Type typeOfT, + InstanceCreator 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 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 GsonBuilder registerSerializer(Type typeOfT, final JsonSerializer serializer) { + serializers.register(typeOfT, new JsonSerializerExceptionWrapper(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 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 GsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer deserializer) { + deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper(deserializer)); + 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 strategies = new LinkedList(); + strategies.add(innerClassExclusionStrategy); + strategies.add(modifierBasedExclusionStrategy); + if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) { + strategies.add(new VersionExclusionStrategy(ignoreVersionsAfter)); + } + if (excludeFieldsWithoutExposeAnnotation) { + strategies.add(new ExposeAnnotationBasedExclusionStrategy()); + } + ExclusionStrategy exclusionStrategy = new DisjunctionExclusionStrategy(strategies); + ObjectNavigatorFactory objectNavigatorFactory = + new ObjectNavigatorFactory(exclusionStrategy, fieldNamingPolicy); + + ParameterizedTypeHandlerMap> customSerializers = serializers.copyOf(); + ParameterizedTypeHandlerMap> customDeserializers = deserializers.copyOf(); + + addTypeAdaptersForDate(datePattern, dateStyle, customSerializers, customDeserializers); + customSerializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_SERIALIZERS); + customDeserializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_DESERIALIZERS); + + ParameterizedTypeHandlerMap> customInstanceCreators = + instanceCreators.copyOf(); + customInstanceCreators.registerIfAbsent(DefaultTypeAdapters.DEFAULT_INSTANCE_CREATORS); + MappedObjectConstructor objConstructor = Gson.createObjectConstructor(customInstanceCreators); + + Gson gson = new Gson(objectNavigatorFactory, objConstructor, typeAdapter, formatter, + serializeNulls, customSerializers, customDeserializers); + return gson; + } + + private static void addTypeAdaptersForDate(String datePattern, int dateStyle, + ParameterizedTypeHandlerMap> serializers, + ParameterizedTypeHandlerMap> deserializers) { + // NOTE: if a date pattern exists, then that style takes priority + DefaultDateTypeAdapter dateTypeAdapter = null; + if (datePattern != null && !"".equals(datePattern.trim())) { + dateTypeAdapter = new DefaultDateTypeAdapter(datePattern); + } else if (dateStyle != DateFormat.DEFAULT) { + dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle); + } + if (dateTypeAdapter != null + && !serializers.hasAnyHandlerFor(Date.class) + && !deserializers.hasAnyHandlerFor(Date.class)) { + serializers.register(Date.class, dateTypeAdapter); + deserializers.register(Date.class, dateTypeAdapter); + } + } +} diff --git a/gson/src/main/java/com/google/gson/InnerClassExclusionStrategy.java b/gson/src/main/java/com/google/gson/InnerClassExclusionStrategy.java new file mode 100644 index 00000000..f3839f03 --- /dev/null +++ b/gson/src/main/java/com/google/gson/InnerClassExclusionStrategy.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Field; + +/** + * Strategy for excluding inner classes. + * + * @author Joel Leitch + */ +final class InnerClassExclusionStrategy implements ExclusionStrategy { + + public boolean shouldSkipField(Field f) { + return isAnonymousOrLocal(f.getType()); + } + + public boolean shouldSkipClass(Class clazz) { + return isAnonymousOrLocal(clazz); + } + + private boolean isAnonymousOrLocal(Class clazz) { + return clazz.isAnonymousClass() || clazz.isLocalClass(); + } +} diff --git a/gson/src/main/java/com/google/gson/InstanceCreator.java b/gson/src/main/java/com/google/gson/InstanceCreator.java new file mode 100644 index 00000000..87fe32f9 --- /dev/null +++ b/gson/src/main/java/com/google/gson/InstanceCreator.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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. + *

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.

+ * + *
+ * 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;
+ *   }
+ * }
+ * 
+ * + *

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:

+ * + *
+ * private Id() {
+ *   this(Object.class, 0L);
+ * }
+ * 
+ * + *

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}:

+ * + *
+ * class IdInstanceCreator implements InstanceCreator<Id> {
+ *   public Id createInstance(Type type) {
+ *     return new Id(Object.class, 0L);
+ *   }
+ * }
+ * 
+ * + *

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 + * new 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:

+ * + *
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdInstanceCreator()).create();
+ * 
+ * + * @param the type of object that will be created by this implementation. + * + * @author Joel Leitch + */ +public interface InstanceCreator { + + /** + * 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); +} diff --git a/gson/src/main/java/com/google/gson/JavaFieldNamingPolicy.java b/gson/src/main/java/com/google/gson/JavaFieldNamingPolicy.java new file mode 100644 index 00000000..e2bb768d --- /dev/null +++ b/gson/src/main/java/com/google/gson/JavaFieldNamingPolicy.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * A simple implementation of the {@link FieldNamingStrategy} interface such that it does not + * perform any string translation of the incoming field name. + * + *

The following is an example:

+ * + *
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * JavaFieldNamingPolicy policy = new JavaFieldNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integerField".equals(translatedFieldName));
+ * 
+ * + *

This is the default {@link FieldNamingStrategy} used by Gson.

+ * + * @author Joel Leitch + */ +class JavaFieldNamingPolicy extends RecursiveFieldNamingPolicy { + + @Override + protected String translateName(String target, Type fieldType, Annotation[] annotations) { + return target; + } +} diff --git a/gson/src/main/java/com/google/gson/JsonArray.java b/gson/src/main/java/com/google/gson/JsonArray.java new file mode 100644 index 00000000..d5bdbdfb --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonArray.java @@ -0,0 +1,291 @@ +/* + * 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.google.gson; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +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 + */ +public final class JsonArray extends JsonElement implements Iterable { + private final List elements; + + /** + * Creates an empty JsonArray. + */ + public JsonArray() { + elements = new LinkedList(); + } + + /** + * Adds the specified element to self. + * + * @param element the element that needs to be added to the array. + */ + public void add(JsonElement element) { + 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 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(); + } + + /** + * convenience method to get this array as a primitive short if it contains a single element. + * + * @return get this element as a primitive short if it is single element array. + * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and + * is not a valid short. + * @throws IllegalStateException if the array has more than one element. + */ + @Override + public short getAsShort() { + if (elements.size() == 1) { + return elements.get(0).getAsShort(); + } + throw new IllegalStateException(); + } + + /** + * convenience method to get this array as a boolean if it contains a single element. + * + * @return get this element as a boolean if it is single element array. + * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and + * is not a valid boolean. + * @throws IllegalStateException if the array has more than one element. + */ + @Override + public boolean getAsBoolean() { + if (elements.size() == 1) { + return elements.get(0).getAsBoolean(); + } + throw new IllegalStateException(); + } + + /** + * convenience method to get this array as an Object if it contains a single element. + * + * @return get this element as an Object if it is single element array. + * @throws ClassCastException if the element in the array is of not a {@link JsonPrimitive} and + * is not a valid Object. + * @throws IllegalStateException if the array has more than one element. + */ + @Override + Object getAsObject() { + if (elements.size() == 1) { + return elements.get(0).getAsObject(); + } + throw new IllegalStateException(); + } + + @Override + protected void toString(StringBuilder sb) { + sb.append('['); + boolean first = true; + for (JsonElement element : elements) { + if (first) { + first = false; + } else { + sb.append(','); + } + element.toString(sb); + } + sb.append(']'); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java new file mode 100644 index 00000000..67c2d544 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonArrayDeserializationVisitor.java @@ -0,0 +1,134 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * A visitor that populates fields of an object with data from its equivalent + * JSON representation + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class JsonArrayDeserializationVisitor extends JsonDeserializationVisitor { + private final Class componentType; + + JsonArrayDeserializationVisitor(JsonArray jsonArray, Type arrayType, + ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, + TypeAdapter typeAdapter, ParameterizedTypeHandlerMap> deserializers, + JsonDeserializationContext context) { + super(jsonArray, arrayType, factory, objectConstructor, typeAdapter, deserializers, context); + this.componentType = TypeUtils.toRawClass(arrayType); + } + + @Override + @SuppressWarnings("unchecked") + protected T constructTarget() { + + TypeInfo typeInfo = new TypeInfo(targetType); + + JsonArray jsonArray = json.getAsJsonArray(); + if (typeInfo.isPrimitiveOrStringAndNotAnArray()) { + if (jsonArray.size() != 1) { + throw new IllegalArgumentException( + "Primitives should be an array of length 1, but was: " + jsonArray); + } + return (T) objectConstructor.construct(typeInfo.getWrappedClass()); + } else if (typeInfo.isArray()) { + TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(targetType); + // We know that we are getting back an array of the required type, so + // this typecasting is safe. + return (T) objectConstructor.constructArray(arrayTypeInfo.getSecondLevelType(), + jsonArray.size()); + } else { // is a collection + return (T) objectConstructor.construct(typeInfo.getRawClass()); + } + } + + public void visitArray(Object array, Type arrayType) { + JsonArray jsonArray = json.getAsJsonArray(); + TypeInfoArray arrayTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType); + for (int i = 0; i < jsonArray.size(); i++) { + JsonElement jsonChild = jsonArray.get(i); + Object child; + + if (jsonChild == null) { + child = null; + } else if (jsonChild instanceof JsonObject) { + child = visitChildAsObject(arrayTypeInfo.getComponentRawType(), jsonChild); + } else if (jsonChild instanceof JsonArray) { + child = visitChildAsArray(arrayTypeInfo.getSecondLevelType(), jsonChild.getAsJsonArray()); + } else if (jsonChild instanceof JsonPrimitive) { + child = visitChildAsPrimitive(arrayTypeInfo.getComponentRawType(), + jsonChild.getAsJsonPrimitive()); + } else { + throw new IllegalStateException(); + } + Array.set(array, i, child); + } + } + + @SuppressWarnings("unchecked") + public void visitCollection(Collection collection, Type collectionType) { + Type childType = TypeUtils.getActualTypeForFirstTypeVariable(collectionType); + for (JsonElement jsonChild : json.getAsJsonArray()) { + if (childType == Object.class) { + throw new JsonParseException(collection + + " must not be a raw collection. Try making it genericized instead."); + } + Object child = visitChild(childType, jsonChild); + collection.add(child); + } + } + + @SuppressWarnings("unchecked") + public void visitPrimitiveValue(Object obj) { + target = (T) typeAdapter.adaptType(json.getAsJsonArray().get(0).getAsObject(), componentType); + } + + // We should not implement any other method from Visitor interface since + // all other methods should be invoked on JsonObjectDeserializationVisitor + // instead. + + public void endVisitingObject(Object node) { + throw new UnsupportedOperationException(); + } + + public void startVisitingObject(Object node) { + throw new UnsupportedOperationException(); + } + + public void visitArrayField(Field f, Type typeOfF, Object obj) { + throw new UnsupportedOperationException(); + } + + public void visitCollectionField(Field f, Type typeOfF, Object obj) { + throw new UnsupportedOperationException(); + } + + public void visitObjectField(Field f, Type typeOfF, Object obj) { + throw new UnsupportedOperationException(); + } + + public void visitPrimitiveField(Field f, Type typeOfF, Object obj) { + throw new UnsupportedOperationException(); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonCompactFormatter.java b/gson/src/main/java/com/google/gson/JsonCompactFormatter.java new file mode 100644 index 00000000..5f2651a6 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonCompactFormatter.java @@ -0,0 +1,133 @@ +/* + * 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.google.gson; + +import java.io.PrintWriter; + +/** + * Formats Json in a compact way eliminating all unnecessary whitespace. + * + * @author Inderjeet Singh + */ +final class JsonCompactFormatter implements JsonFormatter { + + private static class FormattingVisitor implements JsonElementVisitor { + private final PrintWriter writer; + private final boolean serializeNulls; + + FormattingVisitor(PrintWriter writer, boolean serializeNulls) { + this.writer = writer; + this.serializeNulls = serializeNulls; + } + + public void visitPrimitive(JsonPrimitive primitive) { + writer.append(primitive.toString()); + } + + public void visitNull() { + writer.append("null"); + } + + public void startArray(JsonArray array) { + writer.append('['); + } + + public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + writer.append(member.toString()); + } + + public void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + } + + public void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + } + + public void visitNullArrayMember(JsonArray parent, boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + } + + public void endArray(JsonArray array) { + writer.append(']'); + } + + public void startObject(JsonObject object) { + writer.append('{'); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, + boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + writer.append('"'); + writer.append(memberName); + writer.append("\":"); + writer.append(member.toString()); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonArray member, + boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + writer.append('"'); + writer.append(memberName); + writer.append("\":"); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonObject member, + boolean isFirst) { + if (!isFirst) { + writer.append(','); + } + writer.append('"'); + writer.append(memberName); + writer.append("\":"); + } + + public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) { + if (serializeNulls) { + visitObjectMember(parent, memberName, (JsonObject) null, isFirst); + } + } + + public void endObject(JsonObject object) { + writer.append('}'); + } + } + + public void format(JsonElement root, PrintWriter writer, boolean serializeNulls) { + if (root == null) { + return; + } + JsonElementVisitor visitor = + new JsonEscapingVisitor(new FormattingVisitor(writer, serializeNulls)); + JsonTreeNavigator navigator = new JsonTreeNavigator(visitor, serializeNulls); + navigator.navigate(root); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationContext.java b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java new file mode 100644 index 00000000..3c053374 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonDeserializationContext.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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 + */ +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 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 deserialize(JsonElement json, Type typeOfT) throws JsonParseException; +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationContextDefault.java b/gson/src/main/java/com/google/gson/JsonDeserializationContextDefault.java new file mode 100644 index 00000000..f622402d --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonDeserializationContextDefault.java @@ -0,0 +1,93 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Type; + +/** + * implementation of a deserialization context for Gson + * + * @author Inderjeet Singh + */ +final class JsonDeserializationContextDefault implements JsonDeserializationContext { + + private final ObjectNavigatorFactory navigatorFactory; + private final ParameterizedTypeHandlerMap> deserializers; + private final MappedObjectConstructor objectConstructor; + private final TypeAdapter typeAdapter; + + JsonDeserializationContextDefault(ObjectNavigatorFactory navigatorFactory, + ParameterizedTypeHandlerMap> deserializers, + MappedObjectConstructor objectConstructor, TypeAdapter typeAdapter) { + this.navigatorFactory = navigatorFactory; + this.deserializers = deserializers; + this.objectConstructor = objectConstructor; + this.typeAdapter = typeAdapter; + } + + @SuppressWarnings("unchecked") + public T deserialize(JsonElement json, Type typeOfT) throws JsonParseException { + 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 if (json.isJsonNull()) { + return null; + } else { + throw new JsonParseException("Failed parsing JSON source: " + json + " to Json"); + } + } + + private T fromJsonArray(Type arrayType, JsonArray jsonArray, + JsonDeserializationContext context) throws JsonParseException { + JsonArrayDeserializationVisitor visitor = new JsonArrayDeserializationVisitor( + jsonArray, arrayType, navigatorFactory, objectConstructor, typeAdapter, deserializers, + context); + Object target = visitor.getTarget(); + ObjectNavigator on = navigatorFactory.create(target, arrayType); + on.accept(visitor); + return visitor.getTarget(); + } + + private T fromJsonObject(Type typeOfT, JsonObject jsonObject, + JsonDeserializationContext context) throws JsonParseException { + JsonObjectDeserializationVisitor visitor = new JsonObjectDeserializationVisitor( + jsonObject, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers, + context); + Object target = visitor.getTarget(); + ObjectNavigator on = navigatorFactory.create(target, typeOfT); + on.accept(visitor); + return visitor.getTarget(); + } + + @SuppressWarnings("unchecked") + private T fromJsonPrimitive(Type typeOfT, JsonPrimitive json, + JsonDeserializationContext context) throws JsonParseException { + JsonPrimitiveDeserializationVisitor visitor = new JsonPrimitiveDeserializationVisitor( + json, typeOfT, navigatorFactory, objectConstructor, typeAdapter, deserializers, context); + Object target = visitor.getTarget(); + ObjectNavigator on = navigatorFactory.create(target, typeOfT); + on.accept(visitor); + target = visitor.getTarget(); + if (typeOfT instanceof Class) { + target = typeAdapter.adaptType(target, (Class) typeOfT); + } + return (T) target; + } +} diff --git a/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java new file mode 100644 index 00000000..8d7cef00 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonDeserializationVisitor.java @@ -0,0 +1,136 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Type; +import java.util.logging.Logger; + +/** + * 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 implements ObjectNavigator.Visitor { + + protected static Logger logger = Logger.getLogger(JsonDeserializationVisitor.class.getName()); + + protected final ObjectNavigatorFactory factory; + protected final ObjectConstructor objectConstructor; + protected final TypeAdapter typeAdapter; + protected final ParameterizedTypeHandlerMap> deserializers; + protected T target; + protected final JsonElement json; + protected final Type targetType; + private final JsonDeserializationContext context; + + public JsonDeserializationVisitor(JsonElement json, Type targetType, + ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, TypeAdapter typeAdapter, + ParameterizedTypeHandlerMap> deserializers, + JsonDeserializationContext context) { + Preconditions.checkNotNull(json); + this.targetType = targetType; + this.factory = factory; + this.objectConstructor = objectConstructor; + this.typeAdapter = typeAdapter; + this.deserializers = deserializers; + this.json = json; + this.context = context; + } + + T getTarget() { + if (target == null) { + target = constructTarget(); + } + return target; + } + + protected abstract T constructTarget(); + + @SuppressWarnings("unchecked") + public final void visitEnum(Object obj, Type objType) { + JsonDeserializer deserializer = (JsonDeserializer) deserializers.getHandlerFor(objType); + if (deserializer == null) { + deserializer = (JsonDeserializer) deserializers.getHandlerFor(Enum.class); + } + if (deserializer == null) { + throw new RuntimeException("Register a JsonDeserializer for Enum or " + + obj.getClass().getName()); + } + target = deserializer.deserialize(json, objType, context); + } + + @SuppressWarnings("unchecked") + public final boolean visitUsingCustomHandler(Object obj, Type objType) { + JsonDeserializer deserializer = (JsonDeserializer) deserializers.getHandlerFor(objType); + if (deserializer != null) { + target = deserializer.deserialize(json, objType, context); + return true; + } + return false; + } + + final Object visitChildAsObject(Type childType, JsonElement jsonChild) { + JsonDeserializationVisitor childVisitor = + new JsonObjectDeserializationVisitor(jsonChild, childType, + factory, objectConstructor, typeAdapter, deserializers, context); + return visitChild(childType, childVisitor); + } + + final Object visitChildAsArray(Type childType, JsonArray jsonChild) { + JsonDeserializationVisitor childVisitor = + new JsonArrayDeserializationVisitor(jsonChild.getAsJsonArray(), childType, + factory, objectConstructor, typeAdapter, deserializers, context); + return visitChild(childType, childVisitor); + } + + final Object visitChildAsPrimitive(Type childType, JsonPrimitive jsonChild) { + Preconditions.checkNotNull(jsonChild); + Class childClass; + if (childType instanceof Class) { + childClass = (Class) childType; + } else { + childClass = TypeUtils.toRawClass(childType); + } + return typeAdapter.adaptType(jsonChild.getAsObject(), childClass); + } + + final Object visitChild(Type childType, JsonElement jsonChild) { + if (jsonChild == null) { + return null; + } else if (jsonChild instanceof JsonArray) { + return visitChildAsArray(childType, jsonChild.getAsJsonArray()); + } else if (jsonChild instanceof JsonObject) { + return visitChildAsObject(childType, jsonChild); + } else if (jsonChild instanceof JsonPrimitive) { + return visitChildAsPrimitive(childType, jsonChild.getAsJsonPrimitive()); + } else { + throw new IllegalStateException(); + } + } + + private Object visitChild(Type type, JsonDeserializationVisitor childVisitor) { + Object child = childVisitor.getTarget(); + ObjectNavigator on = factory.create(child, type); + on.accept(childVisitor); + // the underlying object may have changed during the construction phase + // This happens primarily because of custom deserializers + return childVisitor.getTarget(); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonDeserializer.java b/gson/src/main/java/com/google/gson/JsonDeserializer.java new file mode 100644 index 00000000..6a864e6a --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonDeserializer.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Type; + +/** + *

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)}.

+ * + *

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}.

+ * + *
+ * 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;
+ *   }
+ * }
+ * 
+ * + *

The default deserialization of {@code Id(com.foo.MyObject.class, 20L)} will require the + * Json string to be {"clazz":com.foo.MyObject,"value":20}. 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:

+ * + *
+ * class IdDeserializer implements JsonDeserializer<Id>() {
+ *   public Id fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ *       throws JsonParseException {
+ *     return (Id) new Id((Class)typeOfT, id.getValue());
+ *   }
+ * 
+ * + *

You will also need to register {@code IdDeserializer} with Gson as follows:

+ * + *
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdDeserializer()).create();
+ * 
+ * + * @author Inderjeet Singh + * @author Joel Leitch + * + * @param 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 { + + /** + * Gson invokes this call-back method during deserialization when it encounters a field of the + * specified type. + *

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; +} diff --git a/gson/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java b/gson/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java new file mode 100644 index 00000000..2bb1831a --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonDeserializerExceptionWrapper.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Type; + +/** + * Decorators a {@code JsonDeserializer} instance with exception handling. This wrapper class + * ensures that a {@code JsonDeserializer} will not propagate any exception other than a + * {@link JsonParseException}. + * + * @param type of the deserializer being wrapped. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +class JsonDeserializerExceptionWrapper implements JsonDeserializer { + + private final JsonDeserializer 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 delegate) { + Preconditions.checkNotNull(delegate); + this.delegate = delegate; + } + + public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + try { + return delegate.deserialize(json, typeOfT, context); + } catch (JsonParseException e) { + // just rethrow the exception + throw e; + } catch (Exception e) { + // rethrow as a JsonParseException + StringBuilder errorMsg = new StringBuilder() + .append("The JsonDeserializer ") + .append(delegate) + .append(" failed to deserialized json object ") + .append(json) + .append(" given the type ") + .append(typeOfT); + throw new JsonParseException(errorMsg.toString(), e); + } + } +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/JsonElement.java b/gson/src/main/java/com/google/gson/JsonElement.java new file mode 100644 index 00000000..6a960e83 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonElement.java @@ -0,0 +1,292 @@ +/* + * 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.google.gson; + +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 { + + /** + * 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 ClassCastException if the element is of another type. + */ + public JsonObject getAsJsonObject() { + return (JsonObject) this; + } + + /** + * 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 ClassCastException if the element is of another type. + */ + public JsonArray getAsJsonArray() { + return (JsonArray) this; + } + + /** + * 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 ClassCastException if the element is of another type. + */ + public JsonPrimitive getAsJsonPrimitive() { + return (JsonPrimitive) this; + } + + /** + * 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 ClassCastException if the element is of another type. + * @since 1.2 + */ + public JsonNull getAsJsonNull() { + return (JsonNull) this; + } + + /** + * 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 {@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. The output is valid Json. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + toString(sb); + return sb.toString(); + } + + protected abstract void toString(StringBuilder sb); +} diff --git a/gson/src/main/java/com/google/gson/JsonElementVisitor.java b/gson/src/main/java/com/google/gson/JsonElementVisitor.java new file mode 100644 index 00000000..29d908a3 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonElementVisitor.java @@ -0,0 +1,42 @@ +/* + * 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.google.gson; + +/** + * Definition of a visitor for a JsonElement tree. + * + * @author Inderjeet Singh + */ +interface JsonElementVisitor { + void visitPrimitive(JsonPrimitive primitive); + void visitNull(); + + void startArray(JsonArray array); + void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst); + void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst); + void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst); + void visitNullArrayMember(JsonArray parent, boolean isFirst); + void endArray(JsonArray array); + + void startObject(JsonObject object); + void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, + boolean isFirst); + void visitObjectMember(JsonObject parent, String memberName, JsonArray member, boolean isFirst); + void visitObjectMember(JsonObject parent, String memberName, JsonObject member, boolean isFirst); + void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst); + void endObject(JsonObject object); +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/JsonEscapingVisitor.java b/gson/src/main/java/com/google/gson/JsonEscapingVisitor.java new file mode 100644 index 00000000..6630f913 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonEscapingVisitor.java @@ -0,0 +1,62 @@ +/* + * 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.google.gson; + +/** + * Performs JSON escaping and passes on the new escaped value to the delegate + * {@link JsonElementVisitor}. + * + * @author Joel Leitch + */ +class JsonEscapingVisitor extends DelegatingJsonElementVisitor { + + /** + * Constructs a Visitor that will properly escape any JSON primitive values. + * + * @param delegate the JsonElementVisitor that this instance will use for delegation + */ + protected JsonEscapingVisitor(JsonElementVisitor delegate) { + super(delegate); + } + + @Override + public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) { + super.visitArrayMember(parent, escapeJsonPrimitive(member), isFirst); + } + + @Override + public void visitObjectMember( + JsonObject parent, String memberName, JsonPrimitive member, boolean isFirst) { + super.visitObjectMember(parent, memberName, escapeJsonPrimitive(member), isFirst); + } + + @Override + public void visitPrimitive(JsonPrimitive primitive) { + super.visitPrimitive(escapeJsonPrimitive(primitive)); + } + + private JsonPrimitive escapeJsonPrimitive(JsonPrimitive member) { + if (member.isString()) { + String memberValue = member.getAsString(); + String escapedValue = Escaper.escapeJsonString(memberValue); + if (!escapedValue.equals(memberValue)) { + member.setValue(escapedValue); + } + } + return member; + } +} diff --git a/gson/src/main/java/com/google/gson/JsonFieldNameValidator.java b/gson/src/main/java/com/google/gson/JsonFieldNameValidator.java new file mode 100644 index 00000000..60c32589 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonFieldNameValidator.java @@ -0,0 +1,68 @@ +/* + * 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.google.gson; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class can be used to check the validity of a JSON field name. + * + *

The primary use of this object is to ensure that any Java fields that use the + * {@link com.google.gson.annotations.SerializedName} annotation is providing valid JSON + * field names. This will make the code fail-fast rather than letting the invalid + * field name propagate to the client and it fails to parse.

+ * + * @author Joel Leitch + */ +class JsonFieldNameValidator { + private static final String[] JS_KEYWORDS = { + "break", "case", "catch", "class", "comment", "const", "continue", "debugger", "default", "delete", "do", + "else", "enum", "export", "extends", "finally", "for", "function", "if", "import", "in", "label", "new", + "return", "super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with" + }; + + private static final Pattern JSON_FIELD_NAME_PATTERN = + Pattern.compile("(^[a-zA-Z][a-zA-Z0-9\\$_]*$)|(^[\\$_][a-zA-Z][a-zA-Z0-9\\$_]*$)"); + + private static final Set KEYWORDS = Collections.unmodifiableSet( + new HashSet(Arrays.asList(JS_KEYWORDS))); + + /** + * Performs validation on the JSON field name to ensure it is a valid field name. + * + * @param fieldName the name of the field to validate + * @return {@code fieldName} if it is a valid JSON field name + * @throws IllegalArgumentException if the field name is an invalid JSON field name + */ + public String validate(String fieldName) { + Preconditions.checkNotNull(fieldName); + Preconditions.checkArgument(!"".equals(fieldName.trim())); + Preconditions.checkArgument(!KEYWORDS.contains(fieldName)); + + Matcher matcher = JSON_FIELD_NAME_PATTERN.matcher(fieldName); + if (!matcher.matches()) { + throw new IllegalArgumentException(fieldName + " is not a valid JSON field name."); + } else { + return fieldName; + } + } +} diff --git a/gson/src/main/java/com/google/gson/JsonFormatter.java b/gson/src/main/java/com/google/gson/JsonFormatter.java new file mode 100644 index 00000000..66e01a1b --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonFormatter.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.io.PrintWriter; + +/** + * Common interface for a formatter for Json. + * + * @author Inderjeet Singh + */ +interface JsonFormatter { + + /** + * Writes a formatted version of the Json corresponding to + * the specified Json. + * + * @param root the root of the Json tree. + * @param writer the writer to output the formatter JSON to. + * @param serializeNulls serialize null values in the output. + */ + public void format(JsonElement root, PrintWriter writer, boolean serializeNulls); +} diff --git a/gson/src/main/java/com/google/gson/JsonNull.java b/gson/src/main/java/com/google/gson/JsonNull.java new file mode 100755 index 00000000..2b6909c0 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonNull.java @@ -0,0 +1,32 @@ +/* + * 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.google.gson; + +/** + * A class representing a Json null value. + * + * @author Inderjeet Singh + * @author Joel Leitch + * @since 1.2 + */ +public final class JsonNull extends JsonElement { + + @Override + protected void toString(StringBuilder sb) { + sb.append("null"); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonObject.java b/gson/src/main/java/com/google/gson/JsonObject.java new file mode 100644 index 00000000..98334c6d --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonObject.java @@ -0,0 +1,156 @@ +/* + * 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.google.gson; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +/** + * 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 + */ +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 members; + + /** + * Creates an empty JsonObject. + */ + public JsonObject() { + members = new LinkedHashMap(); + } + + /** + * 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) { + members.put(property, value); + } + + /** + * 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) { + members.put(property, new JsonPrimitive(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) { + members.put(property, 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> 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) { + return members.get(memberName); + } + + /** + * Convenience method to get the specified member as a JsonPrimitive element. + * + * @param memberName name of the member being requested. + * @return the JsonPrimitive corresponding to the specified member. + */ + public JsonPrimitive getAsJsonPrimitive(String memberName) { + return (JsonPrimitive) members.get(memberName); + } + + /** + * Convenience method to get the specified member as a JsonArray. + * + * @param memberName name of the member being requested. + * @return the JsonArray corresponding to the specified member. + */ + public JsonArray getAsJsonArray(String memberName) { + return (JsonArray) members.get(memberName); + } + + /** + * Convenience method to get the specified member as a JsonObject. + * + * @param memberName name of the member being requested. + * @return the JsonObject corresponding to the specified member. + */ + public JsonObject getAsJsonObject(String memberName) { + return (JsonObject) members.get(memberName); + } + + @Override + protected void toString(StringBuilder sb) { + sb.append('{'); + boolean first = true; + for (Map.Entry entry : members.entrySet()) { + if (first) { + first = false; + } else { + sb.append(','); + } + sb.append('\"'); + sb.append(entry.getKey()); + sb.append("\":"); + entry.getValue().toString(sb); + } + sb.append('}'); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java new file mode 100644 index 00000000..bbf19db3 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonObjectDeserializationVisitor.java @@ -0,0 +1,150 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * A visitor that populates fields of an object with data from its equivalent + * JSON representation + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class JsonObjectDeserializationVisitor extends JsonDeserializationVisitor { + + JsonObjectDeserializationVisitor(JsonElement json, Type type, + ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, + TypeAdapter typeAdapter, ParameterizedTypeHandlerMap> deserializers, + JsonDeserializationContext context) { + super(json, type, factory, objectConstructor, typeAdapter, deserializers, context); + } + + @Override + @SuppressWarnings("unchecked") + protected T constructTarget() { + return (T) objectConstructor.construct(targetType); + } + + public void startVisitingObject(Object node) { + // do nothing + } + + public void endVisitingObject(Object node) { + // do nothing + } + + public void visitCollection(@SuppressWarnings("unchecked")Collection collection, + Type componentType) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitArray(Object array, Type componentType) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitPrimitiveValue(Object obj) { + // should not be called since this case should invoke JsonPrimitiveDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitObjectField(Field f, Type typeOfF, Object obj) { + try { + 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); + } + } + + @SuppressWarnings("unchecked") + public void visitCollectionField(Field f, Type typeOfF, Object obj) { + try { + JsonObject jsonObject = json.getAsJsonObject(); + String fName = getFieldName(f); + JsonArray jsonArray = (JsonArray) jsonObject.get(fName); + if (jsonArray != null) { + Collection collection = (Collection) objectConstructor.construct(typeOfF); + f.set(obj, collection); + Type childType = TypeUtils.getActualTypeForFirstTypeVariable(typeOfF); + for (JsonElement jsonChild : jsonArray) { + Object child = visitChild(childType, jsonChild); + if (childType == Object.class) { + throw new JsonParseException(fName + + " can not be a raw collection. Try making it a genericized collection instead"); + } + collection.add(child); + } + } else { + f.set(obj, null); + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public void visitArrayField(Field f, Type typeOfF, Object obj) { + try { + 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); + } + } + + public void visitPrimitiveField(Field f, Type typeOfF, Object obj) { + try { + JsonObject jsonObject = json.getAsJsonObject(); + String fName = getFieldName(f); + JsonPrimitive value = jsonObject.getAsJsonPrimitive(fName); + if (value != null) { + f.set(obj, typeAdapter.adaptType(value.getAsObject(), TypeUtils.toRawClass(typeOfF))); + } else { + // For Strings, we need to set the field to null + // For other primitive types, any value created during default construction is fine + if (f.getType() == String.class) { + f.set(obj, null); + } + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private String getFieldName(Field f) { + FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy(); + return namingPolicy.translateName(f); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonParseException.java b/gson/src/main/java/com/google/gson/JsonParseException.java new file mode 100644 index 00000000..b00df193 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonParseException.java @@ -0,0 +1,63 @@ +/* + * 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.google.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. + * + *

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}.

+ * + * @author Joel Leitch + */ +public final 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); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonParser.java b/gson/src/main/java/com/google/gson/JsonParser.java new file mode 100755 index 00000000..9e94b7e0 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonParser.java @@ -0,0 +1,506 @@ +/* Generated By:JavaCC: Do not edit this line. JsonParser.java */ +package com.google.gson; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +@SuppressWarnings("all") +final class JsonParser implements JsonParserConstants { + + final public JsonElement parse() throws ParseException { + JsonElement json = null; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 15: + json = JsonObject(); + break; + case 20: + json = JsonArray(); + break; + case DIGITS: + case QUOTE: + case 22: + case 23: + case 24: + json = JsonPrimitive(); + break; + case 17: + json = JsonNull(); + break; + default: + jj_la1[0] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + {if (true) return json;} + throw new Error("Missing return statement in function"); + } + + final private JsonObject JsonObject() throws ParseException { + JsonObject o = new JsonObject(); + jj_consume_token(15); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case QUOTE: + Members(o); + break; + default: + jj_la1[1] = jj_gen; + ; + } + jj_consume_token(16); + {if (true) return o;} + throw new Error("Missing return statement in function"); + } + + final private JsonNull JsonNull() throws ParseException { + JsonNull json = new JsonNull(); + jj_consume_token(17); + {if (true) return json;} + throw new Error("Missing return statement in function"); + } + + final private void Members(JsonObject o) throws ParseException { + Pair(o); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + jj_consume_token(18); + Members(o); + break; + default: + jj_la1[2] = jj_gen; + ; + } + } + + final private void Pair(JsonObject o) throws ParseException { + JsonPrimitive property; + JsonElement value; + property = JsonString(); + jj_consume_token(19); + value = JsonValue(); + o.add(property.getAsString(), value); + } + + final private JsonArray JsonArray() throws ParseException { + JsonArray array = new JsonArray(); + jj_consume_token(20); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case DIGITS: + case QUOTE: + case 15: + case 17: + case 20: + case 22: + case 23: + case 24: + Elements(array); + break; + default: + jj_la1[3] = jj_gen; + ; + } + jj_consume_token(21); + array.reverse(); + {if (true) return array;} + throw new Error("Missing return statement in function"); + } + + final private void Elements(JsonArray array) throws ParseException { + JsonElement element; + element = JsonValue(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 18: + jj_consume_token(18); + Elements(array); + break; + default: + jj_la1[4] = jj_gen; + ; + } + array.add(element); + } + + final private JsonElement JsonValue() throws ParseException { + JsonElement o = null; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case QUOTE: + o = JsonString(); + break; + case DIGITS: + case 24: + o = JsonNumber(); + break; + case 15: + o = JsonObject(); + break; + case 20: + o = JsonArray(); + break; + case 22: + jj_consume_token(22); + o = new JsonPrimitive(true); + break; + case 23: + jj_consume_token(23); + o = new JsonPrimitive(false); + break; + case 17: + jj_consume_token(17); + break; + default: + jj_la1[5] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + {if (true) return o;} + throw new Error("Missing return statement in function"); + } + + final private JsonPrimitive JsonPrimitive() throws ParseException { + JsonPrimitive value; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case QUOTE: + value = JsonString(); + {if (true) return value;} + break; + case DIGITS: + case 24: + value = JsonNumber(); + {if (true) return value;} + break; + case 22: + jj_consume_token(22); + {if (true) return new JsonPrimitive(true);} + break; + case 23: + jj_consume_token(23); + {if (true) return new JsonPrimitive(false);} + break; + default: + jj_la1[6] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + throw new Error("Missing return statement in function"); + } + + final private JsonPrimitive JsonNumber() throws ParseException { + String intpart = null, + fracpart = null, + exppart = null; + intpart = JsonInt(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 25: + fracpart = JsonFrac(); + break; + default: + jj_la1[7] = jj_gen; + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case E: + exppart = JsonExp(); + break; + default: + jj_la1[8] = jj_gen; + ; + } + Number n; + if (exppart != null) { + n = new BigDecimal(intpart + fracpart + exppart); + } else if (fracpart != null) { + n = new Double(intpart + fracpart); + } else { + // See if the number fits in an integer, or long + // Use BigInteger only if it is big enough. + if (intpart.length() < 10) { + n = new Integer(intpart); + } else if (intpart.length() < 19) { + n = new Long(intpart); + } else { + n = new BigInteger(intpart); + } + } + {if (true) return new JsonPrimitive(n);} + throw new Error("Missing return statement in function"); + } + + final private String JsonInt() throws ParseException { + String digits; + boolean negative = false; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case 24: + jj_consume_token(24); + negative = true; + break; + default: + jj_la1[9] = jj_gen; + ; + } + digits = Digits(); + if(negative) + {if (true) return "-" + digits;} + {if (true) return digits;} + throw new Error("Missing return statement in function"); + } + + final private String JsonFrac() throws ParseException { + String digits; + jj_consume_token(25); + digits = Digits(); + {if (true) return "." + digits;} + throw new Error("Missing return statement in function"); + } + + final private String JsonExp() throws ParseException { + Token t; + String digits; + t = jj_consume_token(E); + digits = Digits(); + {if (true) return t.image + digits;} + throw new Error("Missing return statement in function"); + } + + final private String Digits() throws ParseException { + Token t; + t = jj_consume_token(DIGITS); + {if (true) return t.image;} + throw new Error("Missing return statement in function"); + } + + final private JsonPrimitive JsonString() throws ParseException { + StringBuffer strbuf = new StringBuffer(); + jj_consume_token(QUOTE); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case CHAR: + case CNTRL_ESC: + case HEX_ESC: + Chars(strbuf); + break; + default: + jj_la1[10] = jj_gen; + ; + } + jj_consume_token(ENDQUOTE); + {if (true) return new JsonPrimitive(strbuf.toString());} + throw new Error("Missing return statement in function"); + } + + final private void Chars(StringBuffer strbuf) throws ParseException { + char c; + c = Char(); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case CHAR: + case CNTRL_ESC: + case HEX_ESC: + Chars(strbuf); + break; + default: + jj_la1[11] = jj_gen; + ; + } + strbuf.insert(0, c); + } + + final private char Char() throws ParseException { + Token t; + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case CHAR: + t = jj_consume_token(CHAR); + break; + case CNTRL_ESC: + t = jj_consume_token(CNTRL_ESC); + break; + case HEX_ESC: + t = jj_consume_token(HEX_ESC); + break; + default: + jj_la1[12] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + if(t.image.length() < 2) { + {if (true) return t.image.charAt(0);} + } + if(t.image.length() < 6) { + char c = t.image.charAt(1); + switch(t.image.charAt(1)) { + //control characters + case 'b' : {if (true) return (char) 8;} break; + case 'f' : {if (true) return (char) 12;} break; + case 'n' : {if (true) return (char) 10;} break; + case 'r' : {if (true) return (char) 13;} break; + case 't' : {if (true) return (char) 9;} break; + default : {if (true) return c;} //characters that represent themselves + } + } + else { //hex escape code + //create an integer from our hex values + //and then cast into a char + int i = Integer.valueOf(t.image.substring(2,6), 16).intValue(); + {if (true) return (char) i;} + } + throw new Error("Missing return statement in function"); + } + + public JsonParserTokenManager token_source; + SimpleCharStream jj_input_stream; + public Token token, jj_nt; + private int jj_ntk; + private int jj_gen; + final private int[] jj_la1 = new int[13]; + static private int[] jj_la1_0; + static { + jj_la1_0(); + } + private static void jj_la1_0() { + jj_la1_0 = new int[] {0x1d280c0,0x80,0x40000,0x1d280c0,0x40000,0x1d280c0,0x1c000c0,0x2000000,0x20,0x1000000,0x4c00,0x4c00,0x4c00,}; + } + + public JsonParser(java.io.InputStream stream) { + this(stream, null); + } + public JsonParser(java.io.InputStream stream, String encoding) { + try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source = new JsonParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + public void ReInit(java.io.InputStream stream, String encoding) { + try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + public JsonParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new JsonParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + public JsonParser(JsonParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + public void ReInit(JsonParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 13; i++) jj_la1[i] = -1; + } + + final private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + final private int jj_ntk() { + if ((jj_nt=token.next) == null) + return (jj_ntk = (token.next=token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.Vector jj_expentries = new java.util.Vector(); + private int[] jj_expentry; + private int jj_kind = -1; + + public ParseException generateParseException() { + jj_expentries.removeAllElements(); + boolean[] la1tokens = new boolean[26]; + for (int i = 0; i < 26; i++) { + la1tokens[i] = false; + } + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int i = 0; i < 13; i++) { + if (jj_la1[i] == jj_gen) { + for (int j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1<", + "\" \"", + "\"\\t\"", + "\"\\n\"", + "\"\\r\"", + "", + "", + "\"\\\"\"", + "\"\\\\\"", + "", + "", + "", + "\"u\"", + "", + "", + "\"{\"", + "\"}\"", + "\"null\"", + "\",\"", + "\":\"", + "\"[\"", + "\"]\"", + "\"true\"", + "\"false\"", + "\"-\"", + "\".\"", + }; + +} diff --git a/gson/src/main/java/com/google/gson/JsonParserTokenManager.java b/gson/src/main/java/com/google/gson/JsonParserTokenManager.java new file mode 100755 index 00000000..66ed3d4b --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonParserTokenManager.java @@ -0,0 +1,789 @@ +/* Generated By:JavaCC: Do not edit this line. JsonParserTokenManager.java */ +package com.google.gson; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +@SuppressWarnings("all") +final class JsonParserTokenManager implements JsonParserConstants +{ + public java.io.PrintStream debugStream = System.out; + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } +private final int jjMoveStringLiteralDfa0_3() +{ + return jjMoveNfa_3(0, 0); +} +private final void jjCheckNAdd(int state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} +private final void jjAddStates(int start, int end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} +private final void jjCheckNAddTwoStates(int state1, int state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} +private final void jjCheckNAddStates(int start, int end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} +private final void jjCheckNAddStates(int start) +{ + jjCheckNAdd(jjnextStates[start]); + jjCheckNAdd(jjnextStates[start + 1]); +} +private final int jjMoveNfa_3(int startState, int curPos) +{ + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 4; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 1; + break; + case 1: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 2; + break; + case 2: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 3; + break; + case 3: + if ((0x3ff000000000000L & l) != 0L && kind > 14) + kind = 14; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 1; + break; + case 1: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 2; + break; + case 2: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 3; + break; + case 3: + if ((0x7e0000007eL & l) != 0L && kind > 14) + kind = 14; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (int)(curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 4 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +private final int jjStopStringLiteralDfa_0(int pos, long active0) +{ + switch (pos) + { + default : + return -1; + } +} +private final int jjStartNfa_0(int pos, long active0) +{ + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1); +} +private final int jjStopAtPos(int pos, int kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} +private final int jjStartNfaWithStates_0(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_0(state, pos + 1); +} +private final int jjMoveStringLiteralDfa0_0() +{ + switch(curChar) + { + case 34: + return jjStopAtPos(0, 7); + case 44: + return jjStopAtPos(0, 18); + case 45: + return jjStopAtPos(0, 24); + case 46: + return jjStopAtPos(0, 25); + case 58: + return jjStopAtPos(0, 19); + case 91: + return jjStopAtPos(0, 20); + case 93: + return jjStopAtPos(0, 21); + case 102: + return jjMoveStringLiteralDfa1_0(0x800000L); + case 110: + return jjMoveStringLiteralDfa1_0(0x20000L); + case 116: + return jjMoveStringLiteralDfa1_0(0x400000L); + case 123: + return jjStopAtPos(0, 15); + case 125: + return jjStopAtPos(0, 16); + default : + return jjMoveNfa_0(0, 0); + } +} +private final int jjMoveStringLiteralDfa1_0(long active0) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0); + return 1; + } + switch(curChar) + { + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x800000L); + case 114: + return jjMoveStringLiteralDfa2_0(active0, 0x400000L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x20000L); + default : + break; + } + return jjStartNfa_0(0, active0); +} +private final int jjMoveStringLiteralDfa2_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(0, old0); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0); + return 2; + } + switch(curChar) + { + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x820000L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x400000L); + default : + break; + } + return jjStartNfa_0(1, active0); +} +private final int jjMoveStringLiteralDfa3_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(1, old0); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0); + return 3; + } + switch(curChar) + { + case 101: + if ((active0 & 0x400000L) != 0L) + return jjStopAtPos(3, 22); + break; + case 108: + if ((active0 & 0x20000L) != 0L) + return jjStopAtPos(3, 17); + break; + case 115: + return jjMoveStringLiteralDfa4_0(active0, 0x800000L); + default : + break; + } + return jjStartNfa_0(2, active0); +} +private final int jjMoveStringLiteralDfa4_0(long old0, long active0) +{ + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(2, old0); + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0); + return 4; + } + switch(curChar) + { + case 101: + if ((active0 & 0x800000L) != 0L) + return jjStopAtPos(4, 23); + break; + default : + break; + } + return jjStartNfa_0(3, active0); +} +private final int jjMoveNfa_0(int startState, int curPos) +{ + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 3; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + kind = 6; + jjCheckNAdd(2); + break; + case 1: + if ((0x280000000000L & l) != 0L) + kind = 5; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x2000000020L & l) == 0L) + break; + kind = 5; + jjstateSet[jjnewStateCnt++] = 1; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (int)(curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +private final int jjStopStringLiteralDfa_2(int pos, long active0) +{ + switch (pos) + { + default : + return -1; + } +} +private final int jjStartNfa_2(int pos, long active0) +{ + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); +} +private final int jjStartNfaWithStates_2(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_2(state, pos + 1); +} +private final int jjMoveStringLiteralDfa0_2() +{ + switch(curChar) + { + case 117: + return jjStopAtPos(0, 12); + default : + return jjMoveNfa_2(0, 0); + } +} +private final int jjMoveNfa_2(int startState, int curPos) +{ + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 1; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x800400000000L & l) != 0L) + kind = 11; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0x14404410000000L & l) != 0L) + kind = 11; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (int)(curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +private final int jjStopStringLiteralDfa_1(int pos, long active0) +{ + switch (pos) + { + default : + return -1; + } +} +private final int jjStartNfa_1(int pos, long active0) +{ + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); +} +private final int jjStartNfaWithStates_1(int pos, int kind, int state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return pos + 1; } + return jjMoveNfa_1(state, pos + 1); +} +private final int jjMoveStringLiteralDfa0_1() +{ + switch(curChar) + { + case 92: + return jjStopAtPos(0, 8); + default : + return jjMoveNfa_1(0, 0); + } +} +static final long[] jjbitVec0 = { + 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +static final long[] jjbitVec2 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL +}; +private final int jjMoveNfa_1(int startState, int curPos) +{ + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 2; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + long l = 1L << curChar; + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0xfffffffbffffffffL & l) != 0L) + { + if (kind > 10) + kind = 10; + } + else if (curChar == 34) + { + if (kind > 9) + kind = 9; + } + break; + case 1: + if ((0xfffffffbffffffffL & l) != 0L) + kind = 10; + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + long l = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if ((0xffffffffefffffffL & l) != 0L) + kind = 10; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int hiByte = (int)(curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: do + { + switch(jjstateSet[--i]) + { + case 0: + if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 10) + kind = 10; + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 2 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { return curPos; } + } +} +static final int[] jjnextStates = { +}; +private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec2[i2] & l2) != 0L); + default : + if ((jjbitVec0[i1] & l1) != 0L) + return true; + return false; + } +} +public static final String[] jjstrLiteralImages = { +"", null, null, null, null, null, null, "\42", null, null, null, null, null, +null, null, "\173", "\175", "\156\165\154\154", "\54", "\72", "\133", "\135", +"\164\162\165\145", "\146\141\154\163\145", "\55", "\56", }; +public static final String[] lexStateNames = { + "DEFAULT", + "STRING_STATE", + "ESC_STATE", + "HEX_STATE", +}; +public static final int[] jjnewLexState = { + -1, -1, -1, -1, -1, -1, -1, 1, 2, 0, -1, 1, 3, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, +}; +static final long[] jjtoToken = { + 0x3ffcee1L, +}; +static final long[] jjtoSkip = { + 0x1eL, +}; +static final long[] jjtoMore = { + 0x1100L, +}; +protected SimpleCharStream input_stream; +private final int[] jjrounds = new int[4]; +private final int[] jjstateSet = new int[8]; +protected char curChar; +public JsonParserTokenManager(SimpleCharStream stream){ + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; +} +public JsonParserTokenManager(SimpleCharStream stream, int lexState){ + this(stream); + SwitchTo(lexState); +} +public void ReInit(SimpleCharStream stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); +} +private final void ReInitRounds() +{ + int i; + jjround = 0x80000001; + for (i = 4; i-- > 0;) + jjrounds[i] = 0x80000000; +} +public void ReInit(SimpleCharStream stream, int lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} +public void SwitchTo(int lexState) +{ + if (lexState >= 4 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; +} + +protected Token jjFillToken() +{ + Token t = Token.newToken(jjmatchedKind); + t.kind = jjmatchedKind; + String im = jjstrLiteralImages[jjmatchedKind]; + t.image = (im == null) ? input_stream.GetImage() : im; + t.beginLine = input_stream.getBeginLine(); + t.beginColumn = input_stream.getBeginColumn(); + t.endLine = input_stream.getEndLine(); + t.endColumn = input_stream.getEndColumn(); + return t; +} + +int curLexState = 0; +int defaultLexState = 0; +int jjnewStateCnt; +int jjround; +int jjmatchedPos; +int jjmatchedKind; + +public Token getNextToken() +{ + int kind; + Token specialToken = null; + Token matchedToken; + int curPos = 0; + + EOFLoop : + for (;;) + { + try + { + curChar = input_stream.BeginToken(); + } + catch(java.io.IOException e) + { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + + for (;;) + { + switch(curLexState) + { + case 0: + try { input_stream.backup(0); + while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L) + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e1) { continue EOFLoop; } + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + break; + case 1: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_1(); + break; + case 2: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_2(); + break; + case 3: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_3(); + break; + } + if (jjmatchedKind != 0x7fffffff) + { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + matchedToken = jjFillToken(); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + return matchedToken; + } + else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) + { + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + continue EOFLoop; + } + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + curPos = 0; + jjmatchedKind = 0x7fffffff; + try { + curChar = input_stream.readChar(); + continue; + } + catch (java.io.IOException e1) { } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { input_stream.readChar(); input_stream.backup(1); } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } + else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } + } +} + +} diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java new file mode 100644 index 00000000..b968e571 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -0,0 +1,282 @@ +/* + * 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.google.gson; + +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 + */ +public final class JsonPrimitive extends JsonElement { + + private Object value; + + /** + * Create a primitive containing a boolean value. + * + * @param bool the value to create the primitive with. + */ + public JsonPrimitive(Boolean bool) { + this.value = bool; + } + + /** + * Create a primitive containing a {@link Number}. + * + * @param number the value to create the primitive with. + */ + public JsonPrimitive(Number number) { + this.value = number; + } + + /** + * Create a primitive containing a String value. + * + * @param string the value to create the primitive with. + */ + public JsonPrimitive(String string) { + this.value = 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) { + this.value = String.valueOf(c); + } + + /** + * 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(char c) { + this.value = String.valueOf(c); + } + + /** + * Create a primitive using the specified Object. It must be an instance of {@link Number}, a + * Java primitive type, or a String. + * + * @param primitive the value to create the primitive with. + */ + JsonPrimitive(Object primitive) { + setValue(primitive); + } + + void setValue(Object primitive) { + if (primitive instanceof Character) { + // convert characters to strings since in JSON, characters are represented as a single + // character string + char c = ((Character)primitive).charValue(); + this.value = String.valueOf(c); + } else { + Preconditions.checkArgument(primitive instanceof Number + || ObjectNavigator.isPrimitiveOrString(primitive)); + this.value = primitive; + } + } + + /** + * Check whether this primitive contains a boolean value. + * + * @return true if this primitive contains a boolean value, false otherwise. + */ + public boolean isBoolean() { + return value instanceof Boolean; + } + + /** + * convenience method to get this element as a {@link Boolean}. + * + * @return get this element as a {@link Boolean}. + * @throws ClassCastException if the value contained is not a valid boolean value. + */ + @Override + Boolean getAsBooleanWrapper() { + return (Boolean) value; + } + + /** + * convenience method to get this element as a boolean value. + * + * @return get this element as a primitive boolean value. + * @throws ClassCastException if the value contained is not a valid boolean value. + */ + @Override + public boolean getAsBoolean() { + return ((Boolean) value).booleanValue(); + } + + /** + * Check whether this primitive contains a Number. + * + * @return true if this primitive contains a Number, false otherwise. + */ + public boolean isNumber() { + return value instanceof Number; + } + + /** + * convenience method to get this element as a Number. + * + * @return get this element as a Number. + * @throws ClassCastException if the value contained is not a valid Number. + */ + @Override + public Number getAsNumber() { + return (Number) value; + } + + /** + * Check whether this primitive contains a String value. + * + * @return true if this primitive contains a String value, false otherwise. + */ + public boolean isString() { + return value instanceof String; + } + + /** + * convenience method to get this element as a String. + * + * @return get this element as a String. + * @throws ClassCastException if the value contained is not a valid String. + */ + @Override + public String getAsString() { + return (String) value; + } + + /** + * convenience method to get this element as a primitive double. + * + * @return get this element as a primitive double. + * @throws ClassCastException if the value contained is not a valid double. + */ + @Override + public double getAsDouble() { + return ((Number) value).doubleValue(); + } + + /** + * 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() { + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } else { + return 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() { + if (value instanceof BigInteger) { + return (BigInteger) value; + } else { + return new BigInteger(value.toString()); + } + } + + /** + * convenience method to get this element as a float. + * + * @return get this element as a float. + * @throws ClassCastException if the value contained is not a valid float. + */ + @Override + public float getAsFloat() { + return ((Number) value).floatValue(); + } + + /** + * convenience method to get this element as a primitive long. + * + * @return get this element as a primitive long. + * @throws ClassCastException if the value contained is not a valid long. + */ + @Override + public long getAsLong() { + return ((Number) value).longValue(); + } + + /** + * convenience method to get this element as a primitive short. + * + * @return get this element as a primitive short. + * @throws ClassCastException if the value contained is not a valid short value. + */ + @Override + public short getAsShort() { + return ((Number) value).shortValue(); + } + + /** + * convenience method to get this element as a primitive integer. + * + * @return get this element as a primitive integer. + * @throws ClassCastException if the value contained is not a valid integer. + */ + @Override + public int getAsInt() { + return ((Number) value).intValue(); + } + + /** + * 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() { + return value; + } + + @Override + protected void toString(StringBuilder sb) { + if (value != null) { + if (value instanceof String) { + sb.append('"'); + sb.append(value); + sb.append('"'); + + } else { + sb.append(value); + } + } + } +} diff --git a/gson/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java b/gson/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java new file mode 100644 index 00000000..011774f6 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonPrimitiveDeserializationVisitor.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * A visitor that populates a primitive value from its JSON representation + * + * @author Inderjeet Singh + */ +final class JsonPrimitiveDeserializationVisitor extends JsonDeserializationVisitor { + + JsonPrimitiveDeserializationVisitor(JsonPrimitive json, Type type, + ObjectNavigatorFactory factory, ObjectConstructor objectConstructor, + TypeAdapter typeAdapter, ParameterizedTypeHandlerMap> deserializers, + JsonDeserializationContext context) { + super(json, type, factory, objectConstructor, typeAdapter, deserializers, context); + } + + @Override + @SuppressWarnings("unchecked") + protected T constructTarget() { + return (T) objectConstructor.construct(targetType); + } + + public void startVisitingObject(Object node) { + // do nothing + } + + public void endVisitingObject(Object node) { + // do nothing + } + + public void visitCollection(@SuppressWarnings("unchecked")Collection collection, + Type componentType) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitArray(Object array, Type componentType) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + @SuppressWarnings("unchecked") + public void visitPrimitiveValue(Object obj) { + JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive(); + if (jsonPrimitive.isBoolean()) { + target = (T) jsonPrimitive.getAsBooleanWrapper(); + } else if (jsonPrimitive.isNumber()) { + target = (T) jsonPrimitive.getAsNumber(); + } else if (jsonPrimitive.isString()) { + target = (T) jsonPrimitive.getAsString(); + } else { + throw new IllegalStateException(); + } + } + + public void visitObjectField(Field f, Type typeOfF, Object obj) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitCollectionField(Field f, Type typeOfF, Object obj) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitArrayField(Field f, Type typeOfF, Object obj) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } + + public void visitPrimitiveField(Field f, Type fType, Object obj) { + // should not be called since this case should invoke JsonArrayDeserializationVisitor + throw new IllegalStateException(); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonPrintFormatter.java b/gson/src/main/java/com/google/gson/JsonPrintFormatter.java new file mode 100644 index 00000000..d1a1b114 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonPrintFormatter.java @@ -0,0 +1,235 @@ +/* + * 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.google.gson; + +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; + +/** + * Formats Json in a nicely indented way with a specified print margin. + * This printer tries to keep elements on the same line as much as possible + * while respecting right margin. + * + * @author Inderjeet Singh + */ +final class JsonPrintFormatter implements JsonFormatter { + + private final int printMargin; + private final int indentationSize; + private final int rightMargin; + + public static final int DEFAULT_PRINT_MARGIN = 80; + public static final int DEFAULT_INDENTATION_SIZE = 2; + public static final int DEFAULT_RIGHT_MARGIN = 4; + + public JsonPrintFormatter() { + this(DEFAULT_PRINT_MARGIN, DEFAULT_INDENTATION_SIZE, DEFAULT_RIGHT_MARGIN); + } + + public JsonPrintFormatter(int printMargin, int indentationSize, int rightMargin) { + this.printMargin = printMargin; + this.indentationSize = indentationSize; + this.rightMargin = rightMargin; + } + + private class JsonWriter { + private final PrintWriter writer; + private StringBuilder line; + private int level; + JsonWriter(PrintWriter writer) { + this.writer = writer; + level = 0; + line = new StringBuilder(); + } + + void key(String key) { + getLine().append('"'); + getLine().append(key); + getLine().append('"'); + } + + void value(String value) { + getLine().append(value); + } + + void fieldSeparator() { + getLine().append(':'); + breakLineIfNeeded(); + } + + void elementSeparator() { + getLine().append(','); + breakLineIfNeeded(); + } + + void beginObject() { + ++level; + breakLineIfNeeded(); + getLine().append('{'); + } + + void endObject() { + getLine().append('}'); + --level; + } + + void beginArray() { + ++level; + breakLineIfNeeded(); + getLine().append('['); + } + + void endArray() { + getLine().append(']'); + --level; + } + + private void breakLineIfNeeded() { + if (getLine().length() > printMargin - rightMargin) { + finishLine(); + } + } + + private void finishLine() { + if (line != null) { + writer.append(line).append("\n"); + } + line = null; + } + + private StringBuilder getLine() { + if (line == null) { + createNewLine(); + } + return line; + } + + private void createNewLine() { + line = new StringBuilder(); + for (int i = 0; i < level; ++i) { + for (int j = 0; j < indentationSize; ++j) { + line.append(' '); + } + } + } + } + + private class PrintFormattingVisitor implements JsonElementVisitor { + private final Map first; + private final JsonWriter writer; + private final boolean serializeNulls; + private int level = 0; + + PrintFormattingVisitor(JsonWriter writer, boolean serializeNulls) { + this.writer = writer; + this.serializeNulls = serializeNulls; + this.first = new HashMap(); + } + + private void addCommaCheckingFirst() { + if (first.get(level) != Boolean.FALSE) { + first.put(level, false); + } else { + writer.elementSeparator(); + } + } + + public void startArray(JsonArray array) { + first.put(++level, true); + writer.beginArray(); + } + + public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) { + addCommaCheckingFirst(); + writer.value(member.toString()); + } + + public void visitArrayMember(JsonArray parent, JsonArray member, boolean first) { + addCommaCheckingFirst(); + } + + public void visitArrayMember(JsonArray parent, JsonObject member, boolean first) { + addCommaCheckingFirst(); + } + + public void visitNullArrayMember(JsonArray parent, boolean isFirst) { + addCommaCheckingFirst(); + } + + public void endArray(JsonArray array) { + level--; + writer.endArray(); + } + + public void startObject(JsonObject object) { + writer.beginObject(); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonPrimitive member, + boolean isFirst) { + addCommaCheckingFirst(); + writer.key(memberName); + writer.fieldSeparator(); + writer.value(member.toString()); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonArray member, + boolean isFirst) { + addCommaCheckingFirst(); + writer.key(memberName); + writer.fieldSeparator(); + } + + public void visitObjectMember(JsonObject parent, String memberName, JsonObject member, + boolean isFirst) { + addCommaCheckingFirst(); + writer.key(memberName); + writer.fieldSeparator(); + } + + public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) { + if (serializeNulls) { + visitObjectMember(parent, memberName, (JsonObject) null, isFirst); + } + } + + public void endObject(JsonObject object) { + writer.endObject(); + } + + public void visitPrimitive(JsonPrimitive primitive) { + writer.value(primitive.toString()); + } + + public void visitNull() { + writer.value("null"); + } + } + + public void format(JsonElement root, PrintWriter writer, boolean serializeNulls) { + if (root == null) { + return; + } + JsonWriter jsonWriter = new JsonWriter(writer); + JsonElementVisitor visitor = + new JsonEscapingVisitor(new PrintFormattingVisitor(jsonWriter, serializeNulls)); + JsonTreeNavigator navigator = new JsonTreeNavigator(visitor, serializeNulls); + navigator.navigate(root); + jsonWriter.finishLine(); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonSerializationContext.java b/gson/src/main/java/com/google/gson/JsonSerializationContext.java new file mode 100644 index 00000000..81bd5c92 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonSerializationContext.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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 + */ +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); +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/JsonSerializationContextDefault.java b/gson/src/main/java/com/google/gson/JsonSerializationContextDefault.java new file mode 100644 index 00000000..747c771b --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonSerializationContextDefault.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Type; + +/** + * An implementation of serialization context for Gson. + * + * @author Inderjeet Singh + */ +final class JsonSerializationContextDefault implements JsonSerializationContext { + + private final ObjectNavigatorFactory factory; + private final ParameterizedTypeHandlerMap> serializers; + private final boolean serializeNulls; + + JsonSerializationContextDefault(ObjectNavigatorFactory factory, boolean serializeNulls, + ParameterizedTypeHandlerMap> serializers) { + this.factory = factory; + this.serializeNulls = serializeNulls; + this.serializers = serializers; + } + + public JsonElement serialize(Object src) { + return serialize(src, src.getClass()); + } + + public JsonElement serialize(Object src, Type typeOfSrc) { + ObjectNavigator on = factory.create(src, typeOfSrc); + JsonSerializationVisitor visitor = + new JsonSerializationVisitor(factory, serializeNulls, serializers, this); + on.accept(visitor); + return visitor.getJsonElement(); + } +} diff --git a/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java new file mode 100644 index 00000000..c0ef82a0 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonSerializationVisitor.java @@ -0,0 +1,203 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +/** + * A visitor that adds JSON elements corresponding to each field of an object + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class JsonSerializationVisitor implements ObjectNavigator.Visitor { + + private final ObjectNavigatorFactory factory; + private final ParameterizedTypeHandlerMap> serializers; + private final boolean serializeNulls; + + private final JsonSerializationContext context; + + private JsonElement root; + + JsonSerializationVisitor(ObjectNavigatorFactory factory, boolean serializeNulls, + ParameterizedTypeHandlerMap> serializers, + JsonSerializationContext context) { + this.factory = factory; + this.serializeNulls = serializeNulls; + this.serializers = serializers; + this.context = context; + } + + public void endVisitingObject(Object node) { + // nothing to be done here + } + + public void startVisitingObject(Object node) { + assignToRoot(new JsonObject()); + } + + public void visitArray(Object array, Type arrayType) { + assignToRoot(new JsonArray()); + int length = Array.getLength(array); + TypeInfoArray fieldTypeInfo = TypeInfoFactory.getTypeInfoForArray(arrayType); + Type componentType = fieldTypeInfo.getSecondLevelType(); + for (int i = 0; i < length; ++i) { + Object child = Array.get(array, i); + addAsArrayElement(componentType, child); + } + } + + @SuppressWarnings("unchecked") + public void visitCollection(Collection collection, Type collectionType) { + assignToRoot(new JsonArray()); + for (Object child : collection) { + Type childType = TypeUtils.getActualTypeForFirstTypeVariable(collectionType); + if (childType == Object.class && child != null) { + // Try our luck some other way + childType = child.getClass(); + } + addAsArrayElement(childType, child); + } + } + + public void visitArrayField(Field f, Type typeOfF, Object obj) { + if (!isFieldNull(f, obj)) { + Object array = getFieldValue(f, obj); + addAsChildOfObject(f, typeOfF, array); + } + } + + public void visitCollectionField(Field f, Type typeOfF, Object obj) { + if (!isFieldNull(f, obj)) { + if (typeOfF == null) { + throw new RuntimeException("Can not handle non-generic collections"); + } + Object collection = getFieldValue(f, obj); + addAsChildOfObject(f, typeOfF, collection); + } + } + + @SuppressWarnings("unchecked") + public void visitEnum(Object obj, Type objType) { + JsonSerializer serializer = serializers.getHandlerFor(objType); + if (serializer == null) { + serializer = serializers.getHandlerFor(Enum.class); + } + if (serializer == null) { + throw new RuntimeException("Register a JsonSerializer for Enum or " + + obj.getClass().getName()); + } + assignToRoot(serializer.serialize(obj, objType, context)); + } + + public void visitObjectField(Field f, Type typeOfF, Object obj) { + if (isFieldNull(f, obj)) { + if (serializeNulls) { + addChildAsElement(f, new JsonNull()); + } + } else { + Object fieldValue = getFieldValue(f, obj); + addAsChildOfObject(f, typeOfF, fieldValue); + } + } + + private void addAsChildOfObject(Field f, Type fieldType, Object fieldValue) { + JsonElement childElement = getJsonElementForChild(fieldType, fieldValue); + addChildAsElement(f, childElement); + } + + private void addChildAsElement(Field f, JsonElement childElement) { + FieldNamingStrategy namingPolicy = factory.getFieldNamingPolicy(); + root.getAsJsonObject().add(namingPolicy.translateName(f), childElement); + } + + private void addAsArrayElement(Type elementType, Object elementValue) { + if (elementValue == null) { + addNullAsArrayElement(); + } else { + JsonElement childElement = getJsonElementForChild(elementType, elementValue); + root.getAsJsonArray().add(childElement); + } + } + + private void addNullAsArrayElement() { + root.getAsJsonArray().add(null); + } + + private JsonElement getJsonElementForChild(Type fieldType, Object fieldValue) { + ObjectNavigator on = factory.create(fieldValue, fieldType); + JsonSerializationVisitor childVisitor = + new JsonSerializationVisitor(factory, serializeNulls, serializers, context); + on.accept(childVisitor); + return childVisitor.getJsonElement(); + } + + public void visitPrimitiveField(Field f, Type typeOfF, Object obj) { + if (!isFieldNull(f, obj)) { + TypeInfo typeInfo = new TypeInfo(typeOfF); + if (typeInfo.isPrimitiveOrStringAndNotAnArray()) { + Object fieldValue = getFieldValue(f, obj); + addAsChildOfObject(f, typeOfF, fieldValue); + } else { + throw new IllegalArgumentException("Not a primitive type"); + } + } + } + + public void visitPrimitiveValue(Object obj) { + assignToRoot(new JsonPrimitive(obj)); + } + + @SuppressWarnings("unchecked") + public boolean visitUsingCustomHandler(Object obj, Type objType) { + JsonSerializer serializer = serializers.getHandlerFor(objType); + if (serializer == null && obj instanceof Map) { + serializer = serializers.getHandlerFor(Map.class); + } + if (serializer != null) { + assignToRoot(serializer.serialize(obj, objType, context)); + return true; + } + return false; + } + + private void assignToRoot(JsonElement newRoot) { + Preconditions.checkArgument(root == null); + root = newRoot; + } + + private boolean isFieldNull(Field f, Object obj) { + return getFieldValue(f, obj) == null; + } + + private Object getFieldValue(Field f, Object obj) { + try { + return f.get(obj); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public JsonElement getJsonElement() { + return root; + } +} diff --git a/gson/src/main/java/com/google/gson/JsonSerializer.java b/gson/src/main/java/com/google/gson/JsonSerializer.java new file mode 100644 index 00000000..9b223c48 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonSerializer.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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.google.gson.GsonBuilder#registerTypeAdapter(Type, Object)}. + * + *

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}.

+ * + *

+ * 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;
+ *   }
+ * }
+ * 

+ * + *

The default serialization of {@code Id(com.foo.MyObject.class, 20L)} will be + * {"clazz":com.foo.MyObject,"value":20}. 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:

+ * + *

+ * class IdSerializer implements JsonSerializer<Id>() {
+ *   public JsonElement toJson(Id id, Type typeOfId, JsonSerializationContext context) {
+ *     return new JsonPrimitive(id.getValue());
+ *   }
+ * }
+ * 

+ * + *

You will also need to register {@code IdSerializer} with Gson as follows:

+ *
+ * Gson gson = new GsonBuilder().registerTypeAdapter(Id.class, new IdSerializer()).create();
+ * 
+ * + * @author Inderjeet Singh + * @author Joel Leitch + * + * @param 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 { + + /** + * Gson invokes this call-back method during serialization when it encounters a field of the + * specified type. + * + *

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).

+ * + * @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); +} diff --git a/gson/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java b/gson/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java new file mode 100644 index 00000000..ab4b769a --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonSerializerExceptionWrapper.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Type; + +/** + * Decorators a {@code JsonSerializer} instance with exception handling. This wrapper class + * ensures that a {@code JsonSerializer} will not propagate any exception other than a + * {@link JsonParseException}. + * + * @param type of the serializer being wrapped. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +class JsonSerializerExceptionWrapper implements JsonSerializer { + private final JsonSerializer delegate; + + /** + * Returns a wrapped {@link JsonSerializer} object that has been decorated with + * {@link JsonParseException} handling. + * + * @param delegate the {@code JsonSerializer} instance to be wrapped + * @throws IllegalArgumentException if {@code delegate} is {@code null}. + */ + JsonSerializerExceptionWrapper(JsonSerializer delegate) { + Preconditions.checkNotNull(delegate); + this.delegate = delegate; + } + + public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { + try { + return delegate.serialize(src, typeOfSrc, context); + } catch (JsonParseException e) { + // just rethrow the exception + throw e; + } catch (Exception e) { + // throw as a JsonParseException + StringBuilder errorMsg = new StringBuilder() + .append("The JsonSerializer ") + .append(delegate) + .append(" failed to serialized object ") + .append(src) + .append(" given the type ") + .append(typeOfSrc); + throw new JsonParseException(errorMsg.toString(), e); + } + } +} diff --git a/gson/src/main/java/com/google/gson/JsonTreeNavigator.java b/gson/src/main/java/com/google/gson/JsonTreeNavigator.java new file mode 100644 index 00000000..61080a65 --- /dev/null +++ b/gson/src/main/java/com/google/gson/JsonTreeNavigator.java @@ -0,0 +1,102 @@ +/* + * 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.google.gson; + +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) { + if (element == null || 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 member : object.entrySet()) { + visitChild(object, member.getKey(), member.getValue(), isFirst); + if (isFirst) { + isFirst = false; + } + } + visitor.endObject(object); + } else { // must be JsonPrimitive + visitor.visitPrimitive(element.getAsJsonPrimitive()); + } + } + + private void visitChild(JsonObject parent, String childName, JsonElement child, boolean isFirst) { + if (child != null) { + if (child.isJsonNull()) { + if (visitNulls) { + visitor.visitNullObjectMember(parent, childName, isFirst); + navigate(child.getAsJsonNull()); + } + } 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); + } + } + } + + private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) { + if (child == null || child.isJsonNull()) { + visitor.visitNullArrayMember(parent, isFirst); + navigate(null); + } 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); + } + } +} diff --git a/gson/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java b/gson/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java new file mode 100644 index 00000000..475291bf --- /dev/null +++ b/gson/src/main/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicy.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only + * lower case letters and are separated by a particular {@code separatorString}. + * + *

The following is an example:

+ *
+ * class StringWrapper {
+ *   public String AStringField = "abcd";
+ * }
+ *
+ * LowerCamelCaseSeparatorNamingPolicy policy = new LowerCamelCaseSeparatorNamingPolicy("_");
+ * String translatedFieldName =
+ *     policy.translateName(StringWrapper.class.getField("AStringField"));
+ *
+ * assert("a_string_field".equals(translatedFieldName));
+ * 
+ * + * @author Joel Leitch + */ +class LowerCamelCaseSeparatorNamingPolicy extends CompositionFieldNamingPolicy { + + public LowerCamelCaseSeparatorNamingPolicy(String separatorString) { + super(new CamelCaseSeparatorNamingPolicy(separatorString), new LowerCaseNamingPolicy()); + } +} diff --git a/gson/src/main/java/com/google/gson/LowerCaseNamingPolicy.java b/gson/src/main/java/com/google/gson/LowerCaseNamingPolicy.java new file mode 100644 index 00000000..bcc20607 --- /dev/null +++ b/gson/src/main/java/com/google/gson/LowerCaseNamingPolicy.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only + * lower case letters. + * + *

The following is an example:

+ *
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * LowerCaseNamingPolicy policy = new LowerCaseNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("integerfield".equals(translatedFieldName));
+ * 
+ * + * @author Joel Leitch + */ +class LowerCaseNamingPolicy extends RecursiveFieldNamingPolicy { + + @Override + protected String translateName(String target, Type fieldType, Annotation[] annotations) { + return target.toLowerCase(); + } +} diff --git a/gson/src/main/java/com/google/gson/MappedObjectConstructor.java b/gson/src/main/java/com/google/gson/MappedObjectConstructor.java new file mode 100644 index 00000000..fb10117a --- /dev/null +++ b/gson/src/main/java/com/google/gson/MappedObjectConstructor.java @@ -0,0 +1,109 @@ +/* + * 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.google.gson; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * This class contains a mapping of all the application specific + * {@link InstanceCreator} instances. Registering an {@link InstanceCreator} + * with this class will override the default object creation that is defined + * by the ObjectConstructor that this class is wrapping. Using this class + * with the JSON framework provides the application with "pluggable" modules + * to customize framework to suit the application's needs. + * + * @author Joel Leitch + */ +final class MappedObjectConstructor implements ObjectConstructor { + private final Logger log = Logger.getLogger(getClass().getName()); + + private final ParameterizedTypeHandlerMap> instanceCreatorMap = + new ParameterizedTypeHandlerMap>(); + + @SuppressWarnings("unchecked") + public T construct(Type typeOfT) { + if (instanceCreatorMap.hasAnyHandlerFor(typeOfT)) { + InstanceCreator creator = (InstanceCreator) instanceCreatorMap.getHandlerFor(typeOfT); + return creator.createInstance(typeOfT); + } + TypeInfo typeInfo = new TypeInfo(typeOfT); + if (typeInfo.isEnum()) { + InstanceCreator creator = + (InstanceCreator) instanceCreatorMap.getHandlerFor(Enum.class); + return creator.createInstance(typeOfT); + } + return (T) constructWithNoArgConstructor(typeOfT); + } + + public Object constructArray(Type type, int length) { + return Array.newInstance(TypeUtils.toRawClass(type), length); + } + + private T constructWithNoArgConstructor(Type typeOfT) { + try { + Constructor constructor = getNoArgsConstructor(typeOfT); + if (constructor == null) { + throw new RuntimeException(("No-args constructor for " + typeOfT + " does not exist. " + + "Register an InstanceCreator with Gson for this type to fix this problem.")); + } + return constructor.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". " + + "Register an InstanceCreator with Gson for this type may fix this problem."), e); + } catch (IllegalAccessException e) { + throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". " + + "Register an InstanceCreator with Gson for this type may fix this problem."), e); + } catch (InvocationTargetException e) { + throw new RuntimeException(("Unable to invoke no-args constructor for " + typeOfT + ". " + + "Register an InstanceCreator with Gson for this type may fix this problem."), e); + } + } + + @SuppressWarnings({"unchecked", "cast"}) + private Constructor getNoArgsConstructor(Type typeOfT) { + TypeInfo typeInfo = new TypeInfo(typeOfT); + Class clazz = (Class) typeInfo.getRawClass(); + Constructor[] declaredConstructors = (Constructor[]) clazz.getDeclaredConstructors(); + AccessibleObject.setAccessible(declaredConstructors, true); + for (Constructor constructor : declaredConstructors) { + if (constructor.getParameterTypes().length == 0) { + return constructor; + } + } + return null; + } + + /** + * Use this methods to register an {@link InstanceCreator} for a new type. + * + * @param the type of class to be mapped with its "creator" + * @param typeOfT the instance type that will be created + * @param creator the {@link InstanceCreator} instance to register + */ + void register(Type typeOfT, InstanceCreator creator) { + if (instanceCreatorMap.hasSpecificHandlerFor(typeOfT)) { + log.log(Level.WARNING, "Overriding the existing InstanceCreator for " + typeOfT); + } + instanceCreatorMap.register(typeOfT, creator); + } +} diff --git a/gson/src/main/java/com/google/gson/MemoryRefStack.java b/gson/src/main/java/com/google/gson/MemoryRefStack.java new file mode 100644 index 00000000..72d7e126 --- /dev/null +++ b/gson/src/main/java/com/google/gson/MemoryRefStack.java @@ -0,0 +1,82 @@ +/* + * 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.google.gson; + +import java.util.Stack; + +/** + * A stack data structure that only does a memory reference comparison + * when looking for a particular item in the stack. This stack does + * not allow {@code null} values to be added. + * + * @author Joel Leitch + */ +final class MemoryRefStack { + private final Stack stack = new Stack(); + + /** + * 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 T push(T obj) { + Preconditions.checkNotNull(obj); + + return stack.push(obj); + } + + /** + * Removes the top element from the stack. + * + * @return the element being removed from the stack + * @throws java.util.EmptyStackException thrown if the stack is empty + */ + public T pop() { + return stack.pop(); + } + + /** + * 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 T 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(T obj) { + if (obj == null) { + return false; + } + + for (T stackObject : stack) { + if (obj == stackObject) { + return true; + } + } + return false; + } +} diff --git a/gson/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java b/gson/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java new file mode 100644 index 00000000..d64457f1 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ModifierBasedExclusionStrategy.java @@ -0,0 +1,60 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Field; +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 boolean skipSyntheticField; + private final Collection modifiers; + + public ModifierBasedExclusionStrategy(boolean skipSyntheticFields, int... modifiers) { + this.skipSyntheticField = skipSyntheticFields; + this.modifiers = new HashSet(); + if (modifiers != null) { + for (int modifier : modifiers) { + this.modifiers.add(modifier); + } + } + } + + public boolean shouldSkipField(Field f) { + if (skipSyntheticField && f.isSynthetic()) { + return true; + } + int objectModifiers = f.getModifiers(); + for (int modifier : modifiers) { + if ((objectModifiers & modifier) != 0) { + return true; + } + } + return false; + } + + public boolean shouldSkipClass(Class clazz) { + return false; + } +} diff --git a/gson/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java b/gson/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java new file mode 100644 index 00000000..768d6616 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ModifyFirstLetterNamingPolicy.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * A {@link FieldNamingStrategy} that ensures the JSON field names begins with + * an upper case letter. + * + *

The following is an example:

+ *
+ * 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));
+ * 
+ * + * @author Joel Leitch + */ +class ModifyFirstLetterNamingPolicy extends RecursiveFieldNamingPolicy { + + public enum LetterModifier { + UPPER, + LOWER; + } + + private final LetterModifier letterModifier; + + /** + * Creates a new ModifyFirstLetterNamingPolicy that will either modify the first letter of the + * target name to either UPPER case or LOWER case depending on the {@code modifier} parameter. + * + * @param modifier the type of modification that should be performed + * @throws IllegalArgumentException if {@code modifier} is null + */ + public ModifyFirstLetterNamingPolicy(LetterModifier modifier) { + Preconditions.checkNotNull(modifier); + this.letterModifier = modifier; + } + + @Override + protected String translateName(String target, Type fieldType, 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) { + if (indexOfSubstring < srcString.length()) { + return firstCharacter + srcString.substring(indexOfSubstring); + } else { + return String.valueOf(firstCharacter); + } + } +} diff --git a/gson/src/main/java/com/google/gson/NullExclusionStrategy.java b/gson/src/main/java/com/google/gson/NullExclusionStrategy.java new file mode 100644 index 00000000..38b9a44b --- /dev/null +++ b/gson/src/main/java/com/google/gson/NullExclusionStrategy.java @@ -0,0 +1,38 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Field; + +/** + * 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(Field f) { + return false; + } + + public boolean shouldSkipClass(Class clazz) { + return false; + } +} diff --git a/gson/src/main/java/com/google/gson/ObjectConstructor.java b/gson/src/main/java/com/google/gson/ObjectConstructor.java new file mode 100644 index 00000000..67973e9f --- /dev/null +++ b/gson/src/main/java/com/google/gson/ObjectConstructor.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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 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); +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/ObjectNavigator.java b/gson/src/main/java/com/google/gson/ObjectNavigator.java new file mode 100644 index 00000000..79eeaaec --- /dev/null +++ b/gson/src/main/java/com/google/gson/ObjectNavigator.java @@ -0,0 +1,202 @@ +/* + * 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.google.gson; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * 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 { + /** + * This is called before the object navigator starts visiting the current object + */ + void startVisitingObject(Object node); + + /** + * This is called after the object navigator finishes visiting the current object + */ + void endVisitingObject(Object node); + + /** + * This is called to visit the current object if it is an iterable + * + * @param componentType the type of each element of the component + */ + void visitCollection(@SuppressWarnings("unchecked") Collection collection, Type componentType); + + /** + * This is called to visit the current object if it is an array + */ + void visitArray(Object array, Type componentType); + + /** + * This is called to visit the current object if it is a primitive + */ + void visitPrimitiveValue(Object obj); + + /** + * This is called to visit an object field of the current object + */ + void visitObjectField(Field f, Type typeOfF, Object obj); + + /** + * This is called to visit a field of type Collection of the current object + */ + void visitCollectionField(Field f, Type typeOfF, Object obj); + + /** + * This is called to visit an array field of the current object + */ + void visitArrayField(Field f, Type typeOfF, Object obj); + + /** + * This is called to visit a primitive field of the current object + */ + void visitPrimitiveField(Field f, Type typeOfF, Object obj); + + /** + * This is called to visit an enum object + */ + public void visitEnum(Object obj, Type objType); + + /** + * This is called to visit an object using a custom handler + * @return true if a custom handler exists, false otherwise + */ + public boolean visitUsingCustomHandler(Object obj, Type objType); + } + + private final ExclusionStrategy exclusionStrategy; + private final MemoryRefStack ancestors; + private final Object obj; + private final Type objType; + + /** + * @param obj The object being navigated + * @param objType The (fully genericized) type of the object being navigated + * @param exclusionStrategy the concrete strategy object to be used to + * filter out fields of an object. + */ + ObjectNavigator(Object obj, Type objType, ExclusionStrategy exclusionStrategy, + MemoryRefStack ancestors) { + Preconditions.checkNotNull(exclusionStrategy); + Preconditions.checkNotNull(ancestors); + + this.obj = obj; + this.objType = objType; + this.exclusionStrategy = exclusionStrategy; + this.ancestors = ancestors; + } + + /** + * Navigate all the fields of the specified object. + * If a field is null, it does not get visited. + */ + public void accept(Visitor visitor) { + if (obj == null) { + return; + } + TypeInfo objTypeInfo = new TypeInfo(objType); + if (exclusionStrategy.shouldSkipClass(objTypeInfo.getRawClass())) { + return; + } + + if (ancestors.contains(obj)) { + throw new IllegalStateException("Circular reference found: " + obj); + } + ancestors.push(obj); + + try { + if (objTypeInfo.isCollectionOrArray()) { + if (objTypeInfo.isArray()) { + visitor.visitArray(obj, objType); + } else { // must be a collection + visitor.visitCollection((Collection) obj, objType); + } + } else if (objTypeInfo.isEnum()) { + visitor.visitEnum(obj, objType); + } else if (objTypeInfo.isPrimitiveOrStringAndNotAnArray()) { + visitor.visitPrimitiveValue(obj); + } else { + if (!visitor.visitUsingCustomHandler(obj, objType)) { + visitor.startVisitingObject(obj); + // For all classes in the inheritance hierarchy (including the current class), + // visit all fields + for (Class curr = objTypeInfo.getRawClass(); + curr != null && !curr.equals(Object.class); curr = curr.getSuperclass()) { + if (!curr.isSynthetic()) { + navigateClassFields(obj, curr, visitor); + } + } + visitor.endVisitingObject(obj); + } + } + } finally { + ancestors.pop(); + } + } + + private void navigateClassFields(Object obj, Class clazz, Visitor visitor) { + Field[] fields = clazz.getDeclaredFields(); + AccessibleObject.setAccessible(fields, true); + for (Field f : fields) { + TypeInfo fieldTypeInfo = TypeInfoFactory.getTypeInfoForField(f, objType); + Type actualTypeOfField = fieldTypeInfo.getActualType(); + if (exclusionStrategy.shouldSkipField(f)) { + continue; // skip + } else if (fieldTypeInfo.isCollectionOrArray()) { + if (fieldTypeInfo.isArray()) { + visitor.visitArrayField(f, actualTypeOfField, obj); + } else { // must be Collection + visitor.visitCollectionField(f, actualTypeOfField, obj); + } + } else if (fieldTypeInfo.isPrimitiveOrStringAndNotAnArray()) { + visitor.visitPrimitiveField(f, actualTypeOfField, obj); + } else { + visitor.visitObjectField(f, actualTypeOfField, obj); + } + } + } + + @SuppressWarnings("unchecked") + private static final Class[] PRIMITIVE_TYPES = { int.class, long.class, short.class, float.class, + double.class, byte.class, boolean.class, Integer.class, Long.class, Short.class, Float.class, + Double.class, Byte.class, Boolean.class }; + + @SuppressWarnings("unchecked") + 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; + } +} diff --git a/gson/src/main/java/com/google/gson/ObjectNavigatorFactory.java b/gson/src/main/java/com/google/gson/ObjectNavigatorFactory.java new file mode 100644 index 00000000..032f9118 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ObjectNavigatorFactory.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Type; + +/** + * A factory class used to simplify {@link ObjectNavigator} creation. + * This object holds on to a reference of the {@link ExclusionStrategy} + * that you'd like to use with the {@link ObjectNavigator}. + * + * @author Joel Leitch + */ +final class ObjectNavigatorFactory { + private final ExclusionStrategy strategy; + private final FieldNamingStrategy fieldNamingPolicy; + private final MemoryRefStack stack; + + /** + * Creates a factory object that will be able to create new + * {@link ObjectNavigator}s with the provided {@code strategy} + * + * @param strategy the exclusion strategy to use with every instance that + * is created by this factory instance. + * @param fieldNamingPolicy the naming policy that should be applied to field + * names + */ + public ObjectNavigatorFactory(ExclusionStrategy strategy, FieldNamingStrategy fieldNamingPolicy) { + Preconditions.checkNotNull(fieldNamingPolicy); + this.strategy = (strategy == null ? new NullExclusionStrategy() : strategy); + this.fieldNamingPolicy = fieldNamingPolicy; + this.stack = new MemoryRefStack(); + } + + /** + * Creates a new {@link ObjectNavigator} for this {@code srcObject}. + * + * @see #create(Object, Type) + * @param srcObject object to navigate + * @return a new instance of a {@link ObjectNavigator} ready to navigate the + * {@code srcObject}. + */ + public ObjectNavigator create(Object srcObject) { + return create(srcObject, srcObject.getClass()); + } + + /** + * Creates a new {@link ObjectNavigator} for this {@code srcObject}, + * {@code type} pair. + * + * @param srcObject object to navigate + * @param type the "actual" type of this {@code srcObject}. NOTE: this can + * be a {@link java.lang.reflect.ParameterizedType} rather than a {@link Class}. + * @return a new instance of a {@link ObjectNavigator} ready to navigate the + * {@code srcObject} while taking into consideration the + * {@code type}. + */ + public ObjectNavigator create(Object srcObject, Type type) { + return new ObjectNavigator(srcObject, type, strategy, stack); + } + + FieldNamingStrategy getFieldNamingPolicy() { + return fieldNamingPolicy; + } +} diff --git a/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java b/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java new file mode 100644 index 00000000..92dee026 --- /dev/null +++ b/gson/src/main/java/com/google/gson/ParameterizedTypeHandlerMap.java @@ -0,0 +1,93 @@ +/* + * 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.google.gson; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; + +/** + * 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 The handler that will be looked up by type + */ +final class ParameterizedTypeHandlerMap { + + private final Map map = new HashMap(); + private boolean modifiable = true; + + public synchronized void register(Type typeOfT, T value) { + if (!modifiable) { + throw new IllegalStateException("Attempted to modify an unmodifiable map."); + } + if (hasSpecificHandlerFor(typeOfT)) { + Gson.logger.log(Level.WARNING, "Overriding the existing type handler for " + typeOfT); + } + map.put(typeOfT, value); + } + + public synchronized void registerIfAbsent(ParameterizedTypeHandlerMap other) { + if (!modifiable) { + throw new IllegalStateException("Attempted to modify an unmodifiable map."); + } + for (Map.Entry entry : other.entrySet()) { + if (!map.containsKey(entry.getKey())) { + register(entry.getKey(), entry.getValue()); + } + } + } + + public synchronized void makeUnmodifiable() { + modifiable = false; + } + + public synchronized T getHandlerFor(Type type) { + T handler = map.get(type); + if (handler == null && type instanceof ParameterizedType) { + // a handler for a non-generic version is registered, so use that + Type rawType = ((ParameterizedType)type).getRawType(); + handler = map.get(rawType); + } + return handler; + } + + public synchronized boolean hasAnyHandlerFor(Type type) { + return getHandlerFor(type) != null; + } + + public synchronized boolean hasSpecificHandlerFor(Type type) { + return map.containsKey(type); + } + + public synchronized ParameterizedTypeHandlerMap copyOf() { + ParameterizedTypeHandlerMap copy = new ParameterizedTypeHandlerMap(); + for (Map.Entry entry : map.entrySet()) { + copy.register(entry.getKey(), entry.getValue()); + } + return copy; + } + + public synchronized Set> entrySet() { + return map.entrySet(); + } +} diff --git a/gson/src/main/java/com/google/gson/ParameterizedTypeImpl.java b/gson/src/main/java/com/google/gson/ParameterizedTypeImpl.java new file mode 100644 index 00000000..25f1bd1c --- /dev/null +++ b/gson/src/main/java/com/google/gson/ParameterizedTypeImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Arrays; + +/** + * An immutable implementation of the {@link ParameterizedType} interface. This object allows + * us to build a reflective {@link Type} objects on demand. This object is used to support + * serialization and deserialization of classes with an {@code ParameterizedType} field where + * as least one of the actual type parameters is a {@code TypeVariable}. + * + *

Here's an example class: + *

+ * class Foo {
+ *   private List someList;
+ *
+ *   Foo(List list) {
+ *     this.someList = list;
+ *   }
+ * }
+ * 
+ * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class ParameterizedTypeImpl implements ParameterizedType { + + private final Type rawType; + private final Type[] actualTypeArguments; + private final Type owner; + + public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type owner) { + this.rawType = rawType; + this.actualTypeArguments = actualTypeArguments; + this.owner = owner; + } + + public Type getRawType() { + return rawType; + } + + public Type[] getActualTypeArguments() { + return actualTypeArguments; + } + + public Type getOwnerType() { + return owner; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ParameterizedType)) { + return false; + } else { + // Check that information is equivalent + ParameterizedType that = (ParameterizedType) o; + if (this == that) + return true; + + Type thatOwner = that.getOwnerType(); + Type thatRawType = that.getRawType(); + + return (owner == null ? thatOwner == null : owner.equals(thatOwner)) + && (rawType == null ? thatRawType == null : rawType.equals(thatRawType)) + && Arrays.equals(actualTypeArguments, that.getActualTypeArguments()); + } + } + + @Override + public int hashCode() { + return Arrays.hashCode(actualTypeArguments) + ^ (owner == null ? 0 : owner.hashCode()) + ^ (rawType == null ? 0 : rawType.hashCode()); + } +} diff --git a/gson/src/main/java/com/google/gson/ParseException.java b/gson/src/main/java/com/google/gson/ParseException.java new file mode 100755 index 00000000..dad01e2b --- /dev/null +++ b/gson/src/main/java/com/google/gson/ParseException.java @@ -0,0 +1,193 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */ +package com.google.gson; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +@SuppressWarnings("all") +final class ParseException extends Exception { + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. The boolean + * flag "specialConstructor" is also set to true to indicate that + * this constructor was used to create this object. + * This constructor calls its super class with the empty string + * to force the "toString" method of parent class "Throwable" to + * print the error message in the form: + * ParseException: + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) + { + super(""); + specialConstructor = true; + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + specialConstructor = false; + } + + public ParseException(String message) { + super(message); + specialConstructor = false; + } + + /** + * This variable determines which constructor was used to create + * this object and thereby affects the semantics of the + * "getMessage" method (see below). + */ + protected boolean specialConstructor; + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * This method has the standard behavior when this object has been + * created using the standard constructors. Otherwise, it uses + * "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser), then this method is called during the printing + * of the final stack trace, and hence the correct error message + * gets displayed. + */ + public String getMessage() { + if (!specialConstructor) { + return super.getMessage(); + } + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int i = 0; i < expectedTokenSequences.length; i++) { + if (maxSize < expectedTokenSequences[i].length) { + maxSize = expectedTokenSequences[i].length; + } + for (int j = 0; j < expectedTokenSequences[i].length; j++) { + expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" "); + } + if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += add_escapes(tok.image); + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + /** + * The end of line string for this machine. + */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + */ + protected String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + +} diff --git a/gson/src/main/java/com/google/gson/Preconditions.java b/gson/src/main/java/com/google/gson/Preconditions.java new file mode 100644 index 00000000..72423278 --- /dev/null +++ b/gson/src/main/java/com/google/gson/Preconditions.java @@ -0,0 +1,42 @@ +/* + * 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.google.gson; + +/** + * A simple utility class used to check method Preconditions. + * + *
+ * public long divideBy(long value) {
+ *   Preconditions.checkArgument(value != 0);
+ *   return this.value / value;
+ * }
+ * 
+ * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class Preconditions { + public static void checkNotNull(Object obj) { + checkArgument(obj != null); + } + + public static void checkArgument(boolean condition) { + if (!condition) { + throw new IllegalArgumentException("condition failed: " + condition); + } + } +} diff --git a/gson/src/main/java/com/google/gson/PrimitiveTypeAdapter.java b/gson/src/main/java/com/google/gson/PrimitiveTypeAdapter.java new file mode 100644 index 00000000..47bd7a09 --- /dev/null +++ b/gson/src/main/java/com/google/gson/PrimitiveTypeAdapter.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Handles type conversion from some object to some primitive (or primitive + * wrapper instance). + * + * @author Joel Leitch + */ +final class PrimitiveTypeAdapter implements TypeAdapter { + + @SuppressWarnings({"unchecked"}) + public T adaptType(Object from, Class to) { + Class aClass = Primitives.wrap(to); + if (Primitives.isWrapperType(aClass)) { + if (aClass == Character.class) { + String value = from.toString(); + if (value.length() == 1) { + return (T) (Character) from.toString().charAt(0); + } else { + throw new JsonParseException("The value: " + value + " contains more than a character."); + } + } + + try { + Constructor constructor = aClass.getConstructor(String.class); + return (T) constructor.newInstance(from.toString()); + } catch (NoSuchMethodException e) { + throw new JsonParseException(e); + } catch (IllegalAccessException e) { + throw new JsonParseException(e); + } catch (InvocationTargetException e) { + throw new JsonParseException(e); + } catch (InstantiationException e) { + throw new JsonParseException(e); + } + } else if (Enum.class.isAssignableFrom(to)) { + // Case where the type being adapted to is an Enum + // We will try to convert from.toString() to the enum + try { + Method valuesMethod = to.getMethod("valueOf", String.class); + return (T) valuesMethod.invoke(null, from.toString()); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } else { + throw new JsonParseException( + "Can not adapt type " + from.getClass() + " to " + to); + } + } +} diff --git a/gson/src/main/java/com/google/gson/Primitives.java b/gson/src/main/java/com/google/gson/Primitives.java new file mode 100644 index 00000000..13629e0e --- /dev/null +++ b/gson/src/main/java/com/google/gson/Primitives.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Contains static utility methods pertaining to primitive types and their + * corresponding wrapper types. + * + * @author Kevin Bourrillion + */ +final class Primitives { + private Primitives() {} + + /** A map from primitive types to their corresponding wrapper types. */ + public static final Map, Class> PRIMITIVE_TO_WRAPPER_TYPE; + + /** A map from wrapper types to their corresponding primitive types. */ + public static final Map, Class> WRAPPER_TO_PRIMITIVE_TYPE; + + // Sad that we can't use a BiMap. :( + + static { + Map, Class> primToWrap = new HashMap, Class>(16); + Map, Class> wrapToPrim = new HashMap, 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> forward, + Map, Class> backward, Class key, Class value) { + forward.put(key, value); + backward.put(value, key); + } + + /** + * Returns {@code true} if {@code type} is one of the nine + * primitive-wrapper types, such as {@link Integer}. + * + * @see Class#isPrimitive + */ + public static boolean isWrapperType(Class type) { + return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(checkNotNull(type)); + } + + private static Class checkNotNull(Class type) { + Preconditions.checkNotNull(type); + return type; + } + + /** + * Returns the corresponding wrapper type of {@code type} if it is a primitive + * type; otherwise returns {@code type} itself. Idempotent. + *
+   *     wrap(int.class) == Integer.class
+   *     wrap(Integer.class) == Integer.class
+   *     wrap(String.class) == String.class
+   * 
+ */ + public static Class wrap(Class type) { + checkNotNull(type); + + // cast is safe: long.class and Long.class are both of type Class + @SuppressWarnings("unchecked") + Class wrapped = (Class) PRIMITIVE_TO_WRAPPER_TYPE.get(type); + return (wrapped == null) ? type : wrapped; + } + + /** + * Returns the corresponding primitive type of {@code type} if it is a + * wrapper type; otherwise returns {@code type} itself. Idempotent. + *
+   *     unwrap(Integer.class) == int.class
+   *     unwrap(int.class) == int.class
+   *     unwrap(String.class) == String.class
+   * 
+ */ + public static Class unwrap(Class type) { + checkNotNull(type); + + // cast is safe: long.class and Long.class are both of type Class + @SuppressWarnings("unchecked") + Class unwrapped = (Class) WRAPPER_TO_PRIMITIVE_TYPE.get(type); + return (unwrapped == null) ? type : unwrapped; + } +} diff --git a/gson/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java b/gson/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java new file mode 100644 index 00000000..fbdc002c --- /dev/null +++ b/gson/src/main/java/com/google/gson/RecursiveFieldNamingPolicy.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Type; + +/** + * 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 FieldNamingStrategy { + + public final String translateName(Field f) { + Preconditions.checkNotNull(f); + return translateName(f.getName(), f.getGenericType(), 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, Annotation[] annotations); +} diff --git a/gson/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java b/gson/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java new file mode 100644 index 00000000..24224e93 --- /dev/null +++ b/gson/src/main/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicy.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.annotations.SerializedName; + +import java.lang.reflect.Field; + +/** + * A {@link FieldNamingStrategy} that acts as a chain of responsibility. If the + * {@link com.google.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 FieldNamingStrategy}. + * + *

NOTE: this class performs JSON field name validation for any of the fields marked with + * an {@code @SerializedName} annotation.

+ * + * @see SerializedName + * + * @author Joel Leitch + */ +class SerializedNameAnnotationInterceptingNamingPolicy implements FieldNamingStrategy { + private static final JsonFieldNameValidator fieldNameValidator = new JsonFieldNameValidator(); + private final FieldNamingStrategy delegate; + + public SerializedNameAnnotationInterceptingNamingPolicy(FieldNamingStrategy delegate) { + this.delegate = delegate; + } + + public String translateName(Field f) { + Preconditions.checkNotNull(f); + SerializedName serializedName = f.getAnnotation(SerializedName.class); + if (serializedName != null) { + return fieldNameValidator.validate(serializedName.value()); + } else { + return delegate.translateName(f); + } + } +} diff --git a/gson/src/main/java/com/google/gson/SimpleCharStream.java b/gson/src/main/java/com/google/gson/SimpleCharStream.java new file mode 100755 index 00000000..96f09c91 --- /dev/null +++ b/gson/src/main/java/com/google/gson/SimpleCharStream.java @@ -0,0 +1,440 @@ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */ +package com.google.gson; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +@SuppressWarnings("all") +final class SimpleCharStream +{ + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { tabSize = i; } + protected int getTabSize(int i) { return tabSize; } + + + protected void ExpandBuff(boolean wrapAround) + { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try + { + if (wrapAround) + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, + bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } + else + { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) + { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException + { + if (maxNextCharInd == available) + { + if (available == bufsize) + { + if (tokenBegin > 2048) + { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } + else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } + else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, + available - maxNextCharInd)) == -1) + { + inputStream.close(); + throw new java.io.IOException(); + } + else + maxNextCharInd += i; + return; + } + catch(java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + + public char BeginToken() throws java.io.IOException + { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) + { + column++; + + if (prevCharIsLF) + { + prevCharIsLF = false; + line += (column = 1); + } + else if (prevCharIsCR) + { + prevCharIsCR = false; + if (c == '\n') + { + prevCharIsLF = true; + } + else + line += (column = 1); + } + + switch (c) + { + case '\r' : + prevCharIsCR = true; + break; + case '\n' : + prevCharIsLF = true; + break; + case '\t' : + column--; + column += (tabSize - (column % tabSize)); + break; + default : + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + + public char readChar() throws java.io.IOException + { + if (inBuf > 0) + { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return (c); + } + + /** + * @deprecated + * @see #getEndColumn + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + /** + * @deprecated + * @see #getEndLine + */ + + public int getLine() { + return bufline[bufpos]; + } + + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + public int getEndLine() { + return bufline[bufpos]; + } + + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + public int getBeginLine() { + return bufline[tokenBegin]; + } + + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.Reader dstream) + { + this(dstream, 1, 1, 4096); + } + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) + { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) + { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + + public void ReInit(java.io.Reader dstream) + { + ReInit(dstream, 1, 1, 4096); + } + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) + { + this(dstream, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + this(dstream, encoding, 1, 1, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream) + { + this(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException + { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) + { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream) + { + ReInit(dstream, 1, 1, 4096); + } + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException + { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) + { + ReInit(dstream, startline, startcolumn, 4096); + } + public String GetImage() + { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + public char[] GetSuffix(int len) + { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else + { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + public void Done() + { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + */ + public void adjustBeginLineColumn(int newLine, int newCol) + { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) + { + len = bufpos - tokenBegin + inBuf + 1; + } + else + { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k = 0; + int nextColDiff = 0, columnDiff = 0; + + while (i < len && + bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) + { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) + { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) + { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} diff --git a/gson/src/main/java/com/google/gson/Token.java b/gson/src/main/java/com/google/gson/Token.java new file mode 100755 index 00000000..0289a013 --- /dev/null +++ b/gson/src/main/java/com/google/gson/Token.java @@ -0,0 +1,82 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ +package com.google.gson; + +/** + * Describes the input token stream. + */ + +@SuppressWarnings("all") +final class Token { + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** + * beginLine and beginColumn describe the position of the first character + * of this token; endLine and endColumn describe the position of the + * last character of this token. + */ + public int beginLine, beginColumn, endLine, endColumn; + + /** + * The string image of the token. + */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** + * Returns the image. + */ + public String toString() + { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simlpy add something like : + * + * case MyParserConstants.ID : return new IDToken(); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use it in your lexical actions. + */ + public static final Token newToken(int ofKind) + { + switch(ofKind) + { + default : return new Token(); + } + } + +} diff --git a/gson/src/main/java/com/google/gson/TokenMgrError.java b/gson/src/main/java/com/google/gson/TokenMgrError.java new file mode 100755 index 00000000..033348bd --- /dev/null +++ b/gson/src/main/java/com/google/gson/TokenMgrError.java @@ -0,0 +1,134 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ +package com.google.gson; + +@SuppressWarnings("all") +final class TokenMgrError extends Error +{ + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** + * Lexical error occured. + */ + static final int LEXICAL_ERROR = 0; + + /** + * An attempt wass made to create a second instance of a static token manager. + */ + static final int STATIC_LEXER_ERROR = 1; + + /** + * Tried to change to an invalid lexical state. + */ + static final int INVALID_LEXICAL_STATE = 2; + + /** + * Detected (and bailed out of) an infinite loop in the token manager. + */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + + /** + * Replaces unprintable characters by their espaced (or unicode escaped) + * equivalents in the given string + */ + protected static final String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) + { + case 0 : + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u" + s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + continue; + } + } + return retval.toString(); + } + + /** + * Returns a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + * Parameters : + * EOFSeen : indicates if EOF caused the lexicl error + * curLexState : lexical state in which this error occured + * errorLine : line number when the error occured + * errorColumn : column number when the error occured + * errorAfter : prefix that was seen before this error occured + * curchar : the offending character + * Note: You can customize the lexical error message by modifying this method. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * + * "Internal Error : Please file a bug report .... " + * + * from this method for such cases in the release version of your parser. + */ + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + public TokenMgrError() { + } + + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} diff --git a/gson/src/main/java/com/google/gson/TypeAdapter.java b/gson/src/main/java/com/google/gson/TypeAdapter.java new file mode 100644 index 00000000..ae8d7a81 --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeAdapter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * This class is responsible for adapting/converting an particular "from" + * instance to an instance of type "to". + * + * @author Joel Leitch + */ +interface TypeAdapter { + + /** + * Adapts an object instance "from" to and instance of type "to". + * + * @param from the object to adapt + * @param to the Type/Class which this will convert to + * @return the converted "from" instance to type "to" + */ + public T adaptType(Object from, Class to); +} diff --git a/gson/src/main/java/com/google/gson/TypeAdapterNotRequired.java b/gson/src/main/java/com/google/gson/TypeAdapterNotRequired.java new file mode 100644 index 00000000..766d60d2 --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeAdapterNotRequired.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * This class implements the {@link TypeAdapter} interface; however, if the + * from instance type is the same as the to type then this object will + * terminate the chain early and return the "from" object to the calling + * class. + * + * If the incoming object does need some kind of conversion then this object + * will delegate to the {@link TypeAdapter} that it is wrapping. + * + * @author Joel Leitch + */ +final class TypeAdapterNotRequired implements TypeAdapter { + + private final TypeAdapter delegate; + + /** + * Constructs a TypeAdapterNotRequired that will wrap the delegate instance + * that is passed in. + * + * @param delegate the TypeConverter to delegate to if this instance can + * not handle the type adapting (can not be null) + */ + TypeAdapterNotRequired(TypeAdapter delegate) { + Preconditions.checkNotNull(delegate); + this.delegate = delegate; + } + + @SuppressWarnings("unchecked") + public T adaptType(Object from, Class to) { + if (to.isAssignableFrom(from.getClass())) { + return (T) from; + } + return delegate.adaptType(from, to); + } +} diff --git a/gson/src/main/java/com/google/gson/TypeInfo.java b/gson/src/main/java/com/google/gson/TypeInfo.java new file mode 100644 index 00000000..e156b310 --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeInfo.java @@ -0,0 +1,84 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Type; +import java.util.Collection; + +/** + * Class that provides information relevant to different parts of a type. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +class TypeInfo { + protected final Type actualType; + protected final Class rawClass; + + TypeInfo(Type actualType) { + this.actualType = actualType; + rawClass = TypeUtils.toRawClass(actualType); + } + + public final Type getActualType() { + return actualType; + } + + /** + * Returns the corresponding wrapper type of {@code type} if it is a primitive + * type; otherwise returns {@code type} itself. Idempotent. + *
+   *     wrap(int.class) == Integer.class
+   *     wrap(Integer.class) == Integer.class
+   *     wrap(String.class) == String.class
+   * 
+ */ + public final Class getWrappedClass() { + return Primitives.wrap(rawClass); + } + + /** + * @return the raw class associated with this type + */ + public final Class getRawClass() { + return rawClass; + } + + public final boolean isCollectionOrArray() { + return Collection.class.isAssignableFrom(rawClass) || isArray(); + } + + public final boolean isArray() { + return TypeUtils.isArray(rawClass); + } + + public final boolean isEnum() { + return rawClass.isEnum(); + } + + public final boolean isPrimitive() { + return Primitives.isWrapperType(Primitives.wrap(rawClass)); + } + + public final boolean isString() { + return rawClass == String.class; + } + + public final boolean isPrimitiveOrStringAndNotAnArray() { + return (isPrimitive() || isString()) && !isArray(); + } +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/TypeInfoArray.java b/gson/src/main/java/com/google/gson/TypeInfoArray.java new file mode 100644 index 00000000..02156848 --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeInfoArray.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Type; + +/** + * Class to extract information about types used to define a generic array. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class TypeInfoArray extends TypeInfo { + private final Class componentRawType; + private final Type secondLevel; + + TypeInfoArray(Type type) { + super(type); + Class rootComponentType = rawClass; + while (rootComponentType.isArray()) { + rootComponentType = rootComponentType.getComponentType(); + } + this.componentRawType = rootComponentType; + this.secondLevel = extractSecondLevelType(actualType, rawClass); + } + + private static Type extractSecondLevelType(Type actualType, Class rawClass) { + if (actualType instanceof GenericArrayType) { + GenericArrayType castedType = (GenericArrayType) actualType; + return castedType.getGenericComponentType(); + } else { + return rawClass.getComponentType(); + } + } + + /** + * @return the raw type unwrapped of the second level of array. + * If the object is (single-dimensional or multi-dimensional) array, it is the class of the + * elements of the array. For example, this method returns Foo.class for Foo[]. + * It will return Foo[].class for Foo[][]. For Foo[][] types, it will return the type + * representing Foo[] (i.e. {@code new TypeToken[]>() {}.getType()}). + */ + public Type getSecondLevelType() { + return secondLevel; + } + + /** + * @return the raw type of the root component. + * If the object is a single-dimensional array then the component type is the class of an + * element of the array. + * If the object is a multi-dimensional array then the component type is the class of the + * inner-most array element. For example, the This method will return Foo.class for Foo[][][]. + */ + public Class getComponentRawType() { + return componentRawType; + } +} diff --git a/gson/src/main/java/com/google/gson/TypeInfoFactory.java b/gson/src/main/java/com/google/gson/TypeInfoFactory.java new file mode 100644 index 00000000..e02b647d --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeInfoFactory.java @@ -0,0 +1,124 @@ +/* + * 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.google.gson; + +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; + +/** + * A static factory class used to construct the "TypeInfo" objects. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class TypeInfoFactory { + + private TypeInfoFactory() { + // Not instantiable since it provides factory methods only. + } + + public static TypeInfoArray getTypeInfoForArray(Type type) { + Preconditions.checkArgument(TypeUtils.isArray(type)); + return new TypeInfoArray(type); + } + + /** + * Evaluates the "actual" type for the field. If the field is a "TypeVariable" or has a + * "TypeVariable" in a parameterized type then it evaluates the real type. + * + * @param f the actual field object to retrieve the type from + * @param typeDefiningF the type that contains the field {@code f} + * @return the type information for the field + */ + public static TypeInfo getTypeInfoForField(Field f, Type typeDefiningF) { + Class classDefiningF = TypeUtils.toRawClass(typeDefiningF); + Type type = f.getGenericType(); + Type actualType = getActualType(type, typeDefiningF, classDefiningF); + return new TypeInfo(actualType); + } + + private static Type getActualType( + Type typeToEvaluate, Type parentType, Class rawParentClass) { + if (typeToEvaluate instanceof Class) { + return typeToEvaluate; + } else if (typeToEvaluate instanceof ParameterizedType) { + ParameterizedType castedType = (ParameterizedType) typeToEvaluate; + Type owner = castedType.getOwnerType(); + Type[] actualTypeParameters = + extractRealTypes(castedType.getActualTypeArguments(), parentType, rawParentClass); + Type rawType = castedType.getRawType(); + return new ParameterizedTypeImpl(rawType, actualTypeParameters, owner); + } else if (typeToEvaluate instanceof GenericArrayType) { + GenericArrayType castedType = (GenericArrayType) typeToEvaluate; + Type componentType = castedType.getGenericComponentType(); + Type actualType = getActualType(componentType, parentType, rawParentClass); + if (componentType.equals(actualType)) { + return castedType; + } else { + if (actualType instanceof Class) { + return TypeUtils.wrapWithArray(TypeUtils.toRawClass(actualType)); + } else { + return new GenericArrayTypeImpl(actualType); + } + } + } else if (typeToEvaluate instanceof TypeVariable) { + // The class definition has the actual types used for the type variables. + // Find the matching actual type for the Type Variable used for the field. + // For example, class Foo { A a; } + // new Foo(); defines the actual type of A to be Integer. + // So, to find the type of the field a, we will have to look at the class' + // actual type arguments. + TypeVariable fieldTypeVariable = (TypeVariable) typeToEvaluate; + TypeVariable[] classTypeVariables = rawParentClass.getTypeParameters(); + ParameterizedType objParameterizedType = (ParameterizedType) parentType; + int indexOfActualTypeArgument = getIndex(classTypeVariables, fieldTypeVariable); + Type[] actualTypeArguments = objParameterizedType.getActualTypeArguments(); + return actualTypeArguments[indexOfActualTypeArgument]; + } else if (typeToEvaluate instanceof WildcardType) { + WildcardType castedType = (WildcardType) typeToEvaluate; + return getActualType(castedType.getUpperBounds()[0], parentType, rawParentClass); + } else { + throw new IllegalArgumentException("Type \'" + typeToEvaluate + "\' is not a Class, " + + "ParameterizedType, GenericArrayType or TypeVariable. Can't extract type."); + } + } + + private static Type[] extractRealTypes( + Type[] actualTypeArguments, Type parentType, Class rawParentClass) { + Preconditions.checkNotNull(actualTypeArguments); + + Type[] retTypes = new Type[actualTypeArguments.length]; + for (int i = 0; i < actualTypeArguments.length; ++i) { + retTypes[i] = getActualType(actualTypeArguments[i], parentType, rawParentClass); + } + return retTypes; + } + + private static int getIndex(TypeVariable[] types, TypeVariable type) { + for (int i = 0; i < types.length; ++i) { + if (type.equals(types[i])) { + return i; + } + } + throw new IllegalStateException( + "How can the type variable not be present in the class declaration!"); + } +} diff --git a/gson/src/main/java/com/google/gson/TypeInfoMap.java b/gson/src/main/java/com/google/gson/TypeInfoMap.java new file mode 100644 index 00000000..ba9db948 --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeInfoMap.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Map; + +/** + * A convenience object for retrieving the map type information. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class TypeInfoMap { + private final ParameterizedType mapType; + + public TypeInfoMap(Type mapType) { + if (!(mapType instanceof ParameterizedType)) { + throw new IllegalArgumentException( + "Map objects need to be parameterized unless you use a custom serializer. " + + "Use the com.google.gson.reflect.TypeToken to extract the ParameterizedType."); + } + TypeInfo rawType = new TypeInfo(mapType); + Preconditions.checkArgument(Map.class.isAssignableFrom(rawType.getRawClass())); + this.mapType = (ParameterizedType) mapType; + } + + public Type getKeyType() { + return mapType.getActualTypeArguments()[0]; + } + + public Type getValueType() { + return mapType.getActualTypeArguments()[1]; + } +} diff --git a/gson/src/main/java/com/google/gson/TypeUtils.java b/gson/src/main/java/com/google/gson/TypeUtils.java new file mode 100644 index 00000000..50696bda --- /dev/null +++ b/gson/src/main/java/com/google/gson/TypeUtils.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Utility class containing some methods for obtaining information on types. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +final class TypeUtils { + + /** + * Returns the actual type matching up with the first type variable. + * So, for a {@code typeInfo} instance defined as: + *
+   *   class Foo {
+   *   }
+   *   Type fooType = new TypeToken>() {}.getType();
+   * 
+ * TypeUtils.getActualTypeForFirstTypeVariable(fooType) will return Integer.class. + */ + static Type getActualTypeForFirstTypeVariable(Type type) { + if (type instanceof Class) { + return Object.class; + } else if (type instanceof ParameterizedType) { + return ((ParameterizedType)type).getActualTypeArguments()[0]; + } else if (type instanceof GenericArrayType) { + return getActualTypeForFirstTypeVariable(((GenericArrayType)type).getGenericComponentType()); + } else { + throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, " + + "ParameterizedType, or GenericArrayType. Can't extract class."); + } + } + + static boolean isArray(Type type) { + if (type instanceof Class) { + return ((Class)type).isArray(); + } else if (type instanceof GenericArrayType) { + return true; + } else { + return false; + } + } + + /** + * This method returns the actual raw class associated with the specified type. + */ + static Class toRawClass(Type type) { + if (type instanceof Class) { + return (Class) type; + } else if (type instanceof ParameterizedType) { + ParameterizedType actualType = (ParameterizedType)type; + return toRawClass(actualType.getRawType()); + } else if (type instanceof GenericArrayType) { + GenericArrayType actualType = (GenericArrayType) type; + Class rawClass = toRawClass(actualType.getGenericComponentType()); + return wrapWithArray(rawClass); + } else { + throw new IllegalArgumentException("Type \'" + type + "\' is not a Class, " + + "ParameterizedType, or GenericArrayType. Can't extract class."); + } + } + + static Class wrapWithArray(Class rawClass) { + return Array.newInstance(rawClass, 0).getClass(); + } + + private TypeUtils() { + // Class with just some static utility methods, should not be instantiated + } +} diff --git a/gson/src/main/java/com/google/gson/UpperCaseNamingPolicy.java b/gson/src/main/java/com/google/gson/UpperCaseNamingPolicy.java new file mode 100644 index 00000000..cd18208a --- /dev/null +++ b/gson/src/main/java/com/google/gson/UpperCaseNamingPolicy.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * A {@link FieldNamingStrategy} that ensures the JSON field names consist of only + * upper case letters. + * + *

The following is an example:

+ *
+ * class IntWrapper {
+ *   public int integerField = 0;
+ * }
+ *
+ * UpperCaseNamingPolicy policy = new UpperCaseNamingPolicy();
+ * String translatedFieldName =
+ *     policy.translateName(IntWrapper.class.getField("integerField"));
+ *
+ * assert("INTEGERFIELD".equals(translatedFieldName));
+ * 
+ * + * @author Joel Leitch + */ +class UpperCaseNamingPolicy extends RecursiveFieldNamingPolicy { + + @Override + protected String translateName(String target, Type fieldType, Annotation[] annotations) { + return target.toUpperCase(); + } +} diff --git a/gson/src/main/java/com/google/gson/VersionConstants.java b/gson/src/main/java/com/google/gson/VersionConstants.java new file mode 100644 index 00000000..dc859a3f --- /dev/null +++ b/gson/src/main/java/com/google/gson/VersionConstants.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +/** + * Class contain all constants for versioning support. + * + * @author Joel Leitch + */ +final class VersionConstants { + // Prevent instantiation + private VersionConstants() { } + + static final double IGNORE_VERSIONS = -1D; +} diff --git a/gson/src/main/java/com/google/gson/VersionExclusionStrategy.java b/gson/src/main/java/com/google/gson/VersionExclusionStrategy.java new file mode 100644 index 00000000..58161cc0 --- /dev/null +++ b/gson/src/main/java/com/google/gson/VersionExclusionStrategy.java @@ -0,0 +1,57 @@ +/* + * 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.google.gson; + +import com.google.gson.annotations.Since; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + +/** + * This strategy will exclude any files and/or class that are passed the + * {@link #version} value. + * + * @author Joel Leitch + */ +final class VersionExclusionStrategy implements ExclusionStrategy { + private final double version; + + public VersionExclusionStrategy(double version) { + Preconditions.checkArgument(version >= 0.0D); + this.version = version; + } + + public boolean shouldSkipField(Field f) { + return !isValidVersion(f.getAnnotations()); + } + + public boolean shouldSkipClass(Class clazz) { + return !isValidVersion(clazz.getAnnotations()); + } + + private boolean isValidVersion(Annotation[] annotations) { + for (Annotation annotation : annotations) { + if (annotation instanceof Since) { + double annotationVersion = ((Since) annotation).value(); + if (annotationVersion > version) { + return false; + } + } + } + return true; + } +} diff --git a/gson/src/main/java/com/google/gson/annotations/Expose.java b/gson/src/main/java/com/google/gson/annotations/Expose.java new file mode 100644 index 00000000..81aa5bed --- /dev/null +++ b/gson/src/main/java/com/google/gson/annotations/Expose.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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. + * + *

This annotation has no effect unless you build {@link com.google.gson.Gson} + * with a {@link com.google.gson.GsonBuilder} and invoke + * {@link com.google.gson.GsonBuilder#excludeFieldsWithoutExposeAnnotation()} + * method.

+ * + *

Here is an example of how this annotation is meant to be used: + *

+ * public class User {
+ *   @Expose private String firstName;
+ *   @Expose private String lastName;
+ *   @Expose private String emailAddress;
+ *   private String password;
+ * }
+ * 

+ * 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. + * + *

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 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Expose { + // This is a marker annotation with no additional properties +} diff --git a/gson/src/main/java/com/google/gson/annotations/SerializedName.java b/gson/src/main/java/com/google/gson/annotations/SerializedName.java new file mode 100644 index 00000000..4c44e035 --- /dev/null +++ b/gson/src/main/java/com/google/gson/annotations/SerializedName.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.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. + * + *

This annotation will override any {@link com.google.gson.FieldNamingPolicy}, including + * the default field naming policy, that may have been set on the {@link com.google.gson.Gson} + * instance. A different naming policy can set using the {@code GsonBuilder} class. See + * {@link com.google.gson.GsonBuilder#setFieldNamingPolicy(com.google.gson.FieldNamingPolicy)} + * for more information.

+ * + *

Here is an example of how this annotation is meant to be used:

+ *
+ * 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;
+ *   }
+ * }
+ * 
+ * + *

The following shows the output that is generated when serializing an instance of the + * above example class:

+ *
+ * SomeClassWithFields objectToSerialize = new SomeClassWithFields("a", "b");
+ * Gson gson = new Gson();
+ * String jsonRepresentation = gson.toJson(objectToSerialize);
+ * System.out.println(jsonRepresentation);
+ *
+ * ===== OUTPUT =====
+ * {"name":"a","someOtherField":"b"}
+ * 
+ * + *

NOTE: The value you specify in this annotation must be a valid JSON field name.

+ * + * @see com.google.gson.FieldNamingPolicy + * + * @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(); +} diff --git a/gson/src/main/java/com/google/gson/annotations/Since.java b/gson/src/main/java/com/google/gson/annotations/Since.java new file mode 100644 index 00000000..04b9a98b --- /dev/null +++ b/gson/src/main/java/com/google/gson/annotations/Since.java @@ -0,0 +1,60 @@ +/* + * 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.google.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. + * + *

+ * This annotation has no effect unless you build {@link com.google.gson.Gson} with a + * {@link com.google.gson.GsonBuilder} and invoke + * {@link com.google.gson.GsonBuilder#setVersion(double)} method. + * + *

Here is an example of how this annotation is meant to be used:

+ *
+ * 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;
+ * }
+ * 
+ * + *

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()} the 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}.

+ * + * @author Inderjeet Singh + */ +@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(); +} diff --git a/gson/src/main/java/com/google/gson/annotations/package-info.java b/gson/src/main/java/com/google/gson/annotations/package-info.java new file mode 100644 index 00000000..1c461fd6 --- /dev/null +++ b/gson/src/main/java/com/google/gson/annotations/package-info.java @@ -0,0 +1,6 @@ +/** + * This package provides annotations that can be used with {@link com.google.gson.Gson}. + * + * @author Inderjeet Singh, Joel Leitch + */ +package com.google.gson.annotations; \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/package-info.java b/gson/src/main/java/com/google/gson/package-info.java new file mode 100644 index 00000000..428e280c --- /dev/null +++ b/gson/src/main/java/com/google/gson/package-info.java @@ -0,0 +1,11 @@ +/** + * This package provides the {@link com.google.gson.Gson} class to convert Json to Java and + * vice-versa. + * + *

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).

+ * + * @author Inderjeet Singh, Joel Leitch + */ +package com.google.gson; \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/reflect/TypeToken.java b/gson/src/main/java/com/google/gson/reflect/TypeToken.java new file mode 100644 index 00000000..c9eef2f1 --- /dev/null +++ b/gson/src/main/java/com/google/gson/reflect/TypeToken.java @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson.reflect; + +import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a generic type {@code T}. + * + * You can use this class to get the generic type for a class. For example, + * to get the generic type for Collection<Foo>, you can use: + *

+ * Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType() + * + * + *

Assumes {@code Type} implements {@code equals()} and {@code hashCode()} + * as a value (as opposed to identity) comparison. + * + * Also implements {@link #isAssignableFrom(Type)} to check type-safe + * assignability. + * + * @author Bob Lee + * @author Sven Mawson + */ +public abstract class TypeToken { + + final Class rawType; + final Type type; + + /** + * Constructs a new type token. Derives represented class from type + * parameter. + * + *

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. + * + *

For example: + * + * {@literal TypeToken> t = new TypeToken>}(){} + * + */ + @SuppressWarnings("unchecked") + protected TypeToken() { + this.type = getSuperclassTypeParameter(getClass()); + this.rawType = (Class) getRawType(type); + } + + /** + * Unsafe. Constructs a type token manually. + */ + @SuppressWarnings({"unchecked"}) + private TypeToken(Type type) { + this.rawType = (Class) getRawType(nonNull(type, "type")); + this.type = type; + } + + private static T nonNull(T o, String message) { + if (o == null) { + throw new NullPointerException(message); + } + return o; + } + + /** + * Gets type from super class's type parameter. + */ + static Type getSuperclassTypeParameter(Class subclass) { + Type superclass = subclass.getGenericSuperclass(); + if (superclass instanceof Class) { + throw new RuntimeException("Missing type parameter."); + } + return ((ParameterizedType) superclass).getActualTypeArguments()[0]; + } + + /** + * Gets type token from super class's type parameter. + */ + static TypeToken fromSuperclassTypeParameter(Class subclass) { + return new SimpleTypeToken(subclass); + } + + private static Class getRawType(Type type) { + if (type instanceof Class) { + // type is a normal class. + return (Class) type; + } else if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; + + // I'm not exactly sure why getRawType() returns Type instead of Class. + // Neal isn't either but suspects some pathological case related + // to nested classes exists. + Type rawType = parameterizedType.getRawType(); + if (rawType instanceof Class) { + return (Class) rawType; + } + throw buildUnexpectedTypeError(rawType, Class.class); + } else if (type instanceof GenericArrayType) { + GenericArrayType genericArrayType = (GenericArrayType) type; + + // TODO(jleitch): This is not the most efficient way to handle generic + // arrays, but is there another way to extract the array class in a + // non-hacky way (i.e. using String value class names- "[L...")? + Object rawArrayType = Array.newInstance( + getRawType(genericArrayType.getGenericComponentType()), 0); + return rawArrayType.getClass(); + } else { + throw buildUnexpectedTypeError( + type, ParameterizedType.class, GenericArrayType.class); + } + } + + /** + * Gets the raw type. + */ + public Class getRawType() { + return rawType; + } + + /** + * Gets underlying {@code Type} instance. + */ + public Type getType() { + return type; + } + + /** + * Check if this type is assignable from the given class object. + */ + public boolean isAssignableFrom(Class cls) { + return isAssignableFrom((Type) cls); + } + + /** + * Check if this type is assignable from the given Type. + */ + public boolean isAssignableFrom(Type from) { + if (from == null) { + return false; + } + + if (type.equals(from)) { + return true; + } + + if (type instanceof Class) { + return rawType.isAssignableFrom(getRawType(from)); + } else if (type instanceof ParameterizedType) { + return isAssignableFrom(from, (ParameterizedType) type, + new HashMap()); + } else if (type instanceof GenericArrayType) { + return rawType.isAssignableFrom(getRawType(from)) + && isAssignableFrom(from, (GenericArrayType) type); + } else { + throw buildUnexpectedTypeError( + type, Class.class, ParameterizedType.class, GenericArrayType.class); + } + } + + /** + * Check if this type is assignable from the given type token. + */ + public boolean isAssignableFrom(TypeToken token) { + return isAssignableFrom(token.getType()); + } + + /** + * Private helper function that performs some assignability checks for + * the provided GenericArrayType. + */ + private static boolean isAssignableFrom(Type from, GenericArrayType to) { + Type toGenericComponentType = to.getGenericComponentType(); + if (toGenericComponentType instanceof ParameterizedType) { + Type t = from; + if (from instanceof GenericArrayType) { + t = ((GenericArrayType) from).getGenericComponentType(); + } else if (from instanceof Class) { + Class classType = (Class) from; + while (classType.isArray()) { + classType = classType.getComponentType(); + } + t = classType; + } + return isAssignableFrom(t, (ParameterizedType) toGenericComponentType, + new HashMap()); + } + // 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 typeVarMap) { + + if (from == null) { + return false; + } + + if (to.equals(from)) { + return true; + } + + // First figure out the class and any type information. + Class clazz = getRawType(from); + ParameterizedType ptype = null; + if (from instanceof ParameterizedType) { + ptype = (ParameterizedType) from; + } + + // Load up parameterized variable info if it was parameterized. + if (ptype != null) { + Type[] tArgs = ptype.getActualTypeArguments(); + TypeVariable[] tParams = clazz.getTypeParameters(); + for (int i = 0; i < tArgs.length; i++) { + Type arg = tArgs[i]; + TypeVariable var = tParams[i]; + while (arg instanceof TypeVariable) { + TypeVariable v = (TypeVariable) arg; + arg = typeVarMap.get(v.getName()); + } + typeVarMap.put(var.getName(), arg); + } + + // check if they are equivalent under our current mapping. + if (typeEquals(ptype, to, typeVarMap)) { + return true; + } + } + + for (Type itype : clazz.getGenericInterfaces()) { + if (isAssignableFrom(itype, to, new HashMap(typeVarMap))) { + return true; + } + } + + // Interfaces didn't work, try the superclass. + Type sType = clazz.getGenericSuperclass(); + if (isAssignableFrom(sType, to, new HashMap(typeVarMap))) { + return true; + } + + return false; + } + + /** + * Checks if two parameterized types are exactly equal, under the variable + * replacement described in the typeVarMap. + */ + private static boolean typeEquals(ParameterizedType from, + ParameterizedType to, Map typeVarMap) { + if (from.getRawType().equals(to.getRawType())) { + Type[] fromArgs = from.getActualTypeArguments(); + Type[] toArgs = to.getActualTypeArguments(); + for (int i = 0; i < fromArgs.length; i++) { + if (!matches(fromArgs[i], toArgs[i], typeVarMap)) { + return false; + } + } + return true; + } + return false; + } + + /** + * Checks if two types are the same or are equivalent under a variable mapping + * given in the type map that was provided. + */ + private static boolean matches(Type from, Type to, + Map typeMap) { + if (to.equals(from)) return true; + + if (from instanceof TypeVariable) { + return to.equals(typeMap.get(((TypeVariable)from).getName())); + } + + return false; + } + + /** + * Hashcode for this object. + * @return hashcode for this object. + */ + @Override public int hashCode() { + return type.hashCode(); + } + + /** + * Method to test equality. + * + * @return true if this object is logically equal to the specified object, false otherwise. + */ + @Override public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof TypeToken)) { + return false; + } + TypeToken t = (TypeToken) o; + return type.equals(t.type); + } + + /** + * Returns a string representation of this object. + * @return a string representation of this object. + */ + @Override public String toString() { + return type instanceof Class + ? ((Class) type).getName() + : type.toString(); + } + + private static AssertionError buildUnexpectedTypeError( + Type token, Class... expected) { + + // Build exception message + StringBuilder exceptionMessage = + new StringBuilder("Unexpected type. Expected one of: "); + for (Class clazz : expected) { + exceptionMessage.append(clazz.getName()).append(", "); + } + exceptionMessage.append("but got: ").append(token.getClass().getName()) + .append(", for type token: ").append(token.toString()).append('.'); + + return new AssertionError(exceptionMessage.toString()); + } + + /** + * Gets type token for the given {@code Type} instance. + */ + public static TypeToken get(Type type) { + return new SimpleTypeToken(type); + } + + /** + * Gets type token for the given {@code Class} instance. + */ + public static TypeToken get(Class type) { + return new SimpleTypeToken(type); + } + + /** + * Private static class to not create more anonymous classes than + * necessary. + */ + private static class SimpleTypeToken extends TypeToken { + public SimpleTypeToken(Type type) { + super(type); + } + } +} diff --git a/gson/src/main/java/com/google/gson/reflect/package-info.java b/gson/src/main/java/com/google/gson/reflect/package-info.java new file mode 100644 index 00000000..e666c431 --- /dev/null +++ b/gson/src/main/java/com/google/gson/reflect/package-info.java @@ -0,0 +1,6 @@ +/** + * This package provides utility classes for finding type information for generic types. + * + * @author Inderjeet Singh, Joel Leitch + */ +package com.google.gson.reflect; \ No newline at end of file diff --git a/gson/src/main/javacc/JsonParser.jj b/gson/src/main/javacc/JsonParser.jj new file mode 100755 index 00000000..cd8814ab --- /dev/null +++ b/gson/src/main/javacc/JsonParser.jj @@ -0,0 +1,259 @@ +/** + * Adapted from the Json parser grammar from http://code.google.com/p/jsonparser/ + * + * Author: Inderjeet Singh + */ + +options { + STATIC = false; + UNICODE_INPUT = true; +} + +PARSER_BEGIN(JsonParser) + +package com.google.gson; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +@SuppressWarnings("all") +final class JsonParser { + +} + +PARSER_END(JsonParser) + +SKIP : { " " | "\t" | "\n" | "\r" } +/* + * Technically Json does not allow leading zeros in numbers, but we + * will allow that. + */ +TOKEN : { + +| +| : STRING_STATE +} + MORE : { "\\" : ESC_STATE } + TOKEN : { + > : DEFAULT +| +} + TOKEN : { + : STRING_STATE +} + MORE : { "u" : HEX_STATE } + TOKEN : { + <#HEX : ["a"-"f","A"-"F","0"-"9"]> +| > : STRING_STATE +} + +public JsonElement parse() : +{ + JsonElement json = null; +} +{ + ( json=JsonObject() | + json=JsonArray() | + json=JsonPrimitive() | + json=JsonNull()) + { return json; } +} + +private JsonObject JsonObject() : +{ + JsonObject o = new JsonObject(); +} +{ + "{" [ Members(o) ] "}" + { return o; } +} + +private JsonNull JsonNull() : +{ + JsonNull json = new JsonNull(); +} +{ + "null" + { return json; } +} + +private void Members(JsonObject o) : +{ } +{ + Pair(o) [ "," Members(o) ] +} + +private void Pair(JsonObject o) : +{ + JsonPrimitive property; + JsonElement value; +} +{ + property=JsonString() ":" value=JsonValue() + { + o.add(property.getAsString(), value); + } +} + +private JsonArray JsonArray() : +{ JsonArray array = new JsonArray(); } +{ + "[" [ Elements(array) ] "]" + { + array.reverse(); + return array; + } +} + +private void Elements(JsonArray array) : +{ + JsonElement element; +} +{ + element=JsonValue() [ "," Elements(array) ] + { array.add(element); } +} + +private JsonElement JsonValue() : +{ JsonElement o = null; } +{ +( o=JsonString() | + o=JsonNumber() | + o=JsonObject() | + o=JsonArray() | + ( "true" { o = new JsonPrimitive(true); } ) | + ( "false" { o = new JsonPrimitive(false); } ) | + "null" ) + { return o; } +} + +private JsonPrimitive JsonPrimitive() : +{ + JsonPrimitive value; +} +{ + ( value=JsonString()) { return value; } | + ( value=JsonNumber()) { return value; } | + ( "true" { return new JsonPrimitive(true); }) | + ( "false" { return new JsonPrimitive(false); } ) +} + +private JsonPrimitive JsonNumber() : +{ + String intpart = null, + fracpart = null, + exppart = null; +} +{ + intpart=JsonInt() [ fracpart=JsonFrac() ] [ exppart=JsonExp() ] + { + Number n; + if (exppart != null) { + n = new BigDecimal(intpart + fracpart + exppart); + } else if (fracpart != null) { + n = new Double(intpart + fracpart); + } else { + // See if the number fits in an integer, or long + // Use BigInteger only if it is big enough. + if (intpart.length() < 10) { + n = new Integer(intpart); + } else if (intpart.length() < 19) { + n = new Long(intpart); + } else { + n = new BigInteger(intpart); + } + } + return new JsonPrimitive(n); + } +} + +private String JsonInt() : +{ + String digits; + boolean negative = false; +} +{ + ["-" { negative = true; } ] digits=Digits() + { + if(negative) + return "-" + digits; + return digits; + } +} + +private String JsonFrac() : +{ String digits; } +{ + "." digits=Digits() + { return "." + digits; } +} + +private String JsonExp() : +{ + Token t; + String digits; +} +{ + t= digits=Digits() + { return t.image + digits; } +} + +private String Digits() : +{ Token t; } +{ + t= + { return t.image; } +} + +private JsonPrimitive JsonString() : +{ StringBuffer strbuf = new StringBuffer(); } +{ + [ Chars(strbuf) ] + { return new JsonPrimitive(strbuf.toString()); } +} + +private void Chars(StringBuffer strbuf) : +{ char c; } +{ + c=Char() [ Chars(strbuf) ] + { strbuf.insert(0, c); } +} + +private char Char() : +{ Token t; } +{ +( t= +| t= +| t= ) + { + if(t.image.length() < 2) { + return t.image.charAt(0); + } + if(t.image.length() < 6) { + char c = t.image.charAt(1); + switch(t.image.charAt(1)) { + //control characters + case 'b' : return (char) 8; break; + case 'f' : return (char) 12; break; + case 'n' : return (char) 10; break; + case 'r' : return (char) 13; break; + case 't' : return (char) 9; break; + default : return c; //characters that represent themselves + } + } + else { //hex escape code + //create an integer from our hex values + //and then cast into a char + int i = Integer.valueOf(t.image.substring(2,6), 16).intValue(); + return (char) i; + } + } +} \ No newline at end of file diff --git a/gson/src/main/resources/assembly-descriptor.xml b/gson/src/main/resources/assembly-descriptor.xml new file mode 100644 index 00000000..b734ee3a --- /dev/null +++ b/gson/src/main/resources/assembly-descriptor.xml @@ -0,0 +1,21 @@ + + release + + zip + + + + + README* + LICENSE* + + + + target + + + gson-*.jar + + + + \ No newline at end of file diff --git a/gson/src/test/java/com/google/gson/CamelCaseSeparatorNamingPolicyTest.java b/gson/src/test/java/com/google/gson/CamelCaseSeparatorNamingPolicyTest.java new file mode 100644 index 00000000..bf9a924b --- /dev/null +++ b/gson/src/test/java/com/google/gson/CamelCaseSeparatorNamingPolicyTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import junit.framework.TestCase; + +/** + * Tests for the {@link CamelCaseSeparatorNamingPolicy} class. + * + * @author Joel Leitch + */ +public class CamelCaseSeparatorNamingPolicyTest extends TestCase { + + private static final Class CLASS = String.class; + private static final String UNDERSCORE = "_"; + private static final String MULTI_CHAR_SEPARATOR = "_$_"; + + public void testInvalidInstantiation() throws Exception { + try { + new CamelCaseSeparatorNamingPolicy(null); + fail("Null separator string is not supported"); + } catch (IllegalArgumentException expected) { } + + try { + new CamelCaseSeparatorNamingPolicy(""); + fail("Empty separator string is not supported"); + } catch (IllegalArgumentException expected) { } + + try { + new CamelCaseSeparatorNamingPolicy(" "); + fail("space separator string is not supported"); + } catch (IllegalArgumentException expected) { } + + try { + new CamelCaseSeparatorNamingPolicy("\n"); + fail("new-line separator string is not supported"); + } catch (IllegalArgumentException expected) { } + } + + public void testUnderscoreSeparator() throws Exception { + CamelCaseSeparatorNamingPolicy namingPolicy = + new CamelCaseSeparatorNamingPolicy(UNDERSCORE); + String translatedName = namingPolicy.translateName("testUnderscoreBetweenWords", CLASS, null); + assertEquals("test_Underscore_Between_Words", translatedName); + } + + public void testMultiCharSeparator() throws Exception { + CamelCaseSeparatorNamingPolicy namingPolicy = + new CamelCaseSeparatorNamingPolicy(MULTI_CHAR_SEPARATOR); + String translatedName = namingPolicy.translateName("testMultCharBetweenWords", CLASS, null); + assertEquals("test_$_Mult_$_Char_$_Between_$_Words", translatedName); + } + + public void testNameBeginsWithCapital() throws Exception { + CamelCaseSeparatorNamingPolicy namingPolicy = new CamelCaseSeparatorNamingPolicy(UNDERSCORE); + String translatedName = namingPolicy.translateName("TestNameBeginsWithCapital", CLASS, null); + assertEquals("Test_Name_Begins_With_Capital", translatedName); + } + + public void testExceptionPossiblyIncorrectSeparation() throws Exception { + CamelCaseSeparatorNamingPolicy namingPolicy = new CamelCaseSeparatorNamingPolicy(UNDERSCORE); + String translatedName = namingPolicy.translateName("aURL", CLASS, null); + assertEquals("a_U_R_L", translatedName); + } +} diff --git a/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java b/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java new file mode 100644 index 00000000..bdc1417d --- /dev/null +++ b/gson/src/test/java/com/google/gson/DefaultDateTypeAdapterTest.java @@ -0,0 +1,60 @@ +/* + * 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.google.gson; + +import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter; + +import junit.framework.TestCase; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * A simple unit test for the {@link DefaultDateTypeAdapter} class. + * + * @author Joel Leitch + */ +public class DefaultDateTypeAdapterTest extends TestCase { + + public void testDateSerialization() throws Exception { + int dateStyle = DateFormat.LONG; + DefaultDateTypeAdapter dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle); + DateFormat formatter = DateFormat.getDateInstance(dateStyle); + Date currentDate = new Date(); + + String dateString = dateTypeAdapter.serialize(currentDate, Date.class, null).getAsString(); + assertEquals(formatter.format(currentDate), dateString); + } + + public void testDatePattern() throws Exception { + String pattern = "yyyy-MM-dd"; + DefaultDateTypeAdapter dateTypeAdapter = new DefaultDateTypeAdapter(pattern); + DateFormat formatter = new SimpleDateFormat(pattern); + Date currentDate = new Date(); + + String dateString = dateTypeAdapter.serialize(currentDate, Date.class, null).getAsString(); + assertEquals(formatter.format(currentDate), dateString); + } + + public void testInvalidDatePattern() throws Exception { + try { + new DefaultDateTypeAdapter("I am a bad Date pattern...."); + fail("Invalid date pattern should fail."); + } catch (IllegalArgumentException expected) { } + } +} diff --git a/gson/src/test/java/com/google/gson/DefaultMapJsonSerializerTest.java b/gson/src/test/java/com/google/gson/DefaultMapJsonSerializerTest.java new file mode 100644 index 00000000..c2bdfa1e --- /dev/null +++ b/gson/src/test/java/com/google/gson/DefaultMapJsonSerializerTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Unit test for the default JSON map serialization object located in the + * {@link DefaultTypeAdapters} class. + * + * @author Joel Leitch + */ +public class DefaultMapJsonSerializerTest extends TestCase { + + @SuppressWarnings("unchecked") + private JsonSerializer mapSerializer; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mapSerializer = new DefaultTypeAdapters.MapTypeAdapter(); + } + + public void testEmptyMapNoTypeSerialization() { + Map emptyMap = new HashMap(); + try { + mapSerializer.serialize(emptyMap, emptyMap.getClass(), null); + fail("Parameterized types need to have a ParameterizedType passed in, not a Class."); + } catch (IllegalArgumentException expected) { } + } + + public void testEmptyMapSerialization() { + Type mapType = new TypeToken>() { }.getType(); + Map emptyMap = new HashMap(); + JsonElement element = mapSerializer.serialize(emptyMap, mapType, null); + + assertTrue(element instanceof JsonObject); + JsonObject emptyMapJsonObject = (JsonObject) element; + assertTrue(emptyMapJsonObject.entrySet().isEmpty()); + } +} diff --git a/gson/src/test/java/com/google/gson/DisjunctionExclusionStrategyTest.java b/gson/src/test/java/com/google/gson/DisjunctionExclusionStrategyTest.java new file mode 100644 index 00000000..5383e6fa --- /dev/null +++ b/gson/src/test/java/com/google/gson/DisjunctionExclusionStrategyTest.java @@ -0,0 +1,80 @@ +/* + * 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.google.gson; + +import com.google.gson.DisjunctionExclusionStrategy; +import com.google.gson.ExclusionStrategy; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; + +/** + * Unit tests for the {@link DisjunctionExclusionStrategy} class. + * + * @author Joel Leitch + */ +public class DisjunctionExclusionStrategyTest extends TestCase { + + private static final ExclusionStrategy FALSE_STRATEGY = new MockExclusionStrategy(false, false); + private static final ExclusionStrategy TRUE_STRATEGY = new MockExclusionStrategy(true, true); + private static final Class CLAZZ = String.class; + private static final Field FIELD = CLAZZ.getFields()[0]; + + public void testBadInstantiation() throws Exception { + try { + new DisjunctionExclusionStrategy(); + } catch (IllegalArgumentException expected) { } + + try { + ExclusionStrategy[] constructorParam = null; + new DisjunctionExclusionStrategy(constructorParam); + } catch (IllegalArgumentException expected) { } + + try { + ExclusionStrategy[] constructorParam = new ExclusionStrategy[0]; + new DisjunctionExclusionStrategy(constructorParam); + } catch (IllegalArgumentException expected) { } + + try { + List constructorParam = null; + new DisjunctionExclusionStrategy(constructorParam); + } catch (IllegalArgumentException expected) { } + + try { + List constructorParam = new LinkedList(); + new DisjunctionExclusionStrategy(constructorParam); + } catch (IllegalArgumentException expected) { } + } + + public void testSkipFieldsWithMixedTrueAndFalse() throws Exception { + DisjunctionExclusionStrategy strategy = + new DisjunctionExclusionStrategy(FALSE_STRATEGY, TRUE_STRATEGY); + + assertTrue(strategy.shouldSkipClass(CLAZZ)); + assertTrue(strategy.shouldSkipField(FIELD)); + } + + public void testSkipFieldsWithFalseOnly() throws Exception { + DisjunctionExclusionStrategy strategy = new DisjunctionExclusionStrategy(FALSE_STRATEGY); + + assertFalse(strategy.shouldSkipClass(CLAZZ)); + assertFalse(strategy.shouldSkipField(FIELD)); + } +} diff --git a/gson/src/test/java/com/google/gson/EscaperTest.java b/gson/src/test/java/com/google/gson/EscaperTest.java new file mode 100644 index 00000000..4b530724 --- /dev/null +++ b/gson/src/test/java/com/google/gson/EscaperTest.java @@ -0,0 +1,141 @@ +/* + * 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.google.gson; + +import junit.framework.TestCase; + +/** + * Performs some unit testing for the {@link Escaper} class. + * + * @author Joel Leitch + */ +public class EscaperTest extends TestCase { + + public void testNoSpecialCharacters() { + String value = "Testing123"; + String escapedString = Escaper.escapeJsonString(value); + assertEquals(value, escapedString); + } + + public void testNewlineEscaping() throws Exception { + String containsNewline = "123\n456"; + String escapedString = Escaper.escapeJsonString(containsNewline); + assertEquals("123\\n456", escapedString); + } + + public void testCarrageReturnEscaping() throws Exception { + String containsCarrageReturn = "123\r456"; + String escapedString = Escaper.escapeJsonString(containsCarrageReturn); + assertEquals("123\\r456", escapedString); + } + + public void testTabEscaping() throws Exception { + String containsTab = "123\t456"; + String escapedString = Escaper.escapeJsonString(containsTab); + assertEquals("123\\t456", escapedString); + } + + public void testQuoteEscaping() throws Exception { + String containsQuote = "123\"456"; + String escapedString = Escaper.escapeJsonString(containsQuote); + assertEquals("123\\\"456", escapedString); + } + + public void testEqualsEscaping() throws Exception { + String containsEquals = "123=456"; + int index = containsEquals.indexOf('='); + String unicodeValue = convertToUnicodeString(Character.codePointAt(containsEquals, index)); + String escapedString = Escaper.escapeJsonString(containsEquals); + assertEquals("123" + unicodeValue + "456", escapedString); + } + + public void testGreaterThanAndLessThanEscaping() throws Exception { + String containsLtGt = "123>456<"; + int gtIndex = containsLtGt.indexOf('>'); + int ltIndex = containsLtGt.indexOf('<'); + String gtAsUnicode = convertToUnicodeString(Character.codePointAt(containsLtGt, gtIndex)); + String ltAsUnicode = convertToUnicodeString(Character.codePointAt(containsLtGt, ltIndex)); + + String escapedString = Escaper.escapeJsonString(containsLtGt); + assertEquals("123" + gtAsUnicode + "456" + ltAsUnicode, escapedString); + } + + public void testAmpersandEscaping() throws Exception { + String containsAmp = "123&456"; + int ampIndex = containsAmp.indexOf('&'); + String ampAsUnicode = convertToUnicodeString(Character.codePointAt(containsAmp, ampIndex)); + + String escapedString = Escaper.escapeJsonString(containsAmp); + assertEquals("123" + ampAsUnicode + "456", escapedString); + + char ampCharAsUnicode = '\u0026'; + String containsAmpUnicode = "123" + ampCharAsUnicode + "456"; + escapedString = Escaper.escapeJsonString(containsAmpUnicode); + assertEquals("123" + ampAsUnicode + "456", escapedString); + } + + public void testSlashEscaping() throws Exception { + String containsSlash = "123\\456"; + String escapedString = Escaper.escapeJsonString(containsSlash); + assertEquals("123\\\\456", escapedString); + } + + public void testSingleQuoteNotEscaped() throws Exception { + String containsSingleQuote = "123'456"; + String escapedString = Escaper.escapeJsonString(containsSingleQuote); + assertEquals(containsSingleQuote, escapedString); + } + + public void testRequiredEscapingUnicodeCharacter() throws Exception { + char unicodeChar = '\u2028'; + String unicodeString = "Testing" + unicodeChar; + + String escapedString = Escaper.escapeJsonString(unicodeString); + assertFalse(unicodeString.equals(escapedString)); + assertEquals("Testing\\u2028", escapedString); + } + + public void testUnicodeCharacterStringNoEscaping() throws Exception { + String unicodeString = "\u0065\u0066"; + + String escapedString = Escaper.escapeJsonString(unicodeString); + assertEquals(unicodeString, escapedString); + } + + /* + public void testChineseCharacterEscaping() throws Exception { + String unicodeString = "\u597d\u597d\u597d"; + String chineseString = "好好好"; + assertEquals(unicodeString, chineseString); + + String expectedEscapedString = "\\u597d\\u597d\\u597d"; + String escapedString = Escaper.escapeJsonString(chineseString); + assertEquals(expectedEscapedString, escapedString); + } + */ + + private String convertToUnicodeString(int codepoint) { + String hexValue = Integer.toHexString(codepoint); + StringBuilder sb = new StringBuilder("\\u"); + for (int i = 0; i < 4 - hexValue.length(); i++) { + sb.append(0); + } + sb.append(hexValue); + + return sb.toString().toLowerCase(); + } +} diff --git a/gson/src/test/java/com/google/gson/ExposeAnnotationBasedExclusionStrategyTest.java b/gson/src/test/java/com/google/gson/ExposeAnnotationBasedExclusionStrategyTest.java new file mode 100644 index 00000000..30dc0af9 --- /dev/null +++ b/gson/src/test/java/com/google/gson/ExposeAnnotationBasedExclusionStrategyTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.annotations.Expose; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +/** + * Unit tests for the {@link ExposeAnnotationBasedExclusionStrategy} class. + * + * @author Joel Leitch + */ +public class ExposeAnnotationBasedExclusionStrategyTest extends TestCase { + private ExposeAnnotationBasedExclusionStrategy strategy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + strategy = new ExposeAnnotationBasedExclusionStrategy(); + } + + public void testNeverSkipClasses() throws Exception { + assertFalse(strategy.shouldSkipClass(MockObject.class)); + } + + public void testSkipNonAnnotatedFields() throws Exception { + Field f = MockObject.class.getField("hiddenField"); + assertTrue(strategy.shouldSkipField(f)); + } + + public void testNeverSkipExposedAnnotatedFields() throws Exception { + Field f = MockObject.class.getField("exposedField"); + assertFalse(strategy.shouldSkipField(f)); + } + + private static class MockObject { + @Expose + public final int exposedField = 0; + public final int hiddenField = 0; + } +} diff --git a/gson/src/test/java/com/google/gson/FunctionalWithInternalDependenciesTest.java b/gson/src/test/java/com/google/gson/FunctionalWithInternalDependenciesTest.java new file mode 100644 index 00000000..8d23934b --- /dev/null +++ b/gson/src/test/java/com/google/gson/FunctionalWithInternalDependenciesTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson; + +import com.google.gson.common.TestTypes.ArrayOfObjects; +import com.google.gson.common.TestTypes.BagOfPrimitives; +import com.google.gson.common.TestTypes.ClassWithNoFields; +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Functional tests for Gson that depend on some internal package-protected elements of + * com.google.gson package and hence must be placed in the same package. We should make every + * attempt to migrate tests out of this class. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class FunctionalWithInternalDependenciesTest extends TestCase { + private static int INDENTATION_SIZE = 2; + private static int PRINT_MARGIN = 100; + private static int RIGHT_MARGIN = 8; + + private static boolean DEBUG = false; + + private GsonBuilder builder; + + @Override + protected void setUp() throws Exception { + super.setUp(); + builder = new GsonBuilder(); + } + + public void testAnonymousLocalClassesSerialization() { + Gson gson = new Gson(new ObjectNavigatorFactory(new ModifierBasedExclusionStrategy( + true, Modifier.TRANSIENT, Modifier.STATIC), Gson.DEFAULT_NAMING_POLICY)); + assertEquals("{}", gson.toJson(new ClassWithNoFields() { + // empty anonymous class + })); + } + + public void testPrettyPrintList() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + BagOfPrimitives b = new BagOfPrimitives(); + List listOfB = new LinkedList(); + for (int i = 0; i < 15; ++i) { + listOfB.add(b); + } + Type typeOfSrc = new TypeToken>() {}.getType(); + String json = gson.toJson(listOfB, typeOfSrc); + print(json); + assertPrintMargin(json); + } + + public void testPrettyPrintArrayOfObjects() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + ArrayOfObjects target = new ArrayOfObjects(); + String json = gson.toJson(target); + print(json); + assertPrintMargin(json); + } + + public void testPrettyPrintArrayOfPrimitives() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + int[] ints = new int[] { 1, 2, 3, 4, 5 }; + String json = gson.toJson(ints); + assertEquals("[1,2,3,4,5]\n", json); + } + + public void testPrettyPrintArrayOfPrimitiveArrays() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + int[][] ints = new int[][] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 0 }, { 10 } }; + String json = gson.toJson(ints); + assertEquals("[[1,2],[3,4],[5,6],[7,8],[9,0],[10]]\n", json); + } + + public void testPrettyPrintListOfPrimitiveArrays() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + List list = Arrays.asList(new Integer[][] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, + { 9, 0 }, { 10 } }); + String json = gson.toJson(list); + assertEquals("[[1,2],[3,4],[5,6],[7,8],[9,0],[10]]\n", json); + } + + public void testMultipleArrays() { + JsonFormatter formatter = new JsonPrintFormatter(PRINT_MARGIN, INDENTATION_SIZE, RIGHT_MARGIN); + Gson gson = builder.setFormatter(formatter).create(); + int[][][] ints = new int[][][] { { { 1 }, { 2 } } }; + String json = gson.toJson(ints); + assertEquals("[[[1],[2]]]\n", json); + } + + private void print(String msg) { + if (DEBUG) { + System.out.println(msg); + } + } + + private void assertPrintMargin(String str) { + int position = 0; + char[] chars = str.toCharArray(); + for (int i = 0; i < chars.length; ++i, ++position) { + char c = chars[i]; + if (c == '\n') { + position = 0; + } + assertTrue(position < PRINT_MARGIN + RIGHT_MARGIN); + } + } +} diff --git a/gson/src/test/java/com/google/gson/GenericArrayTypeImplTest.java b/gson/src/test/java/com/google/gson/GenericArrayTypeImplTest.java new file mode 100644 index 00000000..c50acb29 --- /dev/null +++ b/gson/src/test/java/com/google/gson/GenericArrayTypeImplTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.List; + +/** + * Unit tests for the {@link GenericArrayTypeImpl} class. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class GenericArrayTypeImplTest extends TestCase { + + private Type parameterizedType; + private Type genericArrayType; + private GenericArrayTypeImpl ourType; + + @Override + protected void setUp() throws Exception { + super.setUp(); + parameterizedType = new TypeToken>() {}.getType(); + genericArrayType = new TypeToken[]>() {}.getType(); + ourType = new GenericArrayTypeImpl(parameterizedType); + } + + public void testOurTypeFunctionality() throws Exception { + assertEquals(parameterizedType, ourType.getGenericComponentType()); + assertEquals(genericArrayType, ourType); + assertEquals(genericArrayType.hashCode(), ourType.hashCode()); + } + + public void testNotEquals() throws Exception { + Type differentGenericArrayType = new TypeToken[][]>() {}.getType(); + + assertFalse(differentGenericArrayType.equals(ourType)); + assertFalse(ourType.equals(differentGenericArrayType)); + } +} diff --git a/gson/src/test/java/com/google/gson/GsonBuilderTest.java b/gson/src/test/java/com/google/gson/GsonBuilderTest.java new file mode 100755 index 00000000..d1756da0 --- /dev/null +++ b/gson/src/test/java/com/google/gson/GsonBuilderTest.java @@ -0,0 +1,33 @@ +/* + * 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.google.gson; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link GsonBuilder}. + * + * @author Inderjeet Singh + */ +public class GsonBuilderTest extends TestCase { + + public void testCreatingMoreThanOnce() { + GsonBuilder builder = new GsonBuilder(); + builder.create(); + builder.create(); + } +} diff --git a/gson/src/test/java/com/google/gson/GsonTypeAdapterTest.java b/gson/src/test/java/com/google/gson/GsonTypeAdapterTest.java new file mode 100644 index 00000000..2c98781d --- /dev/null +++ b/gson/src/test/java/com/google/gson/GsonTypeAdapterTest.java @@ -0,0 +1,108 @@ +/* + * 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.google.gson; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Contains numerous tests involving registered type converters with a Gson instance. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class GsonTypeAdapterTest extends TestCase { + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new GsonBuilder() + .registerTypeAdapter(AtomicLong.class, new ExceptionTypeAdapter()) + .registerTypeAdapter(AtomicInteger.class, new AtomicIntegerTypeAdapter()) + .create(); + } + + public void testDefaultTypeAdapterThrowsParseException() throws Exception { + try { + gson.fromJson("{\"abc\":123}", BigInteger.class); + fail("Should have thrown a JsonParseException"); + } catch (JsonParseException expected) { } + } + + public void testTypeAdapterThrowsException() throws Exception { + try { + gson.toJson(new AtomicLong(0)); + fail("Type Adapter should have thrown an exception"); + } catch (JsonParseException expected) { } + + try { + gson.fromJson("123", AtomicLong.class); + fail("Type Adapter should have thrown an exception"); + } catch (JsonParseException expected) { } + } + + public void testTypeAdapterProperlyConvertsTypes() throws Exception { + int intialValue = 1; + AtomicInteger atomicInt = new AtomicInteger(intialValue); + String json = gson.toJson(atomicInt); + assertEquals(intialValue + 1, Integer.parseInt(json)); + + atomicInt = gson.fromJson(json, AtomicInteger.class); + assertEquals(intialValue, atomicInt.get()); + } + + public void testTypeAdapterDoesNotAffectNonAdaptedTypes() throws Exception { + String expected = "blah"; + String actual = gson.toJson(expected); + assertEquals("\"" + expected + "\"", actual); + + actual = gson.fromJson(actual, String.class); + assertEquals(expected, actual); + } + + private static class ExceptionTypeAdapter + implements JsonSerializer, JsonDeserializer { + public JsonElement serialize( + AtomicLong src, Type typeOfSrc, JsonSerializationContext context) { + throw new IllegalStateException(); + } + + public AtomicLong deserialize( + JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + throw new IllegalStateException(); + } + } + + private static class AtomicIntegerTypeAdapter + implements JsonSerializer, JsonDeserializer { + public JsonElement serialize(AtomicInteger src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.incrementAndGet()); + } + + public AtomicInteger deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + int intValue = json.getAsInt(); + return new AtomicInteger(--intValue); + } + } +} diff --git a/gson/src/test/java/com/google/gson/JavaFieldNamingPolicyTest.java b/gson/src/test/java/com/google/gson/JavaFieldNamingPolicyTest.java new file mode 100644 index 00000000..cf51e076 --- /dev/null +++ b/gson/src/test/java/com/google/gson/JavaFieldNamingPolicyTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +/** + * Tests for the {@link JavaFieldNamingPolicy} class. + * + * @author Joel Leitch + */ +public class JavaFieldNamingPolicyTest extends TestCase { + + private JavaFieldNamingPolicy namingPolicy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + namingPolicy = new JavaFieldNamingPolicy(); + } + + public void testFieldNamingPolicy() throws Exception { + Field f = String.class.getFields()[0]; + assertEquals(f.getName(), namingPolicy.translateName(f)); + } + + public void testNullField() throws Exception { + try { + namingPolicy.translateName((Field) null); + fail("Should have thrown an exception"); + } catch (IllegalArgumentException expected) { } + } +} diff --git a/gson/src/test/java/com/google/gson/JsonDeserializerExceptionWrapperTest.java b/gson/src/test/java/com/google/gson/JsonDeserializerExceptionWrapperTest.java new file mode 100644 index 00000000..f2d30b08 --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonDeserializerExceptionWrapperTest.java @@ -0,0 +1,90 @@ +/* + * 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.google.gson; + +import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.util.Date; + +/** + * Simple unit tests for the {@link JsonDeserializerExceptionWrapper} class. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class JsonDeserializerExceptionWrapperTest extends TestCase { + + private static final String DATE_STRING = + DateFormat.getDateInstance(DateFormat.LONG).format(new Date()); + private static final JsonPrimitive PRIMITIVE_ELEMENT = new JsonPrimitive(DATE_STRING); + + public void testRethrowJsonParseException() throws Exception { + String errorMsg = "please rethrow me"; + JsonDeserializerExceptionWrapper wrappedJsonSerializer = + new JsonDeserializerExceptionWrapper( + new ExceptionJsonDeserializer(new JsonParseException(errorMsg))); + + try { + wrappedJsonSerializer.deserialize(PRIMITIVE_ELEMENT, String.class, null); + fail("JsonParseException should have been thrown"); + } catch (JsonParseException expected) { + assertNull(expected.getCause()); + assertEquals(errorMsg, expected.getMessage()); + } + } + + public void testWrappedExceptionPropagation() throws Exception { + IllegalArgumentException exceptionToThrow = new IllegalArgumentException(); + JsonDeserializerExceptionWrapper wrappedJsonSerializer = + new JsonDeserializerExceptionWrapper( + new ExceptionJsonDeserializer(exceptionToThrow)); + + try { + wrappedJsonSerializer.deserialize(PRIMITIVE_ELEMENT, String.class, null); + fail("JsonParseException should have been thrown"); + } catch (JsonParseException expected) { + assertEquals(exceptionToThrow, expected.getCause()); + } + } + + public void testProperSerialization() throws Exception { + DefaultDateTypeAdapter dateSerializer = new DefaultDateTypeAdapter(DateFormat.LONG); + JsonDeserializerExceptionWrapper wrappedJsonSerializer = + new JsonDeserializerExceptionWrapper(dateSerializer); + + Date expected = dateSerializer.deserialize(PRIMITIVE_ELEMENT, Date.class, null); + Date actual = wrappedJsonSerializer.deserialize(PRIMITIVE_ELEMENT, Date.class, null); + assertEquals(expected, actual); + } + + private static class ExceptionJsonDeserializer implements JsonDeserializer { + private final RuntimeException exceptionToThrow; + + public ExceptionJsonDeserializer(RuntimeException exceptionToThrow) { + this.exceptionToThrow = exceptionToThrow; + } + + public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + throw exceptionToThrow; + } + } +} \ No newline at end of file diff --git a/gson/src/test/java/com/google/gson/JsonEscapingVisitorTest.java b/gson/src/test/java/com/google/gson/JsonEscapingVisitorTest.java new file mode 100644 index 00000000..c88e6fb9 --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonEscapingVisitorTest.java @@ -0,0 +1,180 @@ +/* + * 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.google.gson; + +import junit.framework.TestCase; + +/** + * Performs some unit testing for the {@link JsonEscapingVisitor} class. + * + * @author Joel Leitch + */ +public class JsonEscapingVisitorTest extends TestCase { + private StubbedJsonElementVisitor stubVisitor; + private JsonEscapingVisitor escapingVisitor; + + @Override + protected void setUp() throws Exception { + super.setUp(); + stubVisitor = new StubbedJsonElementVisitor(); + escapingVisitor = new JsonEscapingVisitor(stubVisitor); + } + + public void testNonStringPrimitiveVisitation() throws Exception { + boolean value = true; + JsonPrimitive primitive = new JsonPrimitive(value); + escapingVisitor.visitPrimitive(primitive); + assertEquals(value, stubVisitor.primitiveReceived.getAsBoolean()); + } + + public void testStringPrimitiveVisitationNoEscapingRequired() throws Exception { + String value = "Testing123"; + JsonPrimitive primitive = new JsonPrimitive(value); + escapingVisitor.visitPrimitive(primitive); + assertEquals(value, stubVisitor.primitiveReceived.getAsObject()); + } + + public void testStringPrimitiveVisitationEscapingRequired() throws Exception { + String value = "Testing\"123"; + JsonPrimitive primitive = new JsonPrimitive(value); + escapingVisitor.visitPrimitive(primitive); + assertEquals(Escaper.escapeJsonString(value), stubVisitor.primitiveReceived.getAsString()); + } + + public void testNonStringArrayVisitation() throws Exception { + int value = 123; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonArray array = new JsonArray(); + array.add(primitive); + escapingVisitor.visitArrayMember(array, primitive, true); + assertEquals(value, stubVisitor.primitiveReceived.getAsInt()); + } + + public void testStringArrayVisitationNoEscaping() throws Exception { + String value = "Testing123"; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonArray array = new JsonArray(); + array.add(primitive); + escapingVisitor.visitArrayMember(array, primitive, true); + assertEquals(value, stubVisitor.primitiveReceived.getAsString()); + } + + public void testStringArrayVisitationEscapingRequired() throws Exception { + String value = "Testing\"123"; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonArray array = new JsonArray(); + array.add(primitive); + escapingVisitor.visitArrayMember(array, primitive, true); + assertEquals(Escaper.escapeJsonString(value), stubVisitor.primitiveReceived.getAsString()); + } + + public void testNonStringFieldVisitation() throws Exception { + String fieldName = "fieldName"; + int value = 123; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonObject object = new JsonObject(); + object.addProperty(fieldName, value); + + escapingVisitor.visitObjectMember(object, fieldName, primitive, true); + assertEquals(value, stubVisitor.primitiveReceived.getAsInt()); + } + + public void testStringFieldVisitationNoEscaping() throws Exception { + String fieldName = "fieldName"; + String value = "Testing123"; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonObject object = new JsonObject(); + object.addProperty(fieldName, value); + + escapingVisitor.visitObjectMember(object, fieldName, primitive, true); + assertEquals(value, stubVisitor.primitiveReceived.getAsString()); + } + + public void testStringFieldVisitationEscapingRequired() throws Exception { + String fieldName = "fieldName"; + String value = "Testing\"123"; + JsonPrimitive primitive = new JsonPrimitive(value); + JsonObject object = new JsonObject(); + object.addProperty(fieldName, value); + + escapingVisitor.visitObjectMember(object, fieldName, primitive, true); + assertEquals(Escaper.escapeJsonString(value), stubVisitor.primitiveReceived.getAsString()); + } + + private static class StubbedJsonElementVisitor implements JsonElementVisitor { + public JsonPrimitive primitiveReceived; + + public void endArray(JsonArray array) { + // Do nothing + } + + public void endObject(JsonObject object) { + // Do nothing + } + + public void startArray(JsonArray array) { + // Do nothing + } + + public void startObject(JsonObject object) { + // Do nothing + } + + public void visitArrayMember(JsonArray parent, JsonPrimitive member, boolean isFirst) { + primitiveReceived = member; + } + + public void visitArrayMember(JsonArray parent, JsonArray member, boolean isFirst) { + // Do nothing + } + + public void visitArrayMember(JsonArray parent, JsonObject member, boolean isFirst) { + // Do nothing + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonPrimitive member, boolean isFirst) { + primitiveReceived = member; + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonArray member, boolean isFirst) { + // Do nothing + } + + public void visitObjectMember( + JsonObject parent, String memberName, JsonObject member, boolean isFirst) { + // Do nothing + } + + public void visitPrimitive(JsonPrimitive primitive) { + primitiveReceived = primitive; + } + + public void visitNullArrayMember(JsonArray parent, boolean isFirst) { + // Do nothing + } + + public void visitNull() { + // Do nothing + } + + public void visitNullObjectMember(JsonObject parent, String memberName, boolean isFirst) { + // Do nothing + } + } +} diff --git a/gson/src/test/java/com/google/gson/JsonFieldNameValidatorTest.java b/gson/src/test/java/com/google/gson/JsonFieldNameValidatorTest.java new file mode 100644 index 00000000..20121a1c --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonFieldNameValidatorTest.java @@ -0,0 +1,97 @@ +/* + * 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.google.gson; + +import junit.framework.TestCase; + +/** + * Unit tests for the {@link JsonFieldNameValidator} class. + * + * @author Joel Leitch + */ +public class JsonFieldNameValidatorTest extends TestCase { + + private JsonFieldNameValidator validator; + + @Override + protected void setUp() throws Exception { + super.setUp(); + validator = new JsonFieldNameValidator(); + } + + public void testValidFieldBeginsWithDollarSign() throws Exception { + String fieldName = "$abc"; + assertEquals(fieldName, validator.validate(fieldName)); + } + + public void testValidFieldBeginsWithUnderscore() throws Exception { + String fieldName = "_abc"; + assertEquals(fieldName, validator.validate(fieldName)); + } + + public void testValidFieldBeginsWithLetter() throws Exception { + String fieldName = "abc"; + assertEquals(fieldName, validator.validate(fieldName)); + } + + public void testValidFieldMixingLetter() throws Exception { + String fieldName = "$abc_12v$34"; + assertEquals(fieldName, validator.validate(fieldName)); + } + + public void testInvalidFieldStartingWithNumbers() throws Exception { + try { + validator.validate("1abc"); + fail("Json field name can not start with a number"); + } catch (IllegalArgumentException expected) { } + } + + public void testInvalidFieldStartingTwoDollarSigns() throws Exception { + try { + validator.validate("$$abc"); + fail("Json field name can not start with a double dollar sign"); + } catch (IllegalArgumentException expected) { } + } + + public void testInvalidFieldStartingTwoUnderscores() throws Exception { + try { + validator.validate("__abc"); + fail("Json field name can not start with a double underscore"); + } catch (IllegalArgumentException expected) { } + } + + public void testInvalidFieldStartingDollarUnderscore() throws Exception { + try { + validator.validate("$_abc"); + fail("Json field name can not start with two non-alphabet characters"); + } catch (IllegalArgumentException expected) { } + } + + public void testKeywordAsFieldName() throws Exception { + try { + validator.validate("break"); + fail("Json field name can not be a reserved word"); + } catch (IllegalArgumentException expected) { } + } + + public void testInvalidCharacters() throws Exception { + try { + validator.validate("abc.123"); + fail("Json field name can not contain a period character"); + } catch (IllegalArgumentException expected) { } + } +} diff --git a/gson/src/test/java/com/google/gson/JsonSerializerExceptionWrapperTest.java b/gson/src/test/java/com/google/gson/JsonSerializerExceptionWrapperTest.java new file mode 100644 index 00000000..e019c9e0 --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonSerializerExceptionWrapperTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.util.Date; + +/** + * Simple unit tests for the {@link JsonSerializerExceptionWrapper} class. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class JsonSerializerExceptionWrapperTest extends TestCase { + + public void testRethrowJsonParseException() throws Exception { + String errorMsg = "please rethrow me"; + JsonSerializerExceptionWrapper wrappedJsonSerializer = + new JsonSerializerExceptionWrapper( + new ExceptionJsonSerializer(new JsonParseException(errorMsg))); + + try { + wrappedJsonSerializer.serialize("blah", String.class, null); + fail("JsonParseException should have been thrown"); + } catch (JsonParseException expected) { + assertNull(expected.getCause()); + assertEquals(errorMsg, expected.getMessage()); + } + } + + public void testWrappedExceptionPropagation() throws Exception { + IllegalArgumentException exceptionToThrow = new IllegalArgumentException(); + JsonSerializerExceptionWrapper wrappedJsonSerializer = + new JsonSerializerExceptionWrapper( + new ExceptionJsonSerializer(exceptionToThrow)); + + try { + wrappedJsonSerializer.serialize("blah", String.class, null); + fail("JsonParseException should have been thrown"); + } catch (JsonParseException expected) { + assertEquals(exceptionToThrow, expected.getCause()); + } + } + + public void testProperSerialization() throws Exception { + Date now = new Date(); + DefaultDateTypeAdapter dateSerializer = new DefaultDateTypeAdapter(DateFormat.LONG); + JsonSerializerExceptionWrapper wrappedJsonSerializer = + new JsonSerializerExceptionWrapper(dateSerializer); + + JsonElement expected = dateSerializer.serialize(now, Date.class, null); + JsonElement actual = wrappedJsonSerializer.serialize(now, Date.class, null); + assertEquals(expected.getAsString(), actual.getAsString()); + } + + private static class ExceptionJsonSerializer implements JsonSerializer { + private final RuntimeException exceptionToThrow; + + public ExceptionJsonSerializer(RuntimeException exceptionToThrow) { + this.exceptionToThrow = exceptionToThrow; + } + + public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) { + throw exceptionToThrow; + } + } +} diff --git a/gson/src/test/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicyTest.java b/gson/src/test/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicyTest.java new file mode 100644 index 00000000..d29864ca --- /dev/null +++ b/gson/src/test/java/com/google/gson/LowerCamelCaseSeparatorNamingPolicyTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import junit.framework.TestCase; + +/** + * Tests for the {@link LowerCamelCaseSeparatorNamingPolicy} class. + * + * @author Joel Leitch + */ +public class LowerCamelCaseSeparatorNamingPolicyTest extends TestCase { + + private static final Class CLASS = String.class; + private static final String UNDERSCORE = "_"; + + private LowerCamelCaseSeparatorNamingPolicy namingPolicy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + namingPolicy = new LowerCamelCaseSeparatorNamingPolicy(UNDERSCORE); + } + + public void testNameBeginsWithLowerCase() throws Exception { + String translatedName = namingPolicy.translateName("testNameBeginsWithLower", CLASS, null); + assertEquals("test_name_begins_with_lower", translatedName); + } + + public void testNameBeginsWithUpperCase() throws Exception { + String translatedName = namingPolicy.translateName("TestNameBeginsWithUpper", CLASS, null); + assertEquals("test_name_begins_with_upper", translatedName); + } + + public void testExceptionPossiblyIncorrectSeparation() throws Exception { + String translatedName = namingPolicy.translateName("aURL", CLASS, null); + assertEquals("a_u_r_l", translatedName); + } +} diff --git a/gson/src/test/java/com/google/gson/LowerCaseNamingPolicyTest.java b/gson/src/test/java/com/google/gson/LowerCaseNamingPolicyTest.java new file mode 100644 index 00000000..56d2c2b3 --- /dev/null +++ b/gson/src/test/java/com/google/gson/LowerCaseNamingPolicyTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.LowerCaseNamingPolicy; + +import junit.framework.TestCase; + +/** + * Tests for the {@link LowerCaseNamingPolicy} class. + * + * @author Joel Leitch + */ +public class LowerCaseNamingPolicyTest extends TestCase { + private static final String ALL_LOWER = "abcdefg"; + private static final String ALL_UPPER = "ABCDEFG"; + private static final String MIXED = "aBcdeFg"; + + private LowerCaseNamingPolicy namingPolicy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + namingPolicy = new LowerCaseNamingPolicy(); + } + + public void testAllLowerCase() throws Exception { + assertEquals(ALL_LOWER, namingPolicy.translateName(ALL_LOWER, String.class, null)); + } + + public void testAllUpperCase() throws Exception { + assertEquals(ALL_LOWER, namingPolicy.translateName(ALL_UPPER, String.class, null)); + } + + public void testMixedCase() throws Exception { + assertEquals(ALL_LOWER, namingPolicy.translateName(MIXED, String.class, null)); + } +} diff --git a/gson/src/test/java/com/google/gson/MemoryRefStackTest.java b/gson/src/test/java/com/google/gson/MemoryRefStackTest.java new file mode 100644 index 00000000..a05d2b8c --- /dev/null +++ b/gson/src/test/java/com/google/gson/MemoryRefStackTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.MemoryRefStack; + +import junit.framework.TestCase; + +import java.util.EmptyStackException; + +/** + * Unit tests for the {@link MemoryRefStack} class. + * + * @author Joel Leitch + */ +public class MemoryRefStackTest extends TestCase { + private MemoryRefStack stack; + + @Override + protected void setUp() throws Exception { + super.setUp(); + stack = new MemoryRefStack(); + } + + public void testPeekEmptyStack() throws Exception { + try { + stack.peek(); + } catch (EmptyStackException expected) { } + } + + public void testPushPeekAndPop() throws Exception { + MockObject obj = new MockObject(); + + assertEquals(obj, stack.push(obj)); + assertEquals(obj, stack.peek()); + assertEquals(obj, stack.pop()); + } + + public void testPopTooMany() throws Exception { + MockObject obj = new MockObject(); + stack.push(obj); + assertEquals(obj, stack.pop()); + + try { + stack.pop(); + } catch (EmptyStackException expected) { } + } + + public void testContains() throws Exception { + MockObject objA = new MockObject(); + MockObject objB = new MockObject(); + assertEquals(objA, objB); + + stack.push(objA); + assertFalse(stack.contains(objB)); + assertTrue(stack.contains(objA)); + } + + private static class MockObject { + private final int value = 1; + + @Override + public boolean equals(Object obj) { + return obj instanceof MockObject && value == ((MockObject) obj).value; + } + + @Override + public int hashCode() { + return value; + } + } +} diff --git a/gson/src/test/java/com/google/gson/MockExclusionStrategy.java b/gson/src/test/java/com/google/gson/MockExclusionStrategy.java new file mode 100644 index 00000000..674148bc --- /dev/null +++ b/gson/src/test/java/com/google/gson/MockExclusionStrategy.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.ExclusionStrategy; + +import java.lang.reflect.Field; + +/** + * This is a configurable {@link ExclusionStrategy} that can be used for + * unit testing. + * + * @author Joel Leitch + */ +public class MockExclusionStrategy implements ExclusionStrategy { + private final boolean skipClass; + private final boolean skipField; + + public MockExclusionStrategy(boolean skipClass, boolean skipField) { + this.skipClass = skipClass; + this.skipField = skipField; + } + + public boolean shouldSkipField(Field f) { + return skipField; + } + + public boolean shouldSkipClass(Class clazz) { + return skipClass; + } +} diff --git a/gson/src/test/java/com/google/gson/ModifyFirstLetterNamingPolicyTest.java b/gson/src/test/java/com/google/gson/ModifyFirstLetterNamingPolicyTest.java new file mode 100644 index 00000000..c3274ea3 --- /dev/null +++ b/gson/src/test/java/com/google/gson/ModifyFirstLetterNamingPolicyTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import junit.framework.TestCase; + +/** + * Unit test for the {@link com.google.gson.ModifyFirstLetterNamingPolicy} class. + * + * @author Joel Leitch + */ +public class ModifyFirstLetterNamingPolicyTest extends TestCase { + + public void testInvalidConstruction() throws Exception { + try { + new ModifyFirstLetterNamingPolicy(null); + fail("Null values are not allowed as a constructor parameters"); + } catch (IllegalArgumentException expected) { } + } + + public void testLowerCaseFirstLetter() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.LOWER); + assertEquals("blah", policy.translateName("Blah", String.class, null)); + assertEquals("blah", policy.translateName("blah", String.class, null)); + } + + public void testUpperCaseFirstLetter() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("Blah", policy.translateName("blah", String.class, null)); + assertEquals("Blah", policy.translateName("Blah", String.class, null)); + } + + public void testSingleCharacterField() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("B", policy.translateName("b", String.class, null)); + assertEquals("B", policy.translateName("B", String.class, null)); + } + + public void testFieldStartsWithUnderscore() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("_Blah", policy.translateName("_blah", String.class, null)); + assertEquals("_Blah", policy.translateName("_Blah", String.class, null)); + } + + public void testFieldStartsWithUnderscoreFollowedBySingleLetter() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("_B", policy.translateName("_b", String.class, null)); + assertEquals("_B", policy.translateName("_B", String.class, null)); + } + + public void testFieldHasSingleNonLetter() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.LOWER); + assertEquals("_", policy.translateName("_", String.class, null)); + + policy = new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("_", policy.translateName("_", String.class, null)); + } + + public void testFieldHasNoLetters() throws Exception { + ModifyFirstLetterNamingPolicy policy = + new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.LOWER); + assertEquals("$_$", policy.translateName("$_$", String.class, null)); + + policy = new ModifyFirstLetterNamingPolicy(ModifyFirstLetterNamingPolicy.LetterModifier.UPPER); + assertEquals("$_$", policy.translateName("$_$", String.class, null)); + } +} diff --git a/gson/src/test/java/com/google/gson/NullExclusionStrategyTest.java b/gson/src/test/java/com/google/gson/NullExclusionStrategyTest.java new file mode 100644 index 00000000..7b0eee5e --- /dev/null +++ b/gson/src/test/java/com/google/gson/NullExclusionStrategyTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.NullExclusionStrategy; + +import junit.framework.TestCase; + +/** + * Unit test for the {@link NullExclusionStrategy} class. + * + * @author Joel Leitch + */ +public class NullExclusionStrategyTest extends TestCase { + private NullExclusionStrategy strategy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + strategy = new NullExclusionStrategy(); + } + + public void testNeverSkipsClass() throws Exception { + assertFalse(strategy.shouldSkipClass(String.class)); + } + + public void testNeverSkipsField() throws Exception { + assertFalse(strategy.shouldSkipField("".getClass().getFields()[0])); + } +} diff --git a/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java b/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java new file mode 100644 index 00000000..c0642db8 --- /dev/null +++ b/gson/src/test/java/com/google/gson/ParameterizedTypeHandlerMapTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.List; + +/** + * Unit tests for the {@link ParameterizedTypeHandlerMap} class. + * + * @author Joel Leitch + */ +public class ParameterizedTypeHandlerMapTest extends TestCase { + private ParameterizedTypeHandlerMap paramMap; + + @Override + protected void setUp() throws Exception { + super.setUp(); + paramMap = new ParameterizedTypeHandlerMap(); + } + + public void testNullMap() throws Exception { + assertFalse(paramMap.hasSpecificHandlerFor(String.class)); + assertFalse(paramMap.hasAnyHandlerFor(String.class)); + assertNull(paramMap.getHandlerFor(String.class)); + } + + public void testHasGenericButNotSpecific() throws Exception { + Type specificType = new TypeToken>() {}.getType(); + String handler = "blah"; + paramMap.register(List.class, handler); + + assertFalse(paramMap.hasSpecificHandlerFor(specificType)); + assertTrue(paramMap.hasSpecificHandlerFor(List.class)); + assertTrue(paramMap.hasAnyHandlerFor(specificType)); + assertTrue(paramMap.hasAnyHandlerFor(List.class)); + assertEquals(handler, paramMap.getHandlerFor(specificType)); + } + + public void testHasSpecificType() throws Exception { + Type specificType = new TypeToken>() {}.getType(); + String handler = "blah"; + paramMap.register(specificType, handler); + + assertTrue(paramMap.hasSpecificHandlerFor(specificType)); + assertFalse(paramMap.hasSpecificHandlerFor(List.class)); + assertTrue(paramMap.hasAnyHandlerFor(specificType)); + assertFalse(paramMap.hasAnyHandlerFor(List.class)); + assertEquals(handler, paramMap.getHandlerFor(specificType)); + } + + public void testTypeOverridding() throws Exception { + String handler1 = "blah1"; + String handler2 = "blah2"; + paramMap.register(String.class, handler1); + paramMap.register(String.class, handler2); + + assertTrue(paramMap.hasSpecificHandlerFor(String.class)); + assertEquals(handler2, paramMap.getHandlerFor(String.class)); + } + + public void testMakeUnmodifiable() throws Exception { + paramMap.makeUnmodifiable(); + try { + paramMap.register(String.class, "blah"); + fail("Can not register handlers when map is unmodifiable"); + } catch (IllegalStateException expected) { } + } +} diff --git a/gson/src/test/java/com/google/gson/ParameterizedTypeImplTest.java b/gson/src/test/java/com/google/gson/ParameterizedTypeImplTest.java new file mode 100644 index 00000000..50a0401d --- /dev/null +++ b/gson/src/test/java/com/google/gson/ParameterizedTypeImplTest.java @@ -0,0 +1,57 @@ +/* + * 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.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.List; + +/** + * Unit tests for the {@link ParameterizedTypeImpl} class. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class ParameterizedTypeImplTest extends TestCase { + + private Type parameterizedType; + private ParameterizedTypeImpl ourType; + + @Override + protected void setUp() throws Exception { + super.setUp(); + parameterizedType = new TypeToken>() {}.getType(); + ourType = new ParameterizedTypeImpl(List.class, new Type[] { String.class }, null); + } + + public void testOurTypeFunctionality() throws Exception { + assertNull(ourType.getOwnerType()); + assertEquals(String.class, ourType.getActualTypeArguments()[0]); + assertEquals(List.class, ourType.getRawType()); + assertEquals(parameterizedType, ourType); + assertEquals(parameterizedType.hashCode(), ourType.hashCode()); + } + + public void testNotEquals() throws Exception { + Type differentParameterizedType = new TypeToken>() {}.getType(); + assertFalse(differentParameterizedType.equals(ourType)); + assertFalse(ourType.equals(differentParameterizedType)); + } +} diff --git a/gson/src/test/java/com/google/gson/ParamterizedTypeFixtures.java b/gson/src/test/java/com/google/gson/ParamterizedTypeFixtures.java new file mode 100644 index 00000000..a977fd28 --- /dev/null +++ b/gson/src/test/java/com/google/gson/ParamterizedTypeFixtures.java @@ -0,0 +1,161 @@ +/* + * 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.google.gson; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +/** + * This class contains some test fixtures for Parameterized types. These classes should ideally + * belong either in the common or functional package, but they are placed here because they need + * access to package protected elements of com.google.gson. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class ParamterizedTypeFixtures { + + public static class MyParameterizedType { + public final T value; + public MyParameterizedType(T value) { + this.value = value; + } + public T getValue() { + return value; + } + + public String getExpectedJson() { + String valueAsJson = getExpectedJson(value); + return String.format("{\"value\":%s}", valueAsJson); + } + + private String getExpectedJson(Object obj) { + Class clazz = obj.getClass(); + if (Primitives.isWrapperType(Primitives.wrap(clazz))) { + return obj.toString(); + } else if (obj.getClass().equals(String.class)) { + return "\"" + obj.toString() + "\""; + } else { + // Try invoking a getExpectedJson() method if it exists + try { + Method method = clazz.getMethod("getExpectedJson"); + Object results = method.invoke(obj); + return (String) results; + } catch (SecurityException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public int hashCode() { + return value == null ? 0 : value.hashCode(); + } + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + MyParameterizedType other = (MyParameterizedType) obj; + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!value.equals(other.value)) { + return false; + } + return true; + } + } + + public static class MyParameterizedTypeInstanceCreator + implements InstanceCreator>{ + private final T instanceOfT; + /** + * Caution the specified instance is reused by the instance creator for each call. + * This means that the fields of the same objects will be overwritten by Gson. + * This is usually fine in tests since there we deserialize just once, but quite + * dangerous in practice. + * + * @param instanceOfT + */ + public MyParameterizedTypeInstanceCreator(T instanceOfT) { + this.instanceOfT = instanceOfT; + } + public MyParameterizedType createInstance(Type type) { + return new MyParameterizedType(instanceOfT); + } + } + + public static class MyParameterizedTypeAdapter + implements JsonSerializer>, JsonDeserializer> { + @SuppressWarnings("unchecked") + public static String getExpectedJson(MyParameterizedType obj) { + Class clazz = (Class) obj.value.getClass(); + boolean addQuotes = !clazz.isArray() && !Primitives.unwrap(clazz).isPrimitive(); + StringBuilder sb = new StringBuilder("{\""); + sb.append(obj.value.getClass().getSimpleName()).append("\":"); + if (addQuotes) { + sb.append("\""); + } + sb.append(obj.value.toString()); + if (addQuotes) { + sb.append("\""); + } + sb.append("}"); + return sb.toString(); + } + + public JsonElement serialize(MyParameterizedType src, Type classOfSrc, + JsonSerializationContext context) { + JsonObject json = new JsonObject(); + T value = src.getValue(); + json.add(value.getClass().getSimpleName(), context.serialize(value)); + return json; + } + + @SuppressWarnings("unchecked") + public MyParameterizedType deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + Type genericClass = TypeUtils.getActualTypeForFirstTypeVariable(typeOfT); + TypeInfo typeInfo = new TypeInfo(genericClass); + String className = typeInfo.getRawClass().getSimpleName(); + T value = (T) json.getAsJsonObject().get(className).getAsObject(); + if (typeInfo.isPrimitive()) { + PrimitiveTypeAdapter typeAdapter = new PrimitiveTypeAdapter(); + value = (T) typeAdapter.adaptType(value, typeInfo.getRawClass()); + } + return new MyParameterizedType(value); + } + } +} diff --git a/gson/src/test/java/com/google/gson/PrimitiveTypeAdapterTest.java b/gson/src/test/java/com/google/gson/PrimitiveTypeAdapterTest.java new file mode 100644 index 00000000..149ded02 --- /dev/null +++ b/gson/src/test/java/com/google/gson/PrimitiveTypeAdapterTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import junit.framework.TestCase; + +/** + * Performs some unit testing for the {@link PrimitiveTypeAdapter} class. + * + * @author Joel Leitch + */ +public class PrimitiveTypeAdapterTest extends TestCase { + private PrimitiveTypeAdapter typeAdapter; + + @Override + protected void setUp() throws Exception { + super.setUp(); + typeAdapter = new PrimitiveTypeAdapter(); + } + + public void testImproperConversion() throws Exception { + double someValue = 1.0; + try { + typeAdapter.adaptType(someValue, String.class); + fail("Should not be able to convert incompatible types."); + } catch (JsonParseException expected) { } + } + + public void testImproperCharacterConversion() throws Exception { + String someValue = "test123"; + try { + typeAdapter.adaptType(someValue, Character.class); + fail("Should not be able to convert incompatible types."); + } catch (JsonParseException expected) { } + } + + public void testProperPrimitiveConversions() throws Exception { + String stringValue = "1.0"; + Double actualValue = typeAdapter.adaptType(stringValue, Double.class); + assertEquals(1.0, actualValue.doubleValue(), 0.0001); + + Double doubleValue = 1.0; + actualValue = typeAdapter.adaptType(doubleValue, Double.class); + assertEquals(1.0, actualValue.doubleValue(), 0.0001); + + stringValue = "A"; + Character actualCharacter = typeAdapter.adaptType(stringValue, Character.class); + assertEquals('A', actualCharacter.charValue()); + } + + public void testProperEnumConversions() throws Exception { + TestEnum expected = TestEnum.TEST1; + TestEnum actual = typeAdapter.adaptType(expected, TestEnum.class); + assertEquals(expected, actual); + } + + private static enum TestEnum { + TEST1, TEST2, TEST3 + } +} diff --git a/gson/src/test/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicyTest.java b/gson/src/test/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicyTest.java new file mode 100644 index 00000000..bb9cf92b --- /dev/null +++ b/gson/src/test/java/com/google/gson/SerializedNameAnnotationInterceptingNamingPolicyTest.java @@ -0,0 +1,60 @@ +/* + * 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.google.gson; + +import com.google.gson.annotations.SerializedName; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +/** + * Unit tests for the {@link SerializedNameAnnotationInterceptingNamingPolicy} class. + * + * @author Joel Leitch + */ +public class SerializedNameAnnotationInterceptingNamingPolicyTest extends TestCase { + private static final String ANNOTATED_FIELD_NAME = "annotatedFieldName"; + + private SerializedNameAnnotationInterceptingNamingPolicy policy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + policy = new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy()); + } + + public void testFieldWithAnnotation() throws Exception { + String fieldName = "fieldWithAnnotation"; + Field f = SomeObject.class.getField(fieldName); + + assertFalse(ANNOTATED_FIELD_NAME.equals(fieldName)); + assertEquals(ANNOTATED_FIELD_NAME, policy.translateName(f)); + } + + public void testFieldWithoutAnnotation() throws Exception { + String fieldName = "fieldWithoutAnnotation"; + Field f = SomeObject.class.getField(fieldName); + + assertEquals(fieldName, policy.translateName(f)); + } + + private static class SomeObject { + @SerializedName(ANNOTATED_FIELD_NAME) public final int fieldWithAnnotation = 1; + public final int fieldWithoutAnnotation = 1; + } +} diff --git a/gson/src/test/java/com/google/gson/TypeInfoArrayTest.java b/gson/src/test/java/com/google/gson/TypeInfoArrayTest.java new file mode 100644 index 00000000..12492c4c --- /dev/null +++ b/gson/src/test/java/com/google/gson/TypeInfoArrayTest.java @@ -0,0 +1,123 @@ +/* + * 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.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.List; + +/** + * Small test for the {@link TypeInfoArray}. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class TypeInfoArrayTest extends TestCase { + + public void testArray() { + String[] a = {"a", "b", "c"}; + TypeInfoArray typeInfo = new TypeInfoArray(a.getClass()); + assertEquals(a.getClass(), typeInfo.getRawClass()); + assertEquals(String.class, typeInfo.getComponentRawType()); + } + + public void testArrayOfArrays() { + String[][] a = { + new String[]{"a1", "a2", "a3"}, + new String[]{"b1", "b2", "b3"}, + new String[]{"c1", "c2", "c3"}}; + TypeInfoArray typeInfo = new TypeInfoArray(a.getClass()); + assertEquals(a.getClass(), typeInfo.getRawClass()); + assertEquals(String.class, typeInfo.getComponentRawType()); + assertEquals(String[].class, typeInfo.getSecondLevelType()); + } + + public void testParameterizedArray() { + Type type = new TypeToken[]>() {}.getType(); + TypeInfoArray typeInfo = new TypeInfoArray(type); + assertEquals(List[].class, typeInfo.getRawClass()); + assertEquals(List.class, typeInfo.getComponentRawType()); + } + + public void testParameterizedArrayOfArrays() { + Type type = new TypeToken[][]>() {}.getType(); + Type secondLevelType = new TypeToken[]>() {}.getType(); + + TypeInfoArray typeInfo = new TypeInfoArray(type); + assertEquals(List[][].class, typeInfo.getRawClass()); + assertEquals(secondLevelType, typeInfo.getSecondLevelType()); + assertEquals(List.class, typeInfo.getComponentRawType()); + } + + public void testNestedParameterizedArray() { + Type type = new TypeToken>[]>() {}.getType(); + Type secondLevelType = new TypeToken>>() {}.getType(); + + TypeInfoArray typeInfo = new TypeInfoArray(type); + assertEquals(List[].class, typeInfo.getRawClass()); + assertEquals(secondLevelType, typeInfo.getSecondLevelType()); + assertEquals(List.class, typeInfo.getComponentRawType()); + } + + public void testPrimitiveArray() throws Exception { + TypeInfoArray arrayTypeInfo = new TypeInfoArray(int[].class); + + assertTrue(arrayTypeInfo.isArray()); + assertEquals(int.class, arrayTypeInfo.getSecondLevelType()); + assertFalse(arrayTypeInfo.isPrimitiveOrStringAndNotAnArray()); + } + + public void testStringArray() throws Exception { + TypeInfoArray arrayTypeInfo = new TypeInfoArray(String[].class); + + assertTrue(arrayTypeInfo.isArray()); + assertEquals(String.class, arrayTypeInfo.getSecondLevelType()); + assertEquals(String[].class, arrayTypeInfo.getRawClass()); + } + + public void testPrimitiveArrayType() throws Exception { + TypeInfoArray typeInfo = new TypeInfoArray(long[].class); + assertTrue(typeInfo.isArray()); + assertEquals(long.class, typeInfo.getSecondLevelType()); + assertEquals(long[].class, typeInfo.getRawClass()); + } + + public void testStringArrayType() throws Exception { + TypeInfoArray typeInfo = new TypeInfoArray(String[].class); + assertTrue(typeInfo.isArray()); + assertEquals(String[].class, typeInfo.getRawClass()); + assertEquals(String.class, typeInfo.getSecondLevelType()); + } + + public void testArrayAsParameterizedTypes() throws Exception { + Type type = new TypeToken[]>() {}.getType(); + Type secondLevelType = new TypeToken>() {}.getType(); + + TypeInfoArray typeInfo = new TypeInfoArray(type); + assertTrue(typeInfo.isArray()); + assertEquals(List[].class, typeInfo.getRawClass()); + assertEquals(secondLevelType, typeInfo.getSecondLevelType()); + + Type actualType = typeInfo.getActualType(); + assertEquals(type, actualType); + Type actualTypeForFirstTypeVariable = TypeUtils.getActualTypeForFirstTypeVariable(actualType); + assertEquals(String.class, actualTypeForFirstTypeVariable); + } +} diff --git a/gson/src/test/java/com/google/gson/TypeInfoFactoryTest.java b/gson/src/test/java/com/google/gson/TypeInfoFactoryTest.java new file mode 100644 index 00000000..913154b8 --- /dev/null +++ b/gson/src/test/java/com/google/gson/TypeInfoFactoryTest.java @@ -0,0 +1,252 @@ +/* + * 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.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.List; + +/** + * Small test to ensure that the TypeInfoFactory is return the object that we expect. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class TypeInfoFactoryTest extends TestCase { + + private static Type OBJ_TYPE = new TypeToken>() {}.getType(); + private ObjectWithDifferentFields obj; + + @Override + protected void setUp() throws Exception { + super.setUp(); + obj = new ObjectWithDifferentFields(); + } + + public void testSimpleField() throws Exception { + Field f = obj.getClass().getField("simpleField"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(String.class, typeInfo.getActualType()); + assertEquals(String.class, typeInfo.getRawClass()); + } + + public void testEnumField() throws Exception { + Field f = obj.getClass().getField("enumField"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertTrue(typeInfo.isEnum()); + assertEquals(ObjectWithDifferentFields.TestEnum.class, typeInfo.getActualType()); + assertEquals(ObjectWithDifferentFields.TestEnum.class, typeInfo.getRawClass()); + } + + public void testParameterizedTypeField() throws Exception { + Type listType = new TypeToken>() {}.getType(); + Field f = obj.getClass().getField("simpleParameterizedType"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testNestedParameterizedTypeField() throws Exception { + Type listType = new TypeToken>>() {}.getType(); + Field f = obj.getClass().getField("simpleNestedParameterizedType"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testGenericArrayTypeField() throws Exception { + Type listType = new TypeToken[]>() {}.getType(); + Field f = obj.getClass().getField("simpleGenericArray"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List[].class, typeInfo.getRawClass()); + } + + public void testTypeVariableField() throws Exception { + Field f = obj.getClass().getField("typeVariableObj"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(Integer.class, typeInfo.getActualType()); + assertEquals(Integer.class, typeInfo.getRawClass()); + } + + public void testTypeVariableArrayField() throws Exception { + Field f = obj.getClass().getField("typeVariableArray"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(Integer[].class, typeInfo.getActualType()); + assertEquals(Integer[].class, typeInfo.getRawClass()); + } + + public void testMutliDimensionalTypeVariableArrayField() throws Exception { + Field f = obj.getClass().getField("mutliDimensionalTypeVariableArray"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(Integer[][][].class, typeInfo.getActualType()); + assertEquals(Integer[][][].class, typeInfo.getRawClass()); + } + + public void testParameterizedTypeVariableField() throws Exception { + Type listType = new TypeToken>() {}.getType(); + Field f = obj.getClass().getField("listOfTypeVariables"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testNestedParameterizedTypeVariableField() throws Exception { + Type listType = new TypeToken>>() {}.getType(); + Field f = obj.getClass().getField("listOfListsOfTypeVariables"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testParameterizedTypeVariableArrayField() throws Exception { + Type listType = new TypeToken[]>() {}.getType(); + Field f = obj.getClass().getField("listOfTypeVariablesArray"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List[].class, typeInfo.getRawClass()); + } + + public void testWildcardField() throws Exception { + Type listType = new TypeToken>() {}.getType(); + Field f = obj.getClass().getField("listWithWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testArrayOfWildcardField() throws Exception { + Type listType = new TypeToken[]>() {}.getType(); + Field f = obj.getClass().getField("arrayOfListWithWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List[].class, typeInfo.getRawClass()); + } + + public void testListStringWildcardField() throws Exception { + Type listType = new TypeToken>() {}.getType(); + Field f = obj.getClass().getField("listWithStringWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testArrayOfListStringWildcardField() throws Exception { + Type listType = new TypeToken[]>() {}.getType(); + Field f = obj.getClass().getField("arrayOfListWithStringWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List[].class, typeInfo.getRawClass()); + } + + public void testListTypeVariableWildcardField() throws Exception { + Type listType = new TypeToken>() {}.getType(); + Field f = obj.getClass().getField("listWithTypeVariableWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List.class, typeInfo.getRawClass()); + } + + public void testArrayOfListTypeVariableWildcardField() throws Exception { + Type listType = new TypeToken[]>() {}.getType(); + Field f = obj.getClass().getField("arrayOfListWithTypeVariableWildcard"); + TypeInfo typeInfo = TypeInfoFactory.getTypeInfoForField(f, OBJ_TYPE); + + assertTrue(typeInfo.isArray()); + assertFalse(typeInfo.isEnum()); + assertEquals(listType, typeInfo.getActualType()); + assertEquals(List[].class, typeInfo.getRawClass()); + } + + private static class ObjectWithDifferentFields { + public static enum TestEnum { + TEST_1, TEST_2; + } + + public String simpleField; + public TestEnum enumField; + public List simpleParameterizedType; + public List> simpleNestedParameterizedType; + public List[] simpleGenericArray; + + public T typeVariableObj; + public T[] typeVariableArray; + public T[][][] mutliDimensionalTypeVariableArray; + public List listOfTypeVariables; + public List> listOfListsOfTypeVariables; + public List[] listOfTypeVariablesArray; + + public List listWithWildcard; + public List[] arrayOfListWithWildcard; + public List listWithStringWildcard; + public List[] arrayOfListWithStringWildcard; + + public List listWithTypeVariableWildcard; + public List[] arrayOfListWithTypeVariableWildcard; + } +} diff --git a/gson/src/test/java/com/google/gson/TypeInfoMapTest.java b/gson/src/test/java/com/google/gson/TypeInfoMapTest.java new file mode 100644 index 00000000..1da4fb42 --- /dev/null +++ b/gson/src/test/java/com/google/gson/TypeInfoMapTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Unit test for the default JSON map serialization object located in the + * {@link DefaultTypeAdapters} class. + * + * @author Joel Leitch + */ +public class TypeInfoMapTest extends TestCase { + + public void testInvalidConstruction() throws Exception { + try { + new TypeInfoMap(String.class); + fail("Must be a ParameterizedType"); + } catch (IllegalArgumentException expected) { } + } + + public void testNonMapConstruction() throws Exception { + try { + Type parameterizedMapType = new TypeToken>() {}.getType(); + new TypeInfoMap(parameterizedMapType); + fail("The raw type must be a Map"); + } catch (IllegalArgumentException expected) { } + } + + public void testBasicGetters() throws Exception { + Type parameterizedMapType = new TypeToken>() {}.getType(); + TypeInfoMap mapTypeInfo = new TypeInfoMap(parameterizedMapType); + + assertEquals(String.class, mapTypeInfo.getKeyType()); + assertEquals(Integer.class, mapTypeInfo.getValueType()); + } + + public void testMapImplementations() throws Exception { + Type parameterizedMapType = new TypeToken>() {}.getType(); + TypeInfoMap mapTypeInfo = new TypeInfoMap(parameterizedMapType); + + assertEquals(String.class, mapTypeInfo.getKeyType()); + assertEquals(Integer.class, mapTypeInfo.getValueType()); + } +} diff --git a/gson/src/test/java/com/google/gson/TypeInfoTest.java b/gson/src/test/java/com/google/gson/TypeInfoTest.java new file mode 100644 index 00000000..524bb042 --- /dev/null +++ b/gson/src/test/java/com/google/gson/TypeInfoTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.List; + +/** + * Exercising the construction of the Parameter object and ensure the + * proper types are returned. + * + * @author Joel Leitch + */ +public class TypeInfoTest extends TestCase { + + public void testPrimitive() throws Exception { + TypeInfo typeInfo = new TypeInfo(boolean.class); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isString()); + assertTrue(typeInfo.isPrimitive()); + assertEquals(boolean.class, typeInfo.getRawClass()); + assertEquals(Boolean.class, typeInfo.getWrappedClass()); + } + + public void testPrimitiveWrapper() throws Exception { + TypeInfo typeInfo = new TypeInfo(Integer.class); + + assertEquals(Integer.class, typeInfo.getRawClass()); + assertTrue(typeInfo.isPrimitive()); + assertTrue(typeInfo.isPrimitiveOrStringAndNotAnArray()); + } + + public void testString() throws Exception { + TypeInfo typeInfo = new TypeInfo(String.class); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isPrimitive()); + assertEquals(String.class, typeInfo.getRawClass()); + assertTrue(typeInfo.isPrimitiveOrStringAndNotAnArray()); + } + + public void testObject() throws Exception { + TypeInfo typeInfo = new TypeInfo(Object.class); + + assertFalse(typeInfo.isArray()); + assertFalse(typeInfo.isPrimitive()); + assertEquals(Object.class, typeInfo.getRawClass()); + assertFalse(typeInfo.isPrimitiveOrStringAndNotAnArray()); + } + + public void testPrimitiveType() throws Exception { + TypeInfo typeInfo = new TypeInfo(long.class); + assertFalse(typeInfo.isArray()); + assertEquals(long.class, typeInfo.getRawClass()); + } + + public void testObjectType() throws Exception { + TypeInfo typeInfo = new TypeInfo(String.class); + assertFalse(typeInfo.isArray()); + assertTrue(typeInfo.isString()); + assertEquals(String.class, typeInfo.getRawClass()); + } + + public void testParameterizedTypes() throws Exception { + Type type = new TypeToken>() {}.getType(); + TypeInfo typeInfo = new TypeInfo(type); + + assertFalse(typeInfo.isArray()); + assertEquals(List.class, typeInfo.getRawClass()); + assertEquals(type, typeInfo.getActualType()); + } + + public void testGenericizedGenericType() throws Exception { + Type type = new TypeToken>>() {}.getType(); + Type genericType = new TypeToken>() {}.getType(); + + TypeInfo typeInfo = new TypeInfo(type); + assertFalse(typeInfo.isArray()); + assertEquals(List.class, typeInfo.getRawClass()); + Type actualTypeForFirstTypeVariable = TypeUtils.getActualTypeForFirstTypeVariable(type); + assertEquals(genericType, actualTypeForFirstTypeVariable); + + typeInfo = new TypeInfo(genericType); + actualTypeForFirstTypeVariable = TypeUtils.getActualTypeForFirstTypeVariable(genericType); + assertEquals(String.class, actualTypeForFirstTypeVariable); + } + + public void testStrangeTypeParameters() throws Exception { + try { + new TypeInfo(new Type() {}); + fail("Should not be able to determine this unknown type"); + } catch (IllegalArgumentException expected) { + } + } +} diff --git a/gson/src/test/java/com/google/gson/TypeUtilsTest.java b/gson/src/test/java/com/google/gson/TypeUtilsTest.java new file mode 100644 index 00000000..edc7df04 --- /dev/null +++ b/gson/src/test/java/com/google/gson/TypeUtilsTest.java @@ -0,0 +1,57 @@ +/* + * 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.google.gson; + +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +/** + * Unit tests for {@link TypeUtils}. + * + * @author Inderjeet Singh + */ +public class TypeUtilsTest extends TestCase { + private static final Type MAP_TYPE = new TypeToken>() {}.getType(); + + public void testGetActualTypeForFirstTypeVariable() { + assertEquals(String.class, TypeUtils.getActualTypeForFirstTypeVariable(MAP_TYPE)); + } + + public void testIsArrayForNonArrayClasses() { + assertFalse(TypeUtils.isArray(Boolean.class)); + assertFalse(TypeUtils.isArray(MAP_TYPE)); + } + + public void testIsArrayForArrayClasses() { + assertTrue(TypeUtils.isArray(String[].class)); + assertTrue(TypeUtils.isArray(Integer[][].class)); + assertTrue(TypeUtils.isArray(Collection[].class)); + } + + public void testToRawClassForNonGenericClasses() { + assertEquals(String.class, TypeUtils.toRawClass(String.class)); + } + + public void testToRawClassForGenericClasses() { + assertEquals(Map.class, TypeUtils.toRawClass(MAP_TYPE)); + } +} diff --git a/gson/src/test/java/com/google/gson/UpperCaseNamingPolicyTest.java b/gson/src/test/java/com/google/gson/UpperCaseNamingPolicyTest.java new file mode 100644 index 00000000..2aabfd3d --- /dev/null +++ b/gson/src/test/java/com/google/gson/UpperCaseNamingPolicyTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.LowerCaseNamingPolicy; +import com.google.gson.UpperCaseNamingPolicy; + +import junit.framework.TestCase; + +/** + * Tests for the {@link LowerCaseNamingPolicy} class. + * + * @author Joel Leitch + */ +public class UpperCaseNamingPolicyTest extends TestCase { + private static final String ALL_LOWER = "abcdefg"; + private static final String ALL_UPPER = "ABCDEFG"; + private static final String MIXED = "aBcdeFg"; + + private UpperCaseNamingPolicy namingPolicy; + + @Override + protected void setUp() throws Exception { + super.setUp(); + namingPolicy = new UpperCaseNamingPolicy(); + } + + public void testAllLowerCase() throws Exception { + assertEquals(ALL_UPPER, namingPolicy.translateName(ALL_LOWER, String.class, null)); + } + + public void testAllUpperCase() throws Exception { + assertEquals(ALL_UPPER, namingPolicy.translateName(ALL_UPPER, String.class, null)); + } + + public void testMixedCase() throws Exception { + assertEquals(ALL_UPPER, namingPolicy.translateName(MIXED, String.class, null)); + } +} diff --git a/gson/src/test/java/com/google/gson/VersionExclusionStrategyTest.java b/gson/src/test/java/com/google/gson/VersionExclusionStrategyTest.java new file mode 100644 index 00000000..c626ffe0 --- /dev/null +++ b/gson/src/test/java/com/google/gson/VersionExclusionStrategyTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson; + +import com.google.gson.annotations.Since; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; + +/** + * Unit tests for the {@link VersionExclusionStrategy} class. + * + * @author Joel Leitch + */ +public class VersionExclusionStrategyTest extends TestCase { + private static final double VERSION = 5.0D; + + public void testDisallowNegativeValuesAndFailFast() throws Exception { + try { + new VersionExclusionStrategy(-1.0D); + fail("should have thrown an exception."); + } catch (IllegalArgumentException expected) { } + } + + public void testClassAndFieldAreAtSameVersion() throws Exception { + Class clazz = MockObject.class; + Field f = clazz.getField("someField"); + VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION); + + assertFalse(strategy.shouldSkipClass(clazz)); + assertFalse(strategy.shouldSkipField(f)); + } + + public void testClassAndFieldAreBehindInVersion() throws Exception { + Class clazz = MockObject.class; + Field f = clazz.getField("someField"); + VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION + 1); + + assertFalse(strategy.shouldSkipClass(clazz)); + assertFalse(strategy.shouldSkipField(f)); + } + + public void testClassAndFieldAreAheadInVersion() throws Exception { + Class clazz = MockObject.class; + Field f = clazz.getField("someField"); + VersionExclusionStrategy strategy = new VersionExclusionStrategy(VERSION - 1); + + assertTrue(strategy.shouldSkipClass(clazz)); + assertTrue(strategy.shouldSkipField(f)); + } + + @Since(VERSION) + private static class MockObject { + @Since(VERSION) + public final int someField = 0; + } +} diff --git a/gson/src/test/java/com/google/gson/common/MoreAsserts.java b/gson/src/test/java/com/google/gson/common/MoreAsserts.java new file mode 100644 index 00000000..fde51b9a --- /dev/null +++ b/gson/src/test/java/com/google/gson/common/MoreAsserts.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gson.common; + +import junit.framework.Assert; + +import java.util.Collection; + +/** + * Handy asserts that we wish were present in {@link Assert} + * so that we didn't have to write them. + * + * @author Inderjeet Singh + */ +public class MoreAsserts { + + public static void assertEquals(int[] expected, int[] target) { + if (expected == null) { + Assert.assertNull(target); + } + Assert.assertEquals(expected.length, target.length); + for (int i = 0; i < expected.length; ++i) { + Assert.assertEquals(expected[i], target[i]); + } + } + + public static void assertEquals(Integer[] expected, Integer[] target) { + if (expected == null) { + Assert.assertNull(target); + } + Assert.assertEquals(expected.length, target.length); + for (int i = 0; i < expected.length; ++i) { + Assert.assertEquals(expected[i], target[i]); + } + } + + /** + * Asserts that the specified {@code value} is not present in {@code collection} + * @param collection the collection to look into + * @param value the value that needs to be checked for presence + */ + public static void assertContains(Collection collection, T value) { + for (T entry : collection) { + if (entry.equals(value)) { + return; + } + } + Assert.fail(value + " not present in " + collection); + } +} diff --git a/gson/src/test/java/com/google/gson/common/TestTypes.java b/gson/src/test/java/com/google/gson/common/TestTypes.java new file mode 100644 index 00000000..48ba7a3c --- /dev/null +++ b/gson/src/test/java/com/google/gson/common/TestTypes.java @@ -0,0 +1,352 @@ +/* + * 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.google.gson.common; + +import com.google.gson.annotations.SerializedName; + +/** + * Types used for testing JSON serialization and deserialization + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class TestTypes { + + public static class StringWrapper { + public final String someConstantStringInstanceField; + + StringWrapper() { + this("Blah"); + } + + public StringWrapper(String value) { + someConstantStringInstanceField = value; + } + } + + public static class BagOfPrimitives { + public static final long DEFAULT_VALUE = 0; + public final long longValue; + public final int intValue; + public final boolean booleanValue; + public final String stringValue; + + public BagOfPrimitives() { + this(DEFAULT_VALUE, 0, false, ""); + } + + public BagOfPrimitives(long longValue, int intValue, boolean booleanValue, String stringValue) { + this.longValue = longValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + this.stringValue = stringValue; + } + + public int getIntValue() { + return intValue; + } + + public String getExpectedJson() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append("\"longValue\":").append(longValue).append(","); + sb.append("\"intValue\":").append(intValue).append(","); + sb.append("\"booleanValue\":").append(booleanValue).append(","); + sb.append("\"stringValue\":\"").append(stringValue).append("\""); + sb.append("}"); + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (booleanValue ? 1231 : 1237); + result = prime * result + intValue; + result = prime * result + (int) (longValue ^ (longValue >>> 32)); + result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BagOfPrimitives other = (BagOfPrimitives) obj; + if (booleanValue != other.booleanValue) + return false; + if (intValue != other.intValue) + return false; + if (longValue != other.longValue) + return false; + if (stringValue == null) { + if (other.stringValue != null) + return false; + } else if (!stringValue.equals(other.stringValue)) + return false; + return true; + } + + @Override + public String toString() { + return String.format("(longValue=%d,intValue=%d,booleanValue=%b,stringValue=%s)", + longValue, intValue, booleanValue, stringValue); + } + } + + public static class BagOfPrimitiveWrappers { + private final Long longValue; + private final Integer intValue; + private final Boolean booleanValue; + + public BagOfPrimitiveWrappers() { + this(0L, 0, false); + } + + public BagOfPrimitiveWrappers(Long longValue, Integer intValue, Boolean booleanValue) { + this.longValue = longValue; + this.intValue = intValue; + this.booleanValue = booleanValue; + } + + public String getExpectedJson() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append("\"longValue\":").append(longValue).append(","); + sb.append("\"intValue\":").append(intValue).append(","); + sb.append("\"booleanValue\":").append(booleanValue); + sb.append("}"); + return sb.toString(); + } + } + + public static class PrimitiveArray { + private final long[] longArray; + + public PrimitiveArray() { + this(new long[0]); + } + + public PrimitiveArray(long[] longArray) { + this.longArray = longArray; + } + + public String getExpectedJson() { + StringBuilder sb = new StringBuilder(); + sb.append("{\"longArray\":["); + + boolean first = true; + for (long l : longArray) { + if (!first) { + sb.append(","); + } else { + first = false; + } + sb.append(l); + } + + sb.append("]}"); + return sb.toString(); + } + } + + public static class ClassWithNoFields { + // Nothing here.. . + @Override + public boolean equals(Object other) { + return other.getClass() == ClassWithNoFields.class; + } + } + + public static class Nested { + private final BagOfPrimitives primitive1; + private final BagOfPrimitives primitive2; + + public Nested() { + this(null, null); + } + + public Nested(BagOfPrimitives primitive1, BagOfPrimitives primitive2) { + this.primitive1 = primitive1; + this.primitive2 = primitive2; + } + + public String getExpectedJson() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + appendFields(sb); + sb.append("}"); + return sb.toString(); + } + + public void appendFields(StringBuilder sb) { + if (primitive1 != null) { + sb.append("\"primitive1\":").append(primitive1.getExpectedJson()); + } + if (primitive1 != null && primitive2 != null) { + sb.append(","); + } + if (primitive2 != null) { + sb.append("\"primitive2\":").append(primitive2.getExpectedJson()); + } + } + } + + public static class ClassWithTransientFields { + public final transient long transientLongValue; + private final long[] longValue; + + public ClassWithTransientFields() { + this(0L); + } + + public ClassWithTransientFields(long value) { + longValue = new long[] { value }; + transientLongValue = value + 1; + } + + public String getExpectedJson() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append("\"longValue\":[").append(longValue[0]).append("]"); + sb.append("}"); + return sb.toString(); + } + } + + public static class ClassWithCustomTypeConverter { + private final BagOfPrimitives bag; + private final int value; + + public ClassWithCustomTypeConverter() { + this(new BagOfPrimitives(), 10); + } + + public ClassWithCustomTypeConverter(int value) { + this(new BagOfPrimitives(value, value, false, ""), value); + } + + public ClassWithCustomTypeConverter(BagOfPrimitives bag, int value) { + this.bag = bag; + this.value = value; + } + + public BagOfPrimitives getBag() { + return bag; + } + + public String getExpectedJson() { + return "{\"url\":\"" + bag.getExpectedJson() + "\",\"value\":" + value + "}"; + } + + public int getValue() { + return value; + } + } + + public static class ArrayOfObjects { + private final BagOfPrimitives[] elements; + public ArrayOfObjects() { + elements = new BagOfPrimitives[3]; + for (int i = 0; i < elements.length; ++i) { + elements[i] = new BagOfPrimitives(i, i+2, false, "i"+i); + } + } + public String getExpectedJson() { + StringBuilder sb = new StringBuilder("{\"elements\":["); + boolean first = true; + for (BagOfPrimitives element : elements) { + if (first) { + first = false; + } else { + sb.append(","); + } + sb.append(element.getExpectedJson()); + } + sb.append("]}"); + return sb.toString(); + } + } + + public static enum MyEnum { + VALUE1, VALUE2; + + public String getExpectedJson() { + return "\"" + toString() + "\""; + } + } + + public static class ClassOverridingEquals { + public ClassOverridingEquals ref; + + public String getExpectedJson() { + if (ref == null) { + return "{}"; + } + return "{\"ref\":" + ref.getExpectedJson() + "}"; + } + @Override + public boolean equals(Object obj) { + return true; + } + + @Override + public int hashCode() { + return 1; + } + } + + public static class ClassWithArray { + public final Object[] array; + public ClassWithArray() { + array = null; + } + + public ClassWithArray(Object[] array) { + this.array = array; + } + } + + public static class ClassWithObjects { + public final BagOfPrimitives bag; + public ClassWithObjects() { + this(new BagOfPrimitives()); + } + public ClassWithObjects(BagOfPrimitives bag) { + this.bag = bag; + } + } + + public static class ClassWithSerializedNameFields { + @SerializedName("fooBar") public final int f; + + public ClassWithSerializedNameFields() { + this(1); + } + public ClassWithSerializedNameFields(int f) { + this.f = f; + } + + public String getExpectedJson() { + return '{' + "\"fooBar\":" + f + '}'; + } + } +} \ No newline at end of file diff --git a/gson/src/test/java/com/google/gson/functional/ArrayTest.java b/gson/src/test/java/com/google/gson/functional/ArrayTest.java new file mode 100644 index 00000000..e25a77ab --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/ArrayTest.java @@ -0,0 +1,136 @@ +/* + * 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.google.gson.functional; + +import com.google.gson.Gson; +import com.google.gson.common.MoreAsserts; +import com.google.gson.common.TestTypes.MyEnum; +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Functional tests for Json serialization and deserialization of arrays. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class ArrayTest extends TestCase { + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new Gson(); + } + + public void testTopLevelArrayOfIntsSerialization() { + int[] target = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + assertEquals("[1,2,3,4,5,6,7,8,9]", gson.toJson(target)); + } + + public void testTopLevelArrayOfIntsDeserialization() { + int[] expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int[] actual = gson.fromJson("[1,2,3,4,5,6,7,8,9]", int[].class); + MoreAsserts.assertEquals(expected, actual); + } + + public void testEmptyArraySerialization() { + int[] target = {}; + assertEquals("[]", gson.toJson(target)); + } + + public void testEmptyArrayDeserialization() { + int[] actualObject = gson.fromJson("[]", int[].class); + assertTrue(actualObject.length == 0); + + Integer[] actualObject2 = gson.fromJson("[]", Integer[].class); + assertTrue(actualObject2.length == 0); + } + + public void testNullsInArraySerialization() { + String[] array = {"foo", null, "bar"}; + String expected = "[\"foo\",null,\"bar\"]"; + String json = gson.toJson(array); + assertEquals(expected, json); + } + + public void testNullsInArrayDeserialization() { + String json = "[\"foo\",null,\"bar\"]"; + String[] expected = {"foo", null, "bar"}; + String[] target = gson.fromJson(json, expected.getClass()); + for (int i = 0; i < expected.length; ++i) { + assertEquals(expected[i], target[i]); + } + } + + public void testArrayOfStringsSerialization() { + String[] target = {"Hello", "World"}; + assertEquals("[\"Hello\",\"World\"]", gson.toJson(target)); + } + + public void testArrayOfStringsDeserialization() { + String json = "[\"Hello\",\"World\"]"; + String[] target = gson.fromJson(json, String[].class); + assertEquals("Hello", target[0]); + assertEquals("World", target[1]); + } + + public void testTopLevelEnumInASingleElementArrayDeserialization() { + String json = "[" + MyEnum.VALUE1.getExpectedJson() + "]"; + MyEnum target = gson.fromJson(json, MyEnum.class); + assertEquals(json, "[" + target.getExpectedJson() + "]"); + } + + @SuppressWarnings("unchecked") + public void testArrayOfCollectionSerialization() throws Exception { + StringBuilder sb = new StringBuilder("["); + int arraySize = 3; + + Type typeToSerialize = new TypeToken[]>() {}.getType(); + Collection[] arrayOfCollection = new ArrayList[arraySize]; + for (int i = 0; i < arraySize; ++i) { + int startValue = (3 * i) + 1; + sb.append('[').append(startValue).append(',').append(startValue + 1).append(']'); + ArrayList tmpList = new ArrayList(); + tmpList.add(startValue); + tmpList.add(startValue + 1); + arrayOfCollection[i] = tmpList; + + if (i < arraySize - 1) { + sb.append(','); + } + } + sb.append(']'); + + String json = gson.toJson(arrayOfCollection, typeToSerialize); + assertEquals(sb.toString(), json); + } + + public void testArrayOfCollectionDeserialization() throws Exception { + String json = "[[1,2],[3,4]]"; + Type type = new TypeToken[]>() {}.getType(); + Collection[] target = gson.fromJson(json, type); + + assertEquals(2, target.length); + MoreAsserts.assertEquals(new Integer[] { 1, 2 }, target[0].toArray(new Integer[0])); + MoreAsserts.assertEquals(new Integer[] { 3, 4 }, target[1].toArray(new Integer[0])); + } +} diff --git a/gson/src/test/java/com/google/gson/functional/CollectionTest.java b/gson/src/test/java/com/google/gson/functional/CollectionTest.java new file mode 100644 index 00000000..72ace47b --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/CollectionTest.java @@ -0,0 +1,205 @@ +/* + * 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.google.gson.functional; + +import com.google.gson.Gson; +import com.google.gson.JsonParseException; +import com.google.gson.common.MoreAsserts; +import com.google.gson.common.TestTypes.BagOfPrimitives; +import com.google.gson.common.TestTypes.MyEnum; +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +/** + * Functional tests for Json serialization and deserialization of collections. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class CollectionTest extends TestCase { + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new Gson(); + } + + public void testTopLevelCollectionOfIntegersSerialization() { + Collection target = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); + Type targetType = new TypeToken>() {}.getType(); + String json = gson.toJson(target, targetType); + assertEquals("[1,2,3,4,5,6,7,8,9]", json); + } + + public void testTopLevelCollectionOfIntegersDeserialization() { + String json = "[0,1,2,3,4,5,6,7,8,9]"; + Type collectionType = new TypeToken>() { }.getType(); + Collection target = gson.fromJson(json, collectionType); + int[] expected = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + MoreAsserts.assertEquals(expected, toIntArray(target)); + } + + public void testTopLevelListOfIntegerCollectionsDeserialization() throws Exception { + String json = "[[1,2,3],[4,5,6],[7,8,9]]"; + Type collectionType = new TypeToken>>() {}.getType(); + List> target = gson.fromJson(json, collectionType); + int[][] expected = new int[3][3]; + for (int i = 0; i < 3; ++i) { + int start = (3 * i) + 1; + for (int j = 0; j < 3; ++j) { + expected[i][j] = start + j; + } + } + + for (int i = 0; i < 3; i++) { + MoreAsserts.assertEquals(expected[i], toIntArray(target.get(i))); + } + } + + public void testNullsInListSerialization() { + List list = new ArrayList(); + list.add("foo"); + list.add(null); + list.add("bar"); + String expected = "[\"foo\",null,\"bar\"]"; + Type typeOfList = new TypeToken>() {}.getType(); + String json = gson.toJson(list, typeOfList); + assertEquals(expected, json); + } + + public void testNullsInListDeserialization() { + List expected = new ArrayList(); + expected.add("foo"); + expected.add(null); + expected.add("bar"); + String json = "[\"foo\",null,\"bar\"]"; + Type expectedType = new TypeToken>() {}.getType(); + List target = gson.fromJson(json, expectedType); + for (int i = 0; i < expected.size(); ++i) { + assertEquals(expected.get(i), target.get(i)); + } + } + + public void testCollectionOfStringsSerialization() { + List target = new ArrayList(); + target.add("Hello"); + target.add("World"); + assertEquals("[\"Hello\",\"World\"]", gson.toJson(target)); + } + + public void testCollectionOfBagOfPrimitivesSerialization() { + List target = new ArrayList(); + BagOfPrimitives objA = new BagOfPrimitives(3L, 1, true, "blah"); + BagOfPrimitives objB = new BagOfPrimitives(2L, 6, false, "blahB"); + target.add(objA); + target.add(objB); + + String result = gson.toJson(target); + assertTrue(result.startsWith("[")); + assertTrue(result.endsWith("]")); + for (BagOfPrimitives obj : target) { + assertTrue(result.contains(obj.getExpectedJson())); + } + } + + public void testCollectionOfEnumsSerialization() { + Type type = new TypeToken>() {}.getType(); + Collection target = new ArrayList(); + target.add(MyEnum.VALUE1); + target.add(MyEnum.VALUE2); + String expectedJson = "[\"VALUE1\",\"VALUE2\"]"; + String actualJson = gson.toJson(target); + assertEquals(expectedJson, actualJson); + actualJson = gson.toJson(target, type); + assertEquals(expectedJson, actualJson); + } + + public void testCollectionOfEnumsDeserialization() { + Type type = new TypeToken>() {}.getType(); + String json = "[\"VALUE1\",\"VALUE2\"]"; + Collection target = gson.fromJson(json, type); + MoreAsserts.assertContains(target, MyEnum.VALUE1); + MoreAsserts.assertContains(target, MyEnum.VALUE2); + } + + public void testCollectionOfStringsDeserialization() { + String json = "[\"Hello\",\"World\"]"; + Type collectionType = new TypeToken>() { }.getType(); + Collection target = gson.fromJson(json, collectionType); + + assertTrue(target.contains("Hello")); + assertTrue(target.contains("World")); + } + + public void testRawCollectionOfIntegersSerialization() { + Collection target = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); + assertEquals("[1,2,3,4,5,6,7,8,9]", gson.toJson(target)); + } + + public void testRawCollectionDeserializationNotAlllowed() { + String json = "[0,1,2,3,4,5,6,7,8,9]"; + try { + gson.fromJson(json, Collection.class); + fail("Can not deserialize a non-genericized collection."); + } catch (JsonParseException expected) { } + + json = "[\"Hello\", \"World\"]"; + try { + gson.fromJson(json, Collection.class); + fail("Can not deserialize a non-genericized collection."); + } catch (JsonParseException expected) { } + } + + @SuppressWarnings("unchecked") + public void testRawCollectionOfBagOfPrimitivesNotAllowed() { + try { + BagOfPrimitives bag = new BagOfPrimitives(10, 20, false, "stringValue"); + String json = '[' + bag.getExpectedJson() + ',' + bag.getExpectedJson() + ']'; + Collection target = gson.fromJson(json, Collection.class); + assertEquals(2, target.size()); + for (BagOfPrimitives bag1 : (Collection) target) { + assertEquals(bag.getExpectedJson(), bag1.getExpectedJson()); + } + fail("Raw collection of objects should not work"); + } catch (JsonParseException expected) { + } + } + + @SuppressWarnings("unchecked") + private static int[] toIntArray(Collection collection) { + int[] ints = new int[collection.size()]; + int i = 0; + for (Iterator iterator = collection.iterator(); iterator.hasNext(); ++i) { + Object obj = iterator.next(); + if (obj instanceof Integer) { + ints[i] = ((Integer)obj).intValue(); + } else if (obj instanceof Long) { + ints[i] = ((Long)obj).intValue(); + } + } + return ints; + } +} diff --git a/gson/src/test/java/com/google/gson/functional/CustomTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/CustomTypeAdaptersTest.java new file mode 100644 index 00000000..e00b94e0 --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/CustomTypeAdaptersTest.java @@ -0,0 +1,106 @@ +/* + * 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.google.gson.functional; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.common.TestTypes.BagOfPrimitives; +import com.google.gson.common.TestTypes.ClassWithCustomTypeConverter; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; + +/** + * Functional tests for the support of custom serializer and deserializers. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class CustomTypeAdaptersTest extends TestCase { + private GsonBuilder builder; + + @Override + protected void setUp() throws Exception { + super.setUp(); + builder = new GsonBuilder(); + } + + public void testCustomSerializers() { + Gson gson = builder.registerTypeAdapter( + ClassWithCustomTypeConverter.class, new JsonSerializer() { + public JsonElement serialize(ClassWithCustomTypeConverter src, Type typeOfSrc, + JsonSerializationContext context) { + JsonObject json = new JsonObject(); + json.addProperty("bag", 5); + json.addProperty("value", 25); + return json; + } + }).create(); + ClassWithCustomTypeConverter target = new ClassWithCustomTypeConverter(); + assertEquals("{\"bag\":5,\"value\":25}", gson.toJson(target)); + } + + public void testCustomDeserializers() { + Gson gson = new GsonBuilder().registerTypeAdapter( + ClassWithCustomTypeConverter.class, new JsonDeserializer() { + public ClassWithCustomTypeConverter deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) { + JsonObject jsonObject = json.getAsJsonObject(); + int value = jsonObject.get("bag").getAsInt(); + return new ClassWithCustomTypeConverter(new BagOfPrimitives(value, + value, false, ""), value); + } + }).create(); + String json = "{\"bag\":5,\"value\":25}"; + ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class); + assertEquals(5, target.getBag().getIntValue()); + } + + public void testCustomNestedSerializers() { + Gson gson = new GsonBuilder().registerTypeAdapter( + BagOfPrimitives.class, new JsonSerializer() { + public JsonElement serialize(BagOfPrimitives src, Type typeOfSrc, + JsonSerializationContext context) { + return new JsonPrimitive(6); + } + }).create(); + ClassWithCustomTypeConverter target = new ClassWithCustomTypeConverter(); + assertEquals("{\"bag\":6,\"value\":10}", gson.toJson(target)); + } + + public void testCustomNestedDeserializers() { + Gson gson = new GsonBuilder().registerTypeAdapter( + BagOfPrimitives.class, new JsonDeserializer() { + public BagOfPrimitives deserialize(JsonElement json, Type typeOfT, + JsonDeserializationContext context) throws JsonParseException { + int value = json.getAsInt(); + return new BagOfPrimitives(value, value, false, ""); + } + }).create(); + String json = "{\"bag\":7,\"value\":25}"; + ClassWithCustomTypeConverter target = gson.fromJson(json, ClassWithCustomTypeConverter.class); + assertEquals(7, target.getBag().getIntValue()); + } +} diff --git a/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java new file mode 100644 index 00000000..eda4bca9 --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/DefaultTypeAdaptersTest.java @@ -0,0 +1,230 @@ +/* + * 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.google.gson.functional; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * Functional test for Json serialization and deserialization for common classes for which default + * support is provided in Gson. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class DefaultTypeAdaptersTest extends TestCase { + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new Gson(); + } + + public void testUrlSerialization() throws Exception { + String urlValue = "http://google.com/"; + URL url = new URL(urlValue); + assertEquals('"' + urlValue + '"', gson.toJson(url)); + } + + public void testUrlDeserialization() { + String urlValue = "http://google.com/"; + String json = '"' + urlValue + '"'; + URL target = gson.fromJson(json, URL.class); + assertEquals(urlValue, target.toExternalForm()); + } + + public void testUriSerialization() throws Exception { + String uriValue = "http://google.com/"; + URI uri = new URI(uriValue); + assertEquals('"' + uriValue + '"', gson.toJson(uri)); + } + + public void testUriDeserialization() { + String uriValue = "http://google.com/"; + String json = '"' + uriValue + '"'; + URI target = gson.fromJson(json, URI.class); + assertEquals(uriValue, target.toASCIIString()); + } + + public void testLocaleSerializationWithLanguage() { + Locale target = new Locale("en"); + assertEquals("\"en\"", gson.toJson(target)); + } + + public void testLocaleDeserializationWithLanguage() { + String json = "\"en\""; + Locale locale = gson.fromJson(json, Locale.class); + assertEquals("en", locale.getLanguage()); + } + + public void testLocaleSerializationWithLanguageCountry() { + Locale target = Locale.CANADA_FRENCH; + assertEquals("\"fr_CA\"", gson.toJson(target)); + } + + public void testLocaleDeserializationWithLanguageCountry() { + String json = "\"fr_CA\""; + Locale locale = gson.fromJson(json, Locale.class); + assertEquals(Locale.CANADA_FRENCH, locale); + } + + public void testLocaleSerializationWithLanguageCountryVariant() { + Locale target = new Locale("de", "DE", "EURO"); + String json = gson.toJson(target); + assertEquals("\"de_DE_EURO\"", json); + } + + public void testLocaleDeserializationWithLanguageCountryVariant() { + String json = "\"de_DE_EURO\""; + Locale locale = gson.fromJson(json, Locale.class); + assertEquals("de", locale.getLanguage()); + assertEquals("DE", locale.getCountry()); + assertEquals("EURO", locale.getVariant()); + } + + public void testMapSerialization() { + Map map = new LinkedHashMap(); + map.put("a", 1); + map.put("b", 2); + Type typeOfMap = new TypeToken>() {}.getType(); + String json = gson.toJson(map, typeOfMap); + assertTrue(json.contains("\"a\":1")); + assertTrue(json.contains("\"b\":2")); + } + + public void testMapDeserialization() { + String json = "{\"a\":1,\"b\":2}"; + Type typeOfMap = new TypeToken>(){}.getType(); + Map target = gson.fromJson(json, typeOfMap); + assertEquals(1, target.get("a").intValue()); + assertEquals(2, target.get("b").intValue()); + } + + public void testMapSerializationEmpty() { + Map map = new LinkedHashMap(); + Type typeOfMap = new TypeToken>() {}.getType(); + String json = gson.toJson(map, typeOfMap); + assertEquals("{}", json); + } + + public void testBigDecimalFieldSerialization() { + ClassWithBigDecimal target = new ClassWithBigDecimal("-122.01e-21"); + String json = gson.toJson(target); + String actual = json.substring(json.indexOf(':') + 1, json.indexOf('}')); + assertEquals(target.value, new BigDecimal(actual)); + } + + public void testBigDecimalFieldDeserialization() { + ClassWithBigDecimal expected = new ClassWithBigDecimal("-122.01e-21"); + String json = expected.getExpectedJson(); + ClassWithBigDecimal actual = gson.fromJson(json, ClassWithBigDecimal.class); + assertEquals(expected.value, actual.value); + } + + public void testBadValueForBigDecimalDeserialization() { + try { + gson.fromJson("{\"value\"=1.5e-1.0031}", ClassWithBigDecimal.class); + fail("Exponent of a BigDecimal must be an integer value."); + } catch (JsonParseException expected) { } + } + + public void testBigIntegerFieldSerialization() { + ClassWithBigInteger target = new ClassWithBigInteger("23232323215323234234324324324324324324"); + String json = gson.toJson(target); + assertEquals(target.getExpectedJson(), json); + } + + public void testBigIntegerFieldDeserialization() { + ClassWithBigInteger expected = new ClassWithBigInteger("879697697697697697697697697697697697"); + String json = expected.getExpectedJson(); + ClassWithBigInteger actual = gson.fromJson(json, ClassWithBigInteger.class); + assertEquals(expected.value, actual.value); + } + + public void testSetSerialization() throws Exception { + Gson gson = new Gson(); + HashSet s = new HashSet(); + s.add("blah"); + String json = gson.toJson(s); + assertEquals("[\"blah\"]", json); + + json = gson.toJson(s, Set.class); + assertEquals("[\"blah\"]", json); + } + + public void testDefaultDateSerialization() { + Date now = new Date(); + String json = gson.toJson(now); + assertEquals("\"" + DateFormat.getDateInstance().format(now) + "\"", json); + } + + public void testDefaultDateSerializationUsingBuilder() throws Exception { + Gson gson = new GsonBuilder().create(); + Date now = new Date(); + String json = gson.toJson(now); + assertEquals("\"" + DateFormat.getDateInstance().format(now) + "\"", json); + } + + public void testDateSerializationWithPattern() throws Exception { + String pattern = "yyyy-MM-dd"; + DateFormat formatter = new SimpleDateFormat(pattern); + Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG).setDateFormat(pattern).create(); + Date now = new Date(); + String json = gson.toJson(now); + assertEquals("\"" + formatter.format(now) + "\"", json); + } + + private static class ClassWithBigDecimal { + BigDecimal value; + ClassWithBigDecimal() { } + ClassWithBigDecimal(String value) { + this.value = new BigDecimal(value); + } + String getExpectedJson() { + return "{\"value\":" + value.toEngineeringString() + "}"; + } + } + + private static class ClassWithBigInteger { + BigInteger value; + ClassWithBigInteger() { } + ClassWithBigInteger(String value) { + this.value = new BigInteger(value); + } + String getExpectedJson() { + return "{\"value\":" + value + "}"; + } + } +} diff --git a/gson/src/test/java/com/google/gson/functional/EscapingTest.java b/gson/src/test/java/com/google/gson/functional/EscapingTest.java new file mode 100644 index 00000000..52111e2b --- /dev/null +++ b/gson/src/test/java/com/google/gson/functional/EscapingTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.functional; + +import com.google.gson.Gson; +import com.google.gson.common.TestTypes.BagOfPrimitives; + +import junit.framework.TestCase; + +public class EscapingTest extends TestCase { + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new Gson(); + } + + public void testEscapingQuotesInStringArray() throws Exception { + String[] valueWithQuotes = { "beforeQuote\"afterQuote" }; + String jsonRepresentation = gson.toJson(valueWithQuotes); + String[] target = gson.fromJson(jsonRepresentation, String[].class); + assertEquals(1, target.length); + assertEquals(valueWithQuotes[0], target[0]); + } + + public void testEscapingObjectFields() throws Exception { + BagOfPrimitives objWithPrimitives = new BagOfPrimitives(1L, 1, true, "test with\"