├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── build.yml │ ├── check-android-compatibility.yml │ ├── check-api-compatibility.yml │ ├── cifuzz.yml │ └── codeql-analysis.yml ├── .gitignore ├── .mvn └── jvm.config ├── CHANGELOG.md ├── GsonDesignDocument.md ├── LICENSE ├── README.md ├── ReleaseProcess.md ├── Troubleshooting.md ├── UserGuide.md ├── extras ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── gson │ │ ├── extras │ │ └── examples │ │ │ └── rawcollections │ │ │ └── RawCollectionsExample.java │ │ ├── graph │ │ └── GraphAdapterBuilder.java │ │ ├── interceptors │ │ ├── Intercept.java │ │ ├── InterceptorFactory.java │ │ └── JsonPostDeserializer.java │ │ └── typeadapters │ │ ├── PostConstructAdapterFactory.java │ │ ├── RuntimeTypeAdapterFactory.java │ │ └── UtcDateTypeAdapter.java │ └── test │ └── java │ └── com │ └── google │ └── gson │ ├── graph │ └── GraphAdapterBuilderTest.java │ ├── interceptors │ └── InterceptorTest.java │ └── typeadapters │ ├── PostConstructAdapterFactoryTest.java │ ├── RuntimeTypeAdapterFactoryTest.java │ └── UtcDateTypeAdapterTest.java ├── gson ├── LICENSE ├── README.md ├── pom.xml └── src │ ├── main │ ├── java-templates │ │ └── com │ │ │ └── google │ │ │ └── gson │ │ │ └── internal │ │ │ └── GsonBuildConfig.java │ ├── java │ │ ├── com │ │ │ └── google │ │ │ │ └── gson │ │ │ │ ├── ExclusionStrategy.java │ │ │ │ ├── FieldAttributes.java │ │ │ │ ├── FieldNamingPolicy.java │ │ │ │ ├── FieldNamingStrategy.java │ │ │ │ ├── FormattingStyle.java │ │ │ │ ├── Gson.java │ │ │ │ ├── GsonBuilder.java │ │ │ │ ├── InstanceCreator.java │ │ │ │ ├── JsonArray.java │ │ │ │ ├── JsonDeserializationContext.java │ │ │ │ ├── JsonDeserializer.java │ │ │ │ ├── JsonElement.java │ │ │ │ ├── JsonIOException.java │ │ │ │ ├── JsonNull.java │ │ │ │ ├── JsonObject.java │ │ │ │ ├── JsonParseException.java │ │ │ │ ├── JsonParser.java │ │ │ │ ├── JsonPrimitive.java │ │ │ │ ├── JsonSerializationContext.java │ │ │ │ ├── JsonSerializer.java │ │ │ │ ├── JsonStreamParser.java │ │ │ │ ├── JsonSyntaxException.java │ │ │ │ ├── LongSerializationPolicy.java │ │ │ │ ├── ReflectionAccessFilter.java │ │ │ │ ├── Strictness.java │ │ │ │ ├── ToNumberPolicy.java │ │ │ │ ├── ToNumberStrategy.java │ │ │ │ ├── TypeAdapter.java │ │ │ │ ├── TypeAdapterFactory.java │ │ │ │ ├── annotations │ │ │ │ ├── Expose.java │ │ │ │ ├── JsonAdapter.java │ │ │ │ ├── SerializedName.java │ │ │ │ ├── Since.java │ │ │ │ ├── Until.java │ │ │ │ └── package-info.java │ │ │ │ ├── internal │ │ │ │ ├── ConstructorConstructor.java │ │ │ │ ├── Excluder.java │ │ │ │ ├── GsonPreconditions.java │ │ │ │ ├── GsonTypes.java │ │ │ │ ├── JavaVersion.java │ │ │ │ ├── JsonReaderInternalAccess.java │ │ │ │ ├── LazilyParsedNumber.java │ │ │ │ ├── LinkedTreeMap.java │ │ │ │ ├── NonNullElementWrapperList.java │ │ │ │ ├── NumberLimits.java │ │ │ │ ├── ObjectConstructor.java │ │ │ │ ├── PreJava9DateFormatProvider.java │ │ │ │ ├── Primitives.java │ │ │ │ ├── ReflectionAccessFilterHelper.java │ │ │ │ ├── Streams.java │ │ │ │ ├── TroubleshootingGuide.java │ │ │ │ ├── UnsafeAllocator.java │ │ │ │ ├── bind │ │ │ │ │ ├── ArrayTypeAdapter.java │ │ │ │ │ ├── CollectionTypeAdapterFactory.java │ │ │ │ │ ├── DefaultDateTypeAdapter.java │ │ │ │ │ ├── EnumTypeAdapter.java │ │ │ │ │ ├── JsonAdapterAnnotationTypeAdapterFactory.java │ │ │ │ │ ├── JsonElementTypeAdapter.java │ │ │ │ │ ├── JsonTreeReader.java │ │ │ │ │ ├── JsonTreeWriter.java │ │ │ │ │ ├── MapTypeAdapterFactory.java │ │ │ │ │ ├── NumberTypeAdapter.java │ │ │ │ │ ├── ObjectTypeAdapter.java │ │ │ │ │ ├── ReflectiveTypeAdapterFactory.java │ │ │ │ │ ├── SerializationDelegatingTypeAdapter.java │ │ │ │ │ ├── TreeTypeAdapter.java │ │ │ │ │ ├── TypeAdapterRuntimeTypeWrapper.java │ │ │ │ │ ├── TypeAdapters.java │ │ │ │ │ └── util │ │ │ │ │ │ └── ISO8601Utils.java │ │ │ │ ├── package-info.java │ │ │ │ ├── reflect │ │ │ │ │ └── ReflectionHelper.java │ │ │ │ └── sql │ │ │ │ │ ├── SqlDateTypeAdapter.java │ │ │ │ │ ├── SqlTimeTypeAdapter.java │ │ │ │ │ ├── SqlTimestampTypeAdapter.java │ │ │ │ │ └── SqlTypesSupport.java │ │ │ │ ├── package-info.java │ │ │ │ ├── reflect │ │ │ │ ├── TypeToken.java │ │ │ │ └── package-info.java │ │ │ │ └── stream │ │ │ │ ├── JsonReader.java │ │ │ │ ├── JsonScope.java │ │ │ │ ├── JsonToken.java │ │ │ │ ├── JsonWriter.java │ │ │ │ ├── MalformedJsonException.java │ │ │ │ └── package-info.java │ │ └── module-info.java │ └── resources │ │ └── META-INF │ │ └── proguard │ │ └── gson.pro │ └── test │ ├── java │ └── com │ │ └── google │ │ └── gson │ │ ├── CommentsTest.java │ │ ├── DefaultInetAddressTypeAdapterTest.java │ │ ├── DefaultMapJsonSerializerTest.java │ │ ├── ExposeAnnotationExclusionStrategyTest.java │ │ ├── FieldAttributesTest.java │ │ ├── FieldNamingPolicyTest.java │ │ ├── GenericArrayTypeTest.java │ │ ├── GsonBuilderTest.java │ │ ├── GsonTest.java │ │ ├── GsonTypeAdapterTest.java │ │ ├── InnerClassExclusionStrategyTest.java │ │ ├── JavaSerializationTest.java │ │ ├── JsonArrayAsListSuiteTest.java │ │ ├── JsonArrayAsListTest.java │ │ ├── JsonArrayTest.java │ │ ├── JsonNullTest.java │ │ ├── JsonObjectAsMapSuiteTest.java │ │ ├── JsonObjectAsMapTest.java │ │ ├── JsonObjectTest.java │ │ ├── JsonParserParameterizedTest.java │ │ ├── JsonParserTest.java │ │ ├── JsonPrimitiveTest.java │ │ ├── JsonStreamParserTest.java │ │ ├── LongSerializationPolicyTest.java │ │ ├── MixedStreamTest.java │ │ ├── ObjectTypeAdapterParameterizedTest.java │ │ ├── ObjectTypeAdapterTest.java │ │ ├── OverrideCoreTypeAdaptersTest.java │ │ ├── ParameterizedTypeFixtures.java │ │ ├── ParameterizedTypeTest.java │ │ ├── PrimitiveTypeAdapter.java │ │ ├── ToNumberPolicyTest.java │ │ ├── TypeAdapterTest.java │ │ ├── VersionExclusionStrategyTest.java │ │ ├── common │ │ ├── MoreAsserts.java │ │ └── TestTypes.java │ │ ├── functional │ │ ├── ArrayTest.java │ │ ├── CircularReferenceTest.java │ │ ├── CollectionTest.java │ │ ├── ConcurrencyTest.java │ │ ├── CustomDeserializerTest.java │ │ ├── CustomSerializerTest.java │ │ ├── CustomTypeAdaptersTest.java │ │ ├── DefaultTypeAdaptersTest.java │ │ ├── DelegateTypeAdapterTest.java │ │ ├── EnumTest.java │ │ ├── EnumWithObfuscatedTest.java │ │ ├── EscapingTest.java │ │ ├── ExclusionStrategyFunctionalTest.java │ │ ├── ExposeFieldsTest.java │ │ ├── FieldExclusionTest.java │ │ ├── FieldNamingTest.java │ │ ├── FormattingStyleTest.java │ │ ├── GsonVersionDiagnosticsTest.java │ │ ├── InheritanceTest.java │ │ ├── InstanceCreatorTest.java │ │ ├── InterfaceTest.java │ │ ├── InternationalizationTest.java │ │ ├── Java17RecordTest.java │ │ ├── JavaUtilConcurrentAtomicTest.java │ │ ├── JavaUtilTest.java │ │ ├── JsonAdapterAnnotationOnClassesTest.java │ │ ├── JsonAdapterAnnotationOnFieldsTest.java │ │ ├── JsonAdapterSerializerDeserializerTest.java │ │ ├── JsonParserTest.java │ │ ├── JsonTreeTest.java │ │ ├── LeniencyTest.java │ │ ├── MapAsArrayTypeAdapterTest.java │ │ ├── MapTest.java │ │ ├── MoreSpecificTypeSerializationTest.java │ │ ├── NamingPolicyTest.java │ │ ├── NullObjectAndFieldTest.java │ │ ├── NumberLimitsTest.java │ │ ├── ObjectTest.java │ │ ├── ParameterizedTypesTest.java │ │ ├── PrettyPrintingTest.java │ │ ├── PrimitiveCharacterTest.java │ │ ├── PrimitiveTest.java │ │ ├── PrintFormattingTest.java │ │ ├── RawSerializationTest.java │ │ ├── ReadersWritersTest.java │ │ ├── ReflectionAccessFilterTest.java │ │ ├── ReflectionAccessTest.java │ │ ├── ReusedTypeVariablesFullyResolveTest.java │ │ ├── RuntimeTypeAdapterFactoryFunctionalTest.java │ │ ├── SecurityTest.java │ │ ├── SerializedNameTest.java │ │ ├── StreamingTypeAdaptersTest.java │ │ ├── StringTest.java │ │ ├── ToNumberPolicyFunctionalTest.java │ │ ├── TreeTypeAdaptersTest.java │ │ ├── TypeAdapterPrecedenceTest.java │ │ ├── TypeAdapterRuntimeTypeWrapperTest.java │ │ ├── TypeHierarchyAdapterTest.java │ │ ├── TypeVariableTest.java │ │ ├── UncategorizedTest.java │ │ └── VersioningTest.java │ │ ├── integration │ │ └── OSGiManifestIT.java │ │ ├── internal │ │ ├── ConstructorConstructorTest.java │ │ ├── GsonBuildConfigTest.java │ │ ├── GsonTypesTest.java │ │ ├── JavaVersionTest.java │ │ ├── LazilyParsedNumberTest.java │ │ ├── LinkedTreeMapSuiteTest.java │ │ ├── LinkedTreeMapTest.java │ │ ├── StreamsTest.java │ │ ├── UnsafeAllocatorInstantiationTest.java │ │ ├── bind │ │ │ ├── DefaultDateTypeAdapterTest.java │ │ │ ├── Java17ReflectiveTypeAdapterFactoryTest.java │ │ │ ├── JsonElementReaderTest.java │ │ │ ├── JsonTreeReaderTest.java │ │ │ ├── JsonTreeWriterTest.java │ │ │ ├── RecursiveTypesResolveTest.java │ │ │ └── util │ │ │ │ └── ISO8601UtilsTest.java │ │ ├── reflect │ │ │ └── Java17ReflectionHelperTest.java │ │ └── sql │ │ │ ├── SqlTypesGsonTest.java │ │ │ └── SqlTypesSupportTest.java │ │ ├── metrics │ │ └── PerformanceTest.java │ │ ├── reflect │ │ └── TypeTokenTest.java │ │ └── stream │ │ ├── JsonReaderPathTest.java │ │ ├── JsonReaderTest.java │ │ └── JsonWriterTest.java │ └── resources │ └── testcases-proguard.conf ├── metrics ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── google │ │ └── gson │ │ └── metrics │ │ ├── BagOfPrimitives.java │ │ ├── BagOfPrimitivesDeserializationBenchmark.java │ │ ├── CollectionsDeserializationBenchmark.java │ │ ├── NonUploadingCaliperRunner.java │ │ ├── ParseBenchmark.java │ │ └── SerializationBenchmark.java │ └── resources │ └── ParseBenchmarkData.zip ├── pom.xml ├── proto ├── .gitignore ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── gson │ │ └── protobuf │ │ └── ProtoTypeAdapter.java │ └── test │ ├── java │ └── com │ │ └── google │ │ └── gson │ │ └── protobuf │ │ └── functional │ │ ├── ProtosWithAnnotationsAndJsonNamesTest.java │ │ ├── ProtosWithAnnotationsTest.java │ │ ├── ProtosWithComplexAndRepeatedFieldsTest.java │ │ └── ProtosWithPrimitiveTypesTest.java │ └── proto │ ├── annotations.proto │ └── bag.proto ├── test-graal-native-image ├── README.md ├── pom.xml └── src │ └── test │ ├── java │ └── com │ │ └── google │ │ └── gson │ │ └── native_test │ │ ├── Java17RecordReflectionTest.java │ │ └── ReflectionTest.java │ └── resources │ └── META-INF │ └── native-image │ └── reflect-config.json ├── test-jpms ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── module-info.java │ └── test │ └── java │ ├── com │ └── google │ │ └── gson │ │ └── jpms_test │ │ ├── ExportedPackagesTest.java │ │ ├── ModuleTest.java │ │ ├── ReflectionInaccessibleTest.java │ │ └── opened │ │ └── ReflectionTest.java │ └── module-info.java └── test-shrinker ├── README.md ├── common.pro ├── pom.xml ├── proguard.pro ├── r8.pro └── src ├── main └── java │ └── com │ └── example │ ├── ClassWithAdapter.java │ ├── ClassWithExposeAnnotation.java │ ├── ClassWithHasArgsConstructor.java │ ├── ClassWithJsonAdapterAnnotation.java │ ├── ClassWithNamedFields.java │ ├── ClassWithNoArgsConstructor.java │ ├── ClassWithSerializedName.java │ ├── ClassWithUnreferencedHasArgsConstructor.java │ ├── ClassWithUnreferencedNoArgsConstructor.java │ ├── ClassWithVersionAnnotations.java │ ├── EnumClass.java │ ├── EnumClassWithSerializedName.java │ ├── GenericClasses.java │ ├── InterfaceWithImplementation.java │ ├── Main.java │ ├── NoSerializedNameMain.java │ ├── TestExecutor.java │ └── UnusedClass.java └── test └── java └── com └── google └── gson └── it └── ShrinkingIT.java /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Ignore commit which reformatted code 2 | 2c94c757a6a9426cc2fe47bc1c63f69e7c73b7b4 3 | 4 | # Ignore commit which changed line endings consistently to LF 5 | c2a0e4634a2100494159add78db2ee06f5eb9be6 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a Gson bug. Please have a look at the troubleshooting guide (Troubleshooting.md) first. 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Gson version 11 | 12 | 13 | 14 | # Java / Android version 15 | 16 | 17 | 18 | # Used tools 19 | 20 | - [ ] Maven; version: 21 | - [ ] Gradle; version: 22 | - [ ] ProGuard (attach the configuration file please); version: 23 | - [ ] ... 24 | 25 | # Description 26 | 27 | 28 | 29 | ## Expected behavior 30 | 31 | 32 | 33 | ## Actual behavior 34 | 35 | 36 | 37 | # Reproduction steps 38 | 39 | 40 | 41 | 1. ... 42 | 2. ... 43 | 44 | # Exception stack trace 45 | 46 | 47 | ``` 48 | 49 | ``` 50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Usage question 3 | url: https://stackoverflow.com/questions/tagged/gson 4 | about: Ask usage questions on StackOverflow. 5 | - name: Questions, ideas, tips & tricks, ... 6 | url: https://github.com/google/gson/discussions 7 | about: Share information in GitHub Discussions. 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Request a feature. ⚠️ Gson is in maintenance mode; large feature requests might be rejected. 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Problem solved by the feature 11 | 12 | 13 | 14 | # Feature description 15 | 16 | 17 | 18 | # Alternatives / workarounds 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | groups: 8 | # Name is used for branch name and pull request title 9 | maven: 10 | patterns: 11 | # Create a single pull request for all dependencies and plugins 12 | - "*" 13 | 14 | - package-ecosystem: "github-actions" 15 | directory: "/" 16 | schedule: 17 | interval: "monthly" 18 | groups: 19 | # Name is used for branch name and pull request title 20 | github-actions: 21 | patterns: 22 | # Create a single pull request for all actions 23 | - "*" 24 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ### Purpose 9 | 10 | 11 | 12 | 13 | ### Description 14 | 15 | 16 | 17 | 18 | 19 | ### Checklist 20 | 21 | 22 | - [ ] New code follows the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)\ 23 | This is automatically checked by `mvn verify`, but can also be checked on its own using `mvn spotless:check`.\ 24 | Style violations can be fixed using `mvn spotless:apply`; this can be done in a separate commit to verify that it did not cause undesired changes. 25 | - [ ] If necessary, new public API validates arguments, for example rejects `null` 26 | - [ ] New public API has Javadoc 27 | - [ ] Javadoc uses `@since $next-version$` 28 | (`$next-version$` is a special placeholder which is automatically replaced during release) 29 | - [ ] If necessary, new unit tests have been added 30 | - [ ] Assertions in unit tests use [Truth](https://truth.dev/), see existing tests 31 | - [ ] No JUnit 3 features are used (such as extending class `TestCase`) 32 | - [ ] If this pull request fixes a bug, a new test was added for a situation which failed previously and is now fixed 33 | - [ ] `mvn clean verify javadoc:jar` passes without errors 34 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | # Ignore Dependabot branches because it will also open a pull request, which would cause the 7 | # workflow to redundantly run twice 8 | - dependabot/** 9 | pull_request: 10 | 11 | permissions: 12 | contents: read # to fetch code (actions/checkout) 13 | 14 | jobs: 15 | build: 16 | name: "Build on JDK ${{ matrix.java }}" 17 | strategy: 18 | matrix: 19 | java: [ 11, 17, 21 ] 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 24 | - name: "Set up JDK ${{ matrix.java }}" 25 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 26 | with: 27 | distribution: 'temurin' 28 | java-version: ${{ matrix.java }} 29 | cache: 'maven' 30 | - name: Build with Maven 31 | # This also runs javadoc:jar to detect any issues with the Javadoc generated during release 32 | run: mvn --batch-mode --no-transfer-progress verify javadoc:jar 33 | 34 | native-image-test: 35 | name: "GraalVM Native Image test" 36 | runs-on: ubuntu-latest 37 | 38 | steps: 39 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 40 | - name: "Set up GraalVM" 41 | uses: graalvm/setup-graalvm@01ed653ac833fe80569f1ef9f25585ba2811baab # v1.3.3 42 | with: 43 | java-version: '21' 44 | distribution: 'graalvm' 45 | # According to documentation in graalvm/setup-graalvm this is used to avoid rate-limiting issues 46 | github-token: ${{ secrets.GITHUB_TOKEN }} 47 | cache: 'maven' 48 | - name: Build and run tests 49 | # Only run tests in `test-graal-native-image` (and implicitly build and run tests in `gson`), 50 | # everything else is covered already by regular build job above 51 | run: mvn test --batch-mode --no-transfer-progress --activate-profiles native-image-test --projects test-graal-native-image --also-make 52 | 53 | verify-reproducible-build: 54 | name: "Verify reproducible build" 55 | runs-on: ubuntu-latest 56 | 57 | steps: 58 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 59 | - name: "Set up JDK 17" 60 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 61 | with: 62 | distribution: 'temurin' 63 | java-version: 17 64 | cache: 'maven' 65 | 66 | - name: "Verify no plugin issues" 67 | run: mvn artifact:check-buildplan --batch-mode --no-transfer-progress 68 | 69 | - name: "Verify reproducible build" 70 | # See https://maven.apache.org/guides/mini/guide-reproducible-builds.html#how-to-test-my-maven-build-reproducibility 71 | run: | 72 | mvn clean install --batch-mode --no-transfer-progress -Dproguard.skip -DskipTests 73 | # Run with `-Dbuildinfo.attach=false`; otherwise `artifact:compare` fails because it creates a `.buildinfo` file which 74 | # erroneously references the existing `.buildinfo` file (respectively because it is overwriting it, a file with size 0) 75 | # See https://issues.apache.org/jira/browse/MARTIFACT-57 76 | mvn clean verify artifact:compare --batch-mode --no-transfer-progress -Dproguard.skip -DskipTests -Dbuildinfo.attach=false 77 | -------------------------------------------------------------------------------- /.github/workflows/check-android-compatibility.yml: -------------------------------------------------------------------------------- 1 | # For security reasons this is a separate GitHub workflow, see https://github.com/google/gson/issues/2429#issuecomment-1622522842 2 | # Once https://github.com/mojohaus/animal-sniffer/issues/252 or https://github.com/mojohaus/animal-sniffer/pull/253 3 | # are resolved, can consider adjusting pom.xml to include this as part of normal Maven build 4 | 5 | name: Check Android compatibility 6 | 7 | on: 8 | push: 9 | branches-ignore: 10 | # Ignore Dependabot branches because it will also open a pull request, which would cause the 11 | # workflow to redundantly run twice 12 | - dependabot/** 13 | pull_request: 14 | 15 | permissions: 16 | contents: read # to fetch code (actions/checkout) 17 | 18 | jobs: 19 | check-android-compatibility: 20 | runs-on: ubuntu-latest 21 | 22 | steps: 23 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 24 | 25 | - name: Set up JDK 11 26 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 27 | with: 28 | distribution: 'temurin' 29 | java-version: '11' 30 | cache: 'maven' 31 | 32 | - name: Check Android compatibility 33 | run: | 34 | # Run 'test' phase because plugin normally expects to be executed after tests have been compiled 35 | # Have to skip 'test-jpms' module because it requires that full Gson JAR has been built 36 | mvn --batch-mode --no-transfer-progress test animal-sniffer:check@check-android-compatibility -DskipTests --projects '!test-jpms' 37 | -------------------------------------------------------------------------------- /.github/workflows/check-api-compatibility.yml: -------------------------------------------------------------------------------- 1 | # This workflow makes sure that a pull request does not make any incompatible changes 2 | # to the public API of Gson 3 | name: Check API compatibility 4 | 5 | on: pull_request 6 | 7 | jobs: 8 | check-api-compatibility: 9 | runs-on: ubuntu-latest 10 | 11 | # This setup tries to determine API incompatibility only for the changes introduced by the 12 | # pull request. It does this by first checking out the 'old' version and installing it into 13 | # the local Maven repository before then using japicmp to compare it to the current changes. 14 | # 15 | # Alternatively it would also be possible to compare against the last release version instead. 16 | # 17 | # Both approaches have their advantages and disadvantages, see description of 18 | # https://github.com/google/gson/pull/2692 for details. 19 | 20 | steps: 21 | - name: Check out old version 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | with: 24 | ref: ${{ github.event.pull_request.base.sha }} 25 | path: 'gson-old-japicmp' 26 | 27 | - name: Set up JDK 11 28 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 29 | with: 30 | distribution: 'temurin' 31 | java-version: '11' 32 | cache: 'maven' 33 | 34 | - name: Build old version 35 | run: | 36 | cd gson-old-japicmp 37 | # Set dummy version 38 | mvn --batch-mode --no-transfer-progress org.codehaus.mojo:versions-maven-plugin:2.16.2:set "-DnewVersion=0.0.0-JAPICMP-OLD" 39 | # Install artifacts with dummy version in local repository; used later by Maven plugin for comparison 40 | mvn --batch-mode --no-transfer-progress install -DskipTests 41 | 42 | - name: Check out new version 43 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 44 | 45 | - name: Check API compatibility 46 | id: check-compatibility 47 | run: | 48 | mvn --batch-mode --fail-at-end --no-transfer-progress package japicmp:cmp -DskipTests 49 | 50 | - name: Upload API differences artifacts 51 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 52 | # Run on workflow success (in that case differences report might include added methods and classes) 53 | # or when API compatibility check failed 54 | if: success() || ( failure() && steps.check-compatibility.outcome == 'failure' ) 55 | with: 56 | name: api-differences 57 | path: | 58 | **/japicmp/default-cli.html 59 | **/japicmp/default-cli.diff 60 | # Plugin should always have created report files (though they might be empty) 61 | if-no-files-found: error 62 | -------------------------------------------------------------------------------- /.github/workflows/cifuzz.yml: -------------------------------------------------------------------------------- 1 | name: CIFuzz 2 | on: [pull_request] 3 | jobs: 4 | Fuzzing: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Build Fuzzers 8 | id: build 9 | uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master 10 | with: 11 | oss-fuzz-project-name: 'gson' 12 | dry-run: false 13 | language: jvm 14 | - name: Run Fuzzers 15 | uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master 16 | with: 17 | oss-fuzz-project-name: 'gson' 18 | fuzz-seconds: 600 19 | dry-run: false 20 | - name: Upload Crash 21 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 22 | if: failure() && steps.build.outcome == 'success' 23 | with: 24 | name: artifacts 25 | path: ./out/artifacts 26 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # Based on default config generated by GitHub, see also https://github.com/github/codeql-action 2 | 3 | name: "CodeQL" 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | branches: [ main ] 10 | schedule: 11 | # Run every Monday at 16:10 12 | - cron: '10 16 * * 1' 13 | 14 | jobs: 15 | analyze: 16 | name: Analyze 17 | runs-on: ubuntu-latest 18 | permissions: 19 | security-events: write 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | language: [ 'java' ] 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 29 | 30 | - name: Set up JDK 17 31 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 32 | with: 33 | distribution: 'temurin' 34 | java-version: '17' 35 | cache: 'maven' 36 | 37 | # Initializes the CodeQL tools for scanning 38 | - name: Initialize CodeQL 39 | uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 40 | with: 41 | languages: ${{ matrix.language }} 42 | # Run all security queries and maintainability and reliability queries 43 | queries: +security-and-quality 44 | 45 | # Only compile main sources, but ignore test sources because findings for them might not 46 | # be that relevant (though GitHub security view also allows filtering by source type) 47 | # Can replace this with github/codeql-action/autobuild action to run complete build 48 | - name: Compile sources 49 | run: | 50 | mvn compile --batch-mode --no-transfer-progress 51 | 52 | - name: Perform CodeQL Analysis 53 | uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .project 3 | .settings 4 | eclipsebin 5 | target 6 | */target 7 | pom.xml.* 8 | release.properties 9 | 10 | .idea 11 | *.iml 12 | *.ipr 13 | *.iws 14 | classes 15 | 16 | .gradle 17 | local.properties 18 | build 19 | 20 | .DS_Store 21 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED 2 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED 3 | --add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED 4 | --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED 5 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED 6 | --add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED 7 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED 8 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED 9 | --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED 10 | --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED 11 | -------------------------------------------------------------------------------- /extras/README.md: -------------------------------------------------------------------------------- 1 | # extras 2 | 3 | This Maven module contains the source code for supplementary Gson features which 4 | are not included by default. 5 | 6 | The artifacts created by this module are currently not deployed to Maven Central. 7 | -------------------------------------------------------------------------------- /extras/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | com.google.code.gson 21 | gson-parent 22 | 2.13.2-SNAPSHOT 23 | 24 | 25 | gson-extras 26 | 2.13.2-SNAPSHOT 27 | 2008 28 | Gson Extras 29 | Google Gson grab bag of utilities, type adapters, etc. 30 | 31 | 32 | 33 | 34 | 2025-04-24T01:03:45Z 35 | 36 | 37 | true 38 | 39 | 40 | 41 | 42 | Apache-2.0 43 | https://www.apache.org/licenses/LICENSE-2.0.txt 44 | 45 | 46 | 47 | 48 | Google, Inc. 49 | https://www.google.com 50 | 51 | 52 | 53 | 54 | com.google.code.gson 55 | gson 56 | 2.13.2-SNAPSHOT 57 | 58 | 59 | javax.annotation 60 | jsr250-api 61 | 1.0 62 | 63 | 64 | 65 | junit 66 | junit 67 | test 68 | 69 | 70 | com.google.truth 71 | truth 72 | test 73 | 74 | 75 | 76 | 77 | 78 | Inderjeet Singh 79 | 80 | 81 | Joel Leitch 82 | Google Inc. 83 | 84 | 85 | Jesse Wilson 86 | Square Inc. 87 | 88 | 89 | 90 | 91 | gson-extras-2.12.1 92 | 93 | 94 | -------------------------------------------------------------------------------- /extras/src/main/java/com/google/gson/extras/examples/rawcollections/RawCollectionsExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.gson.extras.examples.rawcollections; 17 | 18 | import com.google.gson.Gson; 19 | import com.google.gson.JsonArray; 20 | import com.google.gson.JsonParser; 21 | import java.util.ArrayList; 22 | import java.util.Collection; 23 | 24 | @SuppressWarnings({"PrivateConstructorForUtilityClass", "SystemOut"}) 25 | public class RawCollectionsExample { 26 | static class Event { 27 | private String name; 28 | private String source; 29 | 30 | private Event(String name, String source) { 31 | this.name = name; 32 | this.source = source; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return String.format("(name=%s, source=%s)", name, source); 38 | } 39 | } 40 | 41 | @SuppressWarnings({"unchecked", "rawtypes"}) 42 | public static void main(String[] args) { 43 | Gson gson = new Gson(); 44 | Collection collection = new ArrayList(); 45 | collection.add("hello"); 46 | collection.add(5); 47 | collection.add(new Event("GREETINGS", "guest")); 48 | String json = gson.toJson(collection); 49 | System.out.println("Using Gson.toJson() on a raw collection: " + json); 50 | JsonArray array = JsonParser.parseString(json).getAsJsonArray(); 51 | String message = gson.fromJson(array.get(0), String.class); 52 | int number = gson.fromJson(array.get(1), int.class); 53 | Event event = gson.fromJson(array.get(2), Event.class); 54 | System.out.printf("Using Gson.fromJson() to get: %s, %d, %s", message, number, event); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /extras/src/main/java/com/google/gson/interceptors/Intercept.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.interceptors; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Use this annotation to indicate various interceptors for class instances after they have been 26 | * processed by Gson. For example, you can use it to validate an instance after it has been 27 | * deserialized from Json. Here is an example of how this annotation is used: 28 | * 29 | *

Here is an example of how this annotation is used: 30 | * 31 | *

32 |  * @Intercept(postDeserialize=UserValidator.class)
33 |  * public class User {
34 |  *   String name;
35 |  *   String password;
36 |  *   String emailAddress;
37 |  * }
38 |  *
39 |  * public class UserValidator implements JsonPostDeserializer<User> {
40 |  *   public void postDeserialize(User user) {
41 |  *     // Do some checks on user
42 |  *     if (user.name == null || user.password == null) {
43 |  *       throw new JsonParseException("name and password are required fields.");
44 |  *     }
45 |  *     if (user.emailAddress == null) {
46 |  *       emailAddress = "unknown"; // assign a default value.
47 |  *     }
48 |  *   }
49 |  * }
50 |  * 
51 | * 52 | * @author Inderjeet Singh 53 | */ 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | public @interface Intercept { 57 | 58 | /** 59 | * Specify the class that provides the methods that should be invoked after an instance has been 60 | * deserialized. 61 | */ 62 | @SuppressWarnings("rawtypes") 63 | public Class postDeserialize(); 64 | } 65 | -------------------------------------------------------------------------------- /extras/src/main/java/com/google/gson/interceptors/InterceptorFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.interceptors; 18 | 19 | import com.google.gson.Gson; 20 | import com.google.gson.TypeAdapter; 21 | import com.google.gson.TypeAdapterFactory; 22 | import com.google.gson.reflect.TypeToken; 23 | import com.google.gson.stream.JsonReader; 24 | import com.google.gson.stream.JsonWriter; 25 | import java.io.IOException; 26 | 27 | /** A type adapter factory that implements {@code @Intercept}. */ 28 | public final class InterceptorFactory implements TypeAdapterFactory { 29 | @Override 30 | public TypeAdapter create(Gson gson, TypeToken type) { 31 | Intercept intercept = type.getRawType().getAnnotation(Intercept.class); 32 | if (intercept == null) { 33 | return null; 34 | } 35 | 36 | TypeAdapter delegate = gson.getDelegateAdapter(this, type); 37 | return new InterceptorAdapter<>(delegate, intercept); 38 | } 39 | 40 | static class InterceptorAdapter extends TypeAdapter { 41 | private final TypeAdapter delegate; 42 | private final JsonPostDeserializer postDeserializer; 43 | 44 | @SuppressWarnings("unchecked") // ? 45 | public InterceptorAdapter(TypeAdapter delegate, Intercept intercept) { 46 | try { 47 | this.delegate = delegate; 48 | this.postDeserializer = intercept.postDeserialize().getDeclaredConstructor().newInstance(); 49 | } catch (Exception e) { 50 | throw new RuntimeException(e); 51 | } 52 | } 53 | 54 | @Override 55 | public void write(JsonWriter out, T value) throws IOException { 56 | delegate.write(out, value); 57 | } 58 | 59 | @Override 60 | public T read(JsonReader in) throws IOException { 61 | T result = delegate.read(in); 62 | postDeserializer.postDeserialize(result); 63 | return result; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /extras/src/main/java/com/google/gson/interceptors/JsonPostDeserializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.gson.interceptors; 17 | 18 | import com.google.gson.InstanceCreator; 19 | 20 | /** 21 | * This interface is implemented by a class that wishes to inspect or modify an object after it has 22 | * been deserialized. You must define a no-args constructor or register an {@link InstanceCreator} 23 | * for such a class. 24 | * 25 | * @author Inderjeet Singh 26 | */ 27 | public interface JsonPostDeserializer { 28 | 29 | /** This method is called by Gson after the object has been deserialized from Json. */ 30 | public void postDeserialize(T object); 31 | } 32 | -------------------------------------------------------------------------------- /extras/src/main/java/com/google/gson/typeadapters/PostConstructAdapterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Gson Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.typeadapters; 18 | 19 | import com.google.gson.Gson; 20 | import com.google.gson.TypeAdapter; 21 | import com.google.gson.TypeAdapterFactory; 22 | import com.google.gson.reflect.TypeToken; 23 | import com.google.gson.stream.JsonReader; 24 | import com.google.gson.stream.JsonWriter; 25 | import java.io.IOException; 26 | import java.lang.reflect.InvocationTargetException; 27 | import java.lang.reflect.Method; 28 | import javax.annotation.PostConstruct; 29 | 30 | public class PostConstructAdapterFactory implements TypeAdapterFactory { 31 | // copied from https://gist.github.com/swankjesse/20df26adaf639ed7fd160f145a0b661a 32 | @Override 33 | public TypeAdapter create(Gson gson, TypeToken type) { 34 | for (Class t = type.getRawType(); 35 | (t != Object.class) && (t.getSuperclass() != null); 36 | t = t.getSuperclass()) { 37 | for (Method m : t.getDeclaredMethods()) { 38 | if (m.isAnnotationPresent(PostConstruct.class)) { 39 | m.setAccessible(true); 40 | TypeAdapter delegate = gson.getDelegateAdapter(this, type); 41 | return new PostConstructAdapter<>(delegate, m); 42 | } 43 | } 44 | } 45 | return null; 46 | } 47 | 48 | static final class PostConstructAdapter extends TypeAdapter { 49 | private final TypeAdapter delegate; 50 | private final Method method; 51 | 52 | public PostConstructAdapter(TypeAdapter delegate, Method method) { 53 | this.delegate = delegate; 54 | this.method = method; 55 | } 56 | 57 | @Override 58 | public T read(JsonReader in) throws IOException { 59 | T result = delegate.read(in); 60 | if (result != null) { 61 | try { 62 | method.invoke(result); 63 | } catch (IllegalAccessException e) { 64 | throw new AssertionError(e); 65 | } catch (InvocationTargetException e) { 66 | if (e.getCause() instanceof RuntimeException) { 67 | throw (RuntimeException) e.getCause(); 68 | } 69 | throw new RuntimeException(e.getCause()); 70 | } 71 | } 72 | return result; 73 | } 74 | 75 | @Override 76 | public void write(JsonWriter out, T value) throws IOException { 77 | delegate.write(out, value); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /gson/README.md: -------------------------------------------------------------------------------- 1 | # gson 2 | 3 | This Maven module contains the Gson source code. The artifacts created by this module 4 | are deployed to Maven Central under the coordinates `com.google.code.gson:gson`. 5 | -------------------------------------------------------------------------------- /gson/src/main/java-templates/com/google/gson/internal/GsonBuildConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Gson authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal; 18 | 19 | /** 20 | * Build configuration for Gson. This file is automatically populated by templating-maven-plugin and 21 | * .java/.class files are generated for use in Gson. 22 | * 23 | * @author Inderjeet Singh 24 | */ 25 | public final class GsonBuildConfig { 26 | // Based on https://stackoverflow.com/questions/2469922/generate-a-version-java-file-in-maven 27 | 28 | /** This field is automatically populated by Maven when a build is triggered */ 29 | public static final String VERSION = "${project.version}"; 30 | 31 | private GsonBuildConfig() {} 32 | } 33 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/FieldNamingStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | import com.google.gson.annotations.SerializedName; 20 | import java.lang.reflect.Field; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | /** 25 | * A mechanism for providing custom field naming in Gson. This allows the client code to translate 26 | * field names into a particular convention that is not supported as a normal Java field declaration 27 | * rules. For example, Java does not support "-" characters in a field name. 28 | * 29 | * @author Inderjeet Singh 30 | * @author Joel Leitch 31 | * @since 1.3 32 | */ 33 | public interface FieldNamingStrategy { 34 | 35 | /** 36 | * Translates the field name into its JSON field name representation. 37 | * 38 | * @param f the field object that we are translating 39 | * @return the translated field name. 40 | * @since 1.3 41 | */ 42 | public String translateName(Field f); 43 | 44 | /** 45 | * Returns alternative names for this field when it is being deserialized. This is similar to 46 | * {@link SerializedName#alternate()}. 47 | * 48 | * @param f the field object 49 | * @return the list of alternative field names. 50 | * @since 2.13.1 51 | */ 52 | default List alternateNames(Field f) { 53 | return Collections.emptyList(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonDeserializationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | /** 22 | * Context for deserialization that is passed to a custom deserializer during invocation of its 23 | * {@link JsonDeserializer#deserialize(JsonElement, Type, JsonDeserializationContext)} method. 24 | * 25 | * @author Inderjeet Singh 26 | * @author Joel Leitch 27 | */ 28 | public interface JsonDeserializationContext { 29 | 30 | /** 31 | * Invokes default deserialization on the specified object. It should never be invoked on the 32 | * element received as a parameter of the {@link JsonDeserializer#deserialize(JsonElement, Type, 33 | * JsonDeserializationContext)} method. Doing so will result in an infinite loop since Gson will 34 | * in-turn call the custom deserializer again. 35 | * 36 | * @param json the parse tree. 37 | * @param typeOfT type of the expected return value. 38 | * @param The type of the deserialized object. 39 | * @return An object of type typeOfT. 40 | * @throws JsonParseException if the parse tree does not contain expected data. 41 | */ 42 | @SuppressWarnings("TypeParameterUnusedInFormals") 43 | public T deserialize(JsonElement json, Type typeOfT) throws JsonParseException; 44 | } 45 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonIOException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.gson; 17 | 18 | /** 19 | * This exception is raised when Gson was unable to read an input stream or write to one. 20 | * 21 | * @author Inderjeet Singh 22 | * @author Joel Leitch 23 | */ 24 | @SuppressWarnings("MemberName") // class name is part of the public API 25 | public final class JsonIOException extends JsonParseException { 26 | private static final long serialVersionUID = 1L; 27 | 28 | public JsonIOException(String msg) { 29 | super(msg); 30 | } 31 | 32 | public JsonIOException(String msg, Throwable cause) { 33 | super(msg, cause); 34 | } 35 | 36 | /** 37 | * Creates exception with the specified cause. Consider using {@link #JsonIOException(String, 38 | * Throwable)} instead if you can describe what happened. 39 | * 40 | * @param cause root exception that caused this exception to be thrown. 41 | */ 42 | public JsonIOException(Throwable cause) { 43 | super(cause); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonNull.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | /** 20 | * A class representing a JSON {@code null} value. 21 | * 22 | * @author Inderjeet Singh 23 | * @author Joel Leitch 24 | * @since 1.2 25 | */ 26 | public final class JsonNull extends JsonElement { 27 | /** 28 | * Singleton for {@code JsonNull}. 29 | * 30 | * @since 1.8 31 | */ 32 | public static final JsonNull INSTANCE = new JsonNull(); 33 | 34 | /** 35 | * Creates a new {@code JsonNull} object. 36 | * 37 | * @deprecated Deprecated since Gson version 1.8, use {@link #INSTANCE} instead. 38 | */ 39 | @Deprecated 40 | public JsonNull() { 41 | // Do nothing 42 | } 43 | 44 | /** 45 | * Returns the same instance since it is an immutable value. 46 | * 47 | * @since 2.8.2 48 | */ 49 | @Override 50 | public JsonNull deepCopy() { 51 | return INSTANCE; 52 | } 53 | 54 | /** All instances of {@code JsonNull} have the same hash code since they are indistinguishable. */ 55 | @Override 56 | public int hashCode() { 57 | return JsonNull.class.hashCode(); 58 | } 59 | 60 | /** All instances of {@code JsonNull} are considered equal. */ 61 | @Override 62 | public boolean equals(Object other) { 63 | return other instanceof JsonNull; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonParseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | /** 20 | * This exception is raised if there is a serious issue that occurs during parsing of a Json string. 21 | * One of the main usages for this class is for the Gson infrastructure. If the incoming Json is 22 | * bad/malicious, an instance of this exception is raised. 23 | * 24 | *

This exception is a {@link RuntimeException} because it is exposed to the client. Using a 25 | * {@link RuntimeException} avoids bad coding practices on the client side where they catch the 26 | * exception and do nothing. It is often the case that you want to blow up if there is a parsing 27 | * error (i.e. often clients do not know how to recover from a {@link JsonParseException}. 28 | * 29 | * @author Inderjeet Singh 30 | * @author Joel Leitch 31 | */ 32 | public class JsonParseException extends RuntimeException { 33 | static final long serialVersionUID = -4086729973971783390L; 34 | 35 | /** 36 | * Creates exception with the specified message. If you are wrapping another exception, consider 37 | * using {@link #JsonParseException(String, Throwable)} instead. 38 | * 39 | * @param msg error message describing a possible cause of this exception. 40 | */ 41 | public JsonParseException(String msg) { 42 | super(msg); 43 | } 44 | 45 | /** 46 | * Creates exception with the specified message and cause. 47 | * 48 | * @param msg error message describing what happened. 49 | * @param cause root exception that caused this exception to be thrown. 50 | */ 51 | public JsonParseException(String msg, Throwable cause) { 52 | super(msg, cause); 53 | } 54 | 55 | /** 56 | * Creates exception with the specified cause. Consider using {@link #JsonParseException(String, 57 | * Throwable)} instead if you can describe what happened. 58 | * 59 | * @param cause root exception that caused this exception to be thrown. 60 | */ 61 | public JsonParseException(Throwable cause) { 62 | super(cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonSerializationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | /** 22 | * Context for serialization that is passed to a custom serializer during invocation of its {@link 23 | * JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method. 24 | * 25 | * @author Inderjeet Singh 26 | * @author Joel Leitch 27 | */ 28 | public interface JsonSerializationContext { 29 | 30 | /** 31 | * Invokes default serialization on the specified object. 32 | * 33 | * @param src the object that needs to be serialized. 34 | * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}. 35 | */ 36 | public JsonElement serialize(Object src); 37 | 38 | /** 39 | * Invokes default serialization on the specified object passing the specific type information. It 40 | * should never be invoked on the element received as a parameter of the {@link 41 | * JsonSerializer#serialize(Object, Type, JsonSerializationContext)} method. Doing so will result 42 | * in an infinite loop since Gson will in-turn call the custom serializer again. 43 | * 44 | * @param src the object that needs to be serialized. 45 | * @param typeOfSrc the actual genericized type of src object. 46 | * @return a tree of {@link JsonElement}s corresponding to the serialized form of {@code src}. 47 | */ 48 | public JsonElement serialize(Object src, Type typeOfSrc); 49 | } 50 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/JsonSyntaxException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.gson; 17 | 18 | /** 19 | * This exception is raised when Gson attempts to read (or write) a malformed JSON element. 20 | * 21 | * @author Inderjeet Singh 22 | * @author Joel Leitch 23 | */ 24 | public final class JsonSyntaxException extends JsonParseException { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | public JsonSyntaxException(String msg) { 29 | super(msg); 30 | } 31 | 32 | public JsonSyntaxException(String msg, Throwable cause) { 33 | super(msg, cause); 34 | } 35 | 36 | /** 37 | * Creates exception with the specified cause. Consider using {@link #JsonSyntaxException(String, 38 | * Throwable)} instead if you can describe what actually happened. 39 | * 40 | * @param cause root exception that caused this exception to be thrown. 41 | */ 42 | public JsonSyntaxException(Throwable cause) { 43 | super(cause); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/LongSerializationPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2009 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | /** 20 | * Defines the expected format for a {@code long} or {@code Long} type when it is serialized. 21 | * 22 | * @since 1.3 23 | * @author Inderjeet Singh 24 | * @author Joel Leitch 25 | */ 26 | public enum LongSerializationPolicy { 27 | /** 28 | * This is the "default" serialization policy that will output a {@code Long} object as a JSON 29 | * number. For example, assume an object has a long field named "f" then the serialized output 30 | * would be: {@code {"f":123}} 31 | * 32 | *

A {@code null} value is serialized as {@link JsonNull}. 33 | */ 34 | DEFAULT() { 35 | @Override 36 | public JsonElement serialize(Long value) { 37 | if (value == null) { 38 | return JsonNull.INSTANCE; 39 | } 40 | return new JsonPrimitive(value); 41 | } 42 | }, 43 | 44 | /** 45 | * Serializes a long value as a quoted string. For example, assume an object has a long field 46 | * named "f" then the serialized output would be: {@code {"f":"123"}} 47 | * 48 | *

A {@code null} value is serialized as {@link JsonNull}. 49 | */ 50 | STRING() { 51 | @Override 52 | public JsonElement serialize(Long value) { 53 | if (value == null) { 54 | return JsonNull.INSTANCE; 55 | } 56 | return new JsonPrimitive(value.toString()); 57 | } 58 | }; 59 | 60 | /** 61 | * Serialize this {@code value} using this serialization policy. 62 | * 63 | * @param value the long value to be serialized into a {@link JsonElement} 64 | * @return the serialized version of {@code value} 65 | */ 66 | public abstract JsonElement serialize(Long value); 67 | } 68 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/Strictness.java: -------------------------------------------------------------------------------- 1 | package com.google.gson; 2 | 3 | import com.google.gson.stream.JsonReader; 4 | import com.google.gson.stream.JsonWriter; 5 | 6 | /** 7 | * Modes that indicate how strictly a JSON {@linkplain JsonReader reader} or {@linkplain JsonWriter 8 | * writer} follows the syntax laid out in the RFC 9 | * 8259 JSON specification. 10 | * 11 | *

You can look at {@link JsonReader#setStrictness(Strictness)} to see how the strictness affects 12 | * the {@link JsonReader} and you can look at {@link JsonWriter#setStrictness(Strictness)} to see 13 | * how the strictness affects the {@link JsonWriter}. 14 | * 15 | * @see GsonBuilder#setStrictness(Strictness) 16 | * @see JsonReader#setStrictness(Strictness) 17 | * @see JsonWriter#setStrictness(Strictness) 18 | * @since 2.11.0 19 | */ 20 | public enum Strictness { 21 | /** Allow large deviations from the JSON specification. */ 22 | LENIENT, 23 | 24 | /** Allow certain small deviations from the JSON specification for legacy reasons. */ 25 | LEGACY_STRICT, 26 | 27 | /** Strict compliance with the JSON specification. */ 28 | STRICT 29 | } 30 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/ToNumberStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson; 18 | 19 | import com.google.gson.stream.JsonReader; 20 | import java.io.IOException; 21 | 22 | /** 23 | * A strategy that is used to control how numbers should be deserialized for {@link Object} and 24 | * {@link Number} when a concrete type of the deserialized number is unknown in advance. By default, 25 | * Gson uses the following deserialization strategies: 26 | * 27 | *

    28 | *
  • {@link Double} values are returned for JSON numbers if the deserialization type is declared 29 | * as {@code Object}, see {@link ToNumberPolicy#DOUBLE}; 30 | *
  • Lazily parsed number values are returned if the deserialization type is declared as {@code 31 | * Number}, see {@link ToNumberPolicy#LAZILY_PARSED_NUMBER}. 32 | *
33 | * 34 | *

For historical reasons, Gson does not support deserialization of arbitrary-length numbers for 35 | * {@code Object} and {@code Number} by default, potentially causing precision loss. However, RFC 8259 permits this: 37 | * 38 | *

39 |  *   This specification allows implementations to set limits on the range
40 |  *   and precision of numbers accepted.  Since software that implements
41 |  *   IEEE 754 binary64 (double precision) numbers [IEEE754] is generally
42 |  *   available and widely used, good interoperability can be achieved by
43 |  *   implementations that expect no more precision or range than these
44 |  *   provide, in the sense that implementations will approximate JSON
45 |  *   numbers within the expected precision.  A JSON number such as 1E400
46 |  *   or 3.141592653589793238462643383279 may indicate potential
47 |  *   interoperability problems, since it suggests that the software that
48 |  *   created it expects receiving software to have greater capabilities
49 |  *   for numeric magnitude and precision than is widely available.
50 |  * 
51 | * 52 | *

To overcome the precision loss, use for example {@link ToNumberPolicy#LONG_OR_DOUBLE} or 53 | * {@link ToNumberPolicy#BIG_DECIMAL}. 54 | * 55 | * @see ToNumberPolicy 56 | * @see GsonBuilder#setObjectToNumberStrategy(ToNumberStrategy) 57 | * @see GsonBuilder#setNumberToNumberStrategy(ToNumberStrategy) 58 | * @since 2.8.9 59 | */ 60 | public interface ToNumberStrategy { 61 | 62 | /** 63 | * Reads a number from the given JSON reader. A strategy is supposed to read a single value from 64 | * the reader, and the read value is guaranteed never to be {@code null}. 65 | * 66 | * @param in JSON reader to read a number from 67 | * @return number read from the JSON reader. 68 | */ 69 | public Number readNumber(JsonReader in) throws IOException; 70 | } 71 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/annotations/Since.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.annotations; 18 | 19 | import com.google.gson.GsonBuilder; 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | /** 27 | * An annotation that indicates the version number since a member or a type has been present. This 28 | * annotation is useful to manage versioning of your JSON classes for a web-service. 29 | * 30 | *

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

Here is an example of how this annotation is meant to be used: 34 | * 35 | *

36 |  * public class User {
37 |  *   private String firstName;
38 |  *   private String lastName;
39 |  *   @Since(1.0) private String emailAddress;
40 |  *   @Since(1.0) private String password;
41 |  *   @Since(1.1) private Address address;
42 |  * }
43 |  * 
44 | * 45 | *

If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()} 46 | * methods will use all the fields for serialization and deserialization. However, if you created 47 | * Gson with {@code Gson gson = new GsonBuilder().setVersion(1.0).create()} then the {@code 48 | * toJson()} and {@code fromJson()} methods of Gson will exclude the {@code address} field since 49 | * it's version number is set to {@code 1.1}. 50 | * 51 | * @author Inderjeet Singh 52 | * @author Joel Leitch 53 | * @see GsonBuilder#setVersion(double) 54 | * @see Until 55 | */ 56 | @Documented 57 | @Retention(RetentionPolicy.RUNTIME) 58 | @Target({ElementType.FIELD, ElementType.TYPE}) 59 | public @interface Since { 60 | /** 61 | * The value indicating a version number since this member or type has been present. The number is 62 | * inclusive; annotated elements will be included if {@code gsonVersion >= value}. 63 | */ 64 | double value(); 65 | } 66 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/annotations/Until.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.annotations; 18 | 19 | import com.google.gson.GsonBuilder; 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | /** 27 | * An annotation that indicates the version number until a member or a type should be present. 28 | * Basically, if Gson is created with a version number that is equal to or exceeds the value stored 29 | * in the {@code Until} annotation then the field will be ignored from the JSON output. This 30 | * annotation is useful to manage versioning of your JSON classes for a web-service. 31 | * 32 | *

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

Here is an example of how this annotation is meant to be used: 36 | * 37 | *

38 |  * public class User {
39 |  *   private String firstName;
40 |  *   private String lastName;
41 |  *   @Until(1.1) private String emailAddress;
42 |  *   @Until(1.1) private String password;
43 |  * }
44 |  * 
45 | * 46 | *

If you created Gson with {@code new Gson()}, the {@code toJson()} and {@code fromJson()} 47 | * methods will use all the fields for serialization and deserialization. However, if you created 48 | * Gson with {@code Gson gson = new GsonBuilder().setVersion(1.2).create()} then the {@code 49 | * toJson()} and {@code fromJson()} methods of Gson will exclude the {@code emailAddress} and {@code 50 | * password} fields from the example above, because the version number passed to the GsonBuilder, 51 | * {@code 1.2}, exceeds the version number set on the {@code Until} annotation, {@code 1.1}, for 52 | * those fields. 53 | * 54 | * @author Inderjeet Singh 55 | * @author Joel Leitch 56 | * @see GsonBuilder#setVersion(double) 57 | * @see Since 58 | * @since 1.3 59 | */ 60 | @Documented 61 | @Retention(RetentionPolicy.RUNTIME) 62 | @Target({ElementType.FIELD, ElementType.TYPE}) 63 | public @interface Until { 64 | 65 | /** 66 | * The value indicating a version number until this member or type should be included. The number 67 | * is exclusive; annotated elements will be included if {@code gsonVersion < value}. 68 | */ 69 | double value(); 70 | } 71 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/annotations/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * This package provides annotations that can be used with {@link com.google.gson.Gson}. 19 | * 20 | * @author Inderjeet Singh, Joel Leitch 21 | */ 22 | @com.google.errorprone.annotations.CheckReturnValue 23 | package com.google.gson.annotations; 24 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/GsonPreconditions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal; 18 | 19 | import java.util.Objects; 20 | 21 | /** 22 | * A simple utility class used to check method Preconditions. 23 | * 24 | *

25 |  * public long divideBy(long value) {
26 |  *   Preconditions.checkArgument(value != 0);
27 |  *   return this.value / value;
28 |  * }
29 |  * 
30 | * 31 | * @author Inderjeet Singh 32 | * @author Joel Leitch 33 | */ 34 | @SuppressWarnings("MemberName") // legacy class name 35 | public final class GsonPreconditions { 36 | private GsonPreconditions() { 37 | throw new UnsupportedOperationException(); 38 | } 39 | 40 | /** 41 | * @deprecated This is an internal Gson method. Use {@link Objects#requireNonNull(Object)} 42 | * instead. 43 | */ 44 | // Only deprecated for now because external projects might be using this by accident 45 | @Deprecated 46 | public static T checkNotNull(T obj) { 47 | if (obj == null) { 48 | throw new NullPointerException(); 49 | } 50 | return obj; 51 | } 52 | 53 | public static void checkArgument(boolean condition) { 54 | if (!condition) { 55 | throw new IllegalArgumentException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/JavaVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Gson authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal; 18 | 19 | /** Utility to check the major Java version of the current JVM. */ 20 | public final class JavaVersion { 21 | // Oracle defines naming conventions at 22 | // http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html 23 | // However, many alternate implementations differ. For example, Debian used 9-debian as the 24 | // version string 25 | 26 | private static final int majorJavaVersion = determineMajorJavaVersion(); 27 | 28 | private static int determineMajorJavaVersion() { 29 | String javaVersion = System.getProperty("java.version"); 30 | return parseMajorJavaVersion(javaVersion); 31 | } 32 | 33 | // Visible for testing only 34 | static int parseMajorJavaVersion(String javaVersion) { 35 | int version = parseDotted(javaVersion); 36 | if (version == -1) { 37 | version = extractBeginningInt(javaVersion); 38 | } 39 | if (version == -1) { 40 | return 6; // Choose minimum supported JDK version as default 41 | } 42 | return version; 43 | } 44 | 45 | // Parses both legacy 1.8 style and newer 9.0.4 style 46 | private static int parseDotted(String javaVersion) { 47 | try { 48 | String[] parts = javaVersion.split("[._]", 3); 49 | int firstVer = Integer.parseInt(parts[0]); 50 | if (firstVer == 1 && parts.length > 1) { 51 | return Integer.parseInt(parts[1]); 52 | } else { 53 | return firstVer; 54 | } 55 | } catch (NumberFormatException e) { 56 | return -1; 57 | } 58 | } 59 | 60 | private static int extractBeginningInt(String javaVersion) { 61 | try { 62 | StringBuilder num = new StringBuilder(); 63 | for (int i = 0; i < javaVersion.length(); ++i) { 64 | char c = javaVersion.charAt(i); 65 | if (Character.isDigit(c)) { 66 | num.append(c); 67 | } else { 68 | break; 69 | } 70 | } 71 | return Integer.parseInt(num.toString()); 72 | } catch (NumberFormatException e) { 73 | return -1; 74 | } 75 | } 76 | 77 | /** 78 | * Gets the major Java version 79 | * 80 | * @return the major Java version, i.e. '8' for Java 1.8, '9' for Java 9 etc. 81 | */ 82 | public static int getMajorJavaVersion() { 83 | return majorJavaVersion; 84 | } 85 | 86 | /** 87 | * Gets a boolean value depending if the application is running on Java 9 or later 88 | * 89 | * @return {@code true} if the application is running on Java 9 or later; and {@code false} 90 | * otherwise. 91 | */ 92 | public static boolean isJava9OrLater() { 93 | return majorJavaVersion >= 9; 94 | } 95 | 96 | private JavaVersion() {} 97 | } 98 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/JsonReaderInternalAccess.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal; 18 | 19 | import com.google.gson.stream.JsonReader; 20 | import java.io.IOException; 21 | 22 | /** Internal-only APIs of JsonReader available only to other classes in Gson. */ 23 | public abstract class JsonReaderInternalAccess { 24 | // Suppress warnings because field is initialized by `JsonReader` class during class loading 25 | // (and therefore should be thread-safe), and any usage appears after `JsonReader` was loaded 26 | @SuppressWarnings({"ConstantField", "NonFinalStaticField"}) 27 | public static volatile JsonReaderInternalAccess INSTANCE; 28 | 29 | /** Changes the type of the current property name token to a string value. */ 30 | public abstract void promoteNameToValue(JsonReader reader) throws IOException; 31 | } 32 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/NumberLimits.java: -------------------------------------------------------------------------------- 1 | package com.google.gson.internal; 2 | 3 | import java.math.BigDecimal; 4 | import java.math.BigInteger; 5 | 6 | /** 7 | * This class enforces limits on numbers parsed from JSON to avoid potential performance problems 8 | * when extremely large numbers are used. 9 | */ 10 | public class NumberLimits { 11 | private NumberLimits() {} 12 | 13 | private static final int MAX_NUMBER_STRING_LENGTH = 10_000; 14 | 15 | private static void checkNumberStringLength(String s) { 16 | if (s.length() > MAX_NUMBER_STRING_LENGTH) { 17 | throw new NumberFormatException("Number string too large: " + s.substring(0, 30) + "..."); 18 | } 19 | } 20 | 21 | public static BigDecimal parseBigDecimal(String s) throws NumberFormatException { 22 | checkNumberStringLength(s); 23 | BigDecimal decimal = new BigDecimal(s); 24 | 25 | // Cast to long to avoid issues with abs when value is Integer.MIN_VALUE 26 | if (Math.abs((long) decimal.scale()) >= 10_000) { 27 | throw new NumberFormatException("Number has unsupported scale: " + s); 28 | } 29 | return decimal; 30 | } 31 | 32 | public static BigInteger parseBigInteger(String s) throws NumberFormatException { 33 | checkNumberStringLength(s); 34 | return new BigInteger(s); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/ObjectConstructor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal; 18 | 19 | /** 20 | * Defines a generic object construction factory. The purpose of this class is to construct a 21 | * default instance of a class that can be used for object navigation while deserialization from its 22 | * JSON representation. 23 | * 24 | * @author Inderjeet Singh 25 | * @author Joel Leitch 26 | */ 27 | public interface ObjectConstructor { 28 | 29 | /** Returns a new instance. */ 30 | public T construct(); 31 | } 32 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/PreJava9DateFormatProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Gson authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.gson.internal; 17 | 18 | import java.text.DateFormat; 19 | import java.text.SimpleDateFormat; 20 | import java.util.Locale; 21 | 22 | /** Provides DateFormats for US locale with patterns which were the default ones before Java 9. */ 23 | public class PreJava9DateFormatProvider { 24 | private PreJava9DateFormatProvider() {} 25 | 26 | /** 27 | * Returns the same DateFormat as {@code DateFormat.getDateTimeInstance(dateStyle, timeStyle, 28 | * Locale.US)} in Java 8 or below. 29 | */ 30 | public static DateFormat getUsDateTimeFormat(int dateStyle, int timeStyle) { 31 | String pattern = 32 | getDatePartOfDateTimePattern(dateStyle) + " " + getTimePartOfDateTimePattern(timeStyle); 33 | return new SimpleDateFormat(pattern, Locale.US); 34 | } 35 | 36 | private static String getDatePartOfDateTimePattern(int dateStyle) { 37 | switch (dateStyle) { 38 | case DateFormat.SHORT: 39 | return "M/d/yy"; 40 | case DateFormat.MEDIUM: 41 | return "MMM d, yyyy"; 42 | case DateFormat.LONG: 43 | return "MMMM d, yyyy"; 44 | case DateFormat.FULL: 45 | return "EEEE, MMMM d, yyyy"; 46 | default: 47 | throw new IllegalArgumentException("Unknown DateFormat style: " + dateStyle); 48 | } 49 | } 50 | 51 | private static String getTimePartOfDateTimePattern(int timeStyle) { 52 | switch (timeStyle) { 53 | case DateFormat.SHORT: 54 | return "h:mm a"; 55 | case DateFormat.MEDIUM: 56 | return "h:mm:ss a"; 57 | case DateFormat.FULL: 58 | case DateFormat.LONG: 59 | return "h:mm:ss a z"; 60 | default: 61 | throw new IllegalArgumentException("Unknown DateFormat style: " + timeStyle); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/TroubleshootingGuide.java: -------------------------------------------------------------------------------- 1 | package com.google.gson.internal; 2 | 3 | public class TroubleshootingGuide { 4 | private TroubleshootingGuide() {} 5 | 6 | /** Creates a URL referring to the specified troubleshooting section. */ 7 | public static String createUrl(String id) { 8 | return "https://github.com/google/gson/blob/main/Troubleshooting.md#" + id; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/bind/NumberTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal.bind; 18 | 19 | import com.google.gson.Gson; 20 | import com.google.gson.JsonSyntaxException; 21 | import com.google.gson.ToNumberPolicy; 22 | import com.google.gson.ToNumberStrategy; 23 | import com.google.gson.TypeAdapter; 24 | import com.google.gson.TypeAdapterFactory; 25 | import com.google.gson.reflect.TypeToken; 26 | import com.google.gson.stream.JsonReader; 27 | import com.google.gson.stream.JsonToken; 28 | import com.google.gson.stream.JsonWriter; 29 | import java.io.IOException; 30 | 31 | /** Type adapter for {@link Number}. */ 32 | public final class NumberTypeAdapter extends TypeAdapter { 33 | /** Gson default factory using {@link ToNumberPolicy#LAZILY_PARSED_NUMBER}. */ 34 | private static final TypeAdapterFactory LAZILY_PARSED_NUMBER_FACTORY = 35 | newFactory(ToNumberPolicy.LAZILY_PARSED_NUMBER); 36 | 37 | private final ToNumberStrategy toNumberStrategy; 38 | 39 | private NumberTypeAdapter(ToNumberStrategy toNumberStrategy) { 40 | this.toNumberStrategy = toNumberStrategy; 41 | } 42 | 43 | private static TypeAdapterFactory newFactory(ToNumberStrategy toNumberStrategy) { 44 | NumberTypeAdapter adapter = new NumberTypeAdapter(toNumberStrategy); 45 | return new TypeAdapterFactory() { 46 | @SuppressWarnings("unchecked") 47 | @Override 48 | public TypeAdapter create(Gson gson, TypeToken type) { 49 | return type.getRawType() == Number.class ? (TypeAdapter) adapter : null; 50 | } 51 | }; 52 | } 53 | 54 | public static TypeAdapterFactory getFactory(ToNumberStrategy toNumberStrategy) { 55 | if (toNumberStrategy == ToNumberPolicy.LAZILY_PARSED_NUMBER) { 56 | return LAZILY_PARSED_NUMBER_FACTORY; 57 | } else { 58 | return newFactory(toNumberStrategy); 59 | } 60 | } 61 | 62 | @Override 63 | public Number read(JsonReader in) throws IOException { 64 | JsonToken jsonToken = in.peek(); 65 | switch (jsonToken) { 66 | case NULL: 67 | in.nextNull(); 68 | return null; 69 | case NUMBER: 70 | case STRING: 71 | return toNumberStrategy.readNumber(in); 72 | default: 73 | throw new JsonSyntaxException( 74 | "Expecting number, got: " + jsonToken + "; at path " + in.getPath()); 75 | } 76 | } 77 | 78 | @Override 79 | public void write(JsonWriter out, Number value) throws IOException { 80 | out.value(value); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/bind/SerializationDelegatingTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal.bind; 18 | 19 | import com.google.gson.TypeAdapter; 20 | 21 | /** Type adapter which might delegate serialization to another adapter. */ 22 | public abstract class SerializationDelegatingTypeAdapter extends TypeAdapter { 23 | /** 24 | * Returns the adapter used for serialization, might be {@code this} or another adapter. That 25 | * other adapter might itself also be a {@code SerializationDelegatingTypeAdapter}. 26 | */ 27 | public abstract TypeAdapter getSerializationDelegate(); 28 | } 29 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Do NOT use any class in this package as they are meant for internal use in Gson. These classes 19 | * will very likely change incompatibly in future versions. You have been warned. 20 | * 21 | * @author Inderjeet Singh, Joel Leitch, Jesse Wilson 22 | */ 23 | @com.google.errorprone.annotations.CheckReturnValue 24 | package com.google.gson.internal; 25 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/sql/SqlDateTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal.sql; 18 | 19 | import com.google.gson.Gson; 20 | import com.google.gson.JsonSyntaxException; 21 | import com.google.gson.TypeAdapter; 22 | import com.google.gson.TypeAdapterFactory; 23 | import com.google.gson.reflect.TypeToken; 24 | import com.google.gson.stream.JsonReader; 25 | import com.google.gson.stream.JsonToken; 26 | import com.google.gson.stream.JsonWriter; 27 | import java.io.IOException; 28 | import java.text.DateFormat; 29 | import java.text.ParseException; 30 | import java.text.SimpleDateFormat; 31 | import java.util.Date; 32 | import java.util.TimeZone; 33 | 34 | /** 35 | * Adapter for java.sql.Date. Although this class appears stateless, it is not. DateFormat captures 36 | * its time zone and locale when it is created, which gives this class state. DateFormat isn't 37 | * thread safe either, so this class has to synchronize its read and write methods. 38 | */ 39 | @SuppressWarnings("JavaUtilDate") 40 | final class SqlDateTypeAdapter extends TypeAdapter { 41 | static final TypeAdapterFactory FACTORY = 42 | new TypeAdapterFactory() { 43 | @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal 44 | @Override 45 | public TypeAdapter create(Gson gson, TypeToken typeToken) { 46 | return typeToken.getRawType() == java.sql.Date.class 47 | ? (TypeAdapter) new SqlDateTypeAdapter() 48 | : null; 49 | } 50 | }; 51 | 52 | private final DateFormat format = new SimpleDateFormat("MMM d, yyyy"); 53 | 54 | private SqlDateTypeAdapter() {} 55 | 56 | @Override 57 | public java.sql.Date read(JsonReader in) throws IOException { 58 | if (in.peek() == JsonToken.NULL) { 59 | in.nextNull(); 60 | return null; 61 | } 62 | String s = in.nextString(); 63 | synchronized (this) { 64 | TimeZone originalTimeZone = format.getTimeZone(); // Save the original time zone 65 | try { 66 | Date utilDate = format.parse(s); 67 | return new java.sql.Date(utilDate.getTime()); 68 | } catch (ParseException e) { 69 | throw new JsonSyntaxException( 70 | "Failed parsing '" + s + "' as SQL Date; at path " + in.getPreviousPath(), e); 71 | } finally { 72 | format.setTimeZone(originalTimeZone); // Restore the original time zone after parsing 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public void write(JsonWriter out, java.sql.Date value) throws IOException { 79 | if (value == null) { 80 | out.nullValue(); 81 | return; 82 | } 83 | String dateString; 84 | synchronized (this) { 85 | dateString = format.format(value); 86 | } 87 | out.value(dateString); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.google.gson.internal.sql; 18 | 19 | import com.google.gson.Gson; 20 | import com.google.gson.JsonSyntaxException; 21 | import com.google.gson.TypeAdapter; 22 | import com.google.gson.TypeAdapterFactory; 23 | import com.google.gson.reflect.TypeToken; 24 | import com.google.gson.stream.JsonReader; 25 | import com.google.gson.stream.JsonToken; 26 | import com.google.gson.stream.JsonWriter; 27 | import java.io.IOException; 28 | import java.sql.Time; 29 | import java.text.DateFormat; 30 | import java.text.ParseException; 31 | import java.text.SimpleDateFormat; 32 | import java.util.Date; 33 | import java.util.TimeZone; 34 | 35 | /** 36 | * Adapter for java.sql.Time. Although this class appears stateless, it is not. DateFormat captures 37 | * its time zone and locale when it is created, which gives this class state. DateFormat isn't 38 | * thread safe either, so this class has to synchronize its read and write methods. 39 | */ 40 | @SuppressWarnings("JavaUtilDate") 41 | final class SqlTimeTypeAdapter extends TypeAdapter